javascript学习

 <head><script type="text/javascript">....</script></head>: head部分的脚本, 在脚本被调用或者事件被触发的时候, 运行

<body><script type="text/javascript">....</script></body>: 在页面加载的时候运行

<script src="xxx.js">....</script>: 调用外部脚本

 

单行的注释以 // 开始。

多行注释以 /* 开头,以 */ 结尾。

 

JavaScript 变量名称的规则:

  • 变量对大小写敏感(yY 是两个不同的变量)
  • 变量必须以字母或下划线开始

可以通过 var 语句来声明 JavaScript 变量, 没有类型的

 

运算符:

给定 y=5,下面的表格解释了这些算术运算符:

运算符 描述 例子 结果
+ x=y+2 x=7
- x=y-2 x=3
* x=y*2 x=10
/ x=y/2 x=2.5
% 求余数 (保留整数) x=y%2 x=1
++ 累加 x=++y x=6
-- 递减 x=--y x=4

 

给定 x=10y=5,下面的表格解释了赋值运算符:

运算符 例子 等价于 结果
= x=y   x=5
+= x+=y x=x+y x=15
-= x-=y x=x-y x=5
*= x*=y x=x*y x=50
/= x/=y x=x/y x=2
%= x%=y x=x%y x=0

+ 运算符用于把文本值或字符串变量加起来(连接起来)。如果把数字与字符串相加,结果将成为字符串。很多弱类型的语言都这样。

 

一元运算符:

delete(删除引用), void(设置返回值无效), ++/--(前后增减运算), +/-(取正负)

 

位运算符:

~ 实质上是对数字求负,然后减 1。

有符号右移:>>

无符号右移:>>>

 

toboolean的结果:

 

Undefined false
Null false
Boolean 结果等于输入的参数(不转换)
Number 如果参数为 +0, -0 或 NaN,则结果为 false;否则为 true。
String 如果参数为空字符串,则结果为 false;否则为 true。
Object true

 

 逻辑非 !:

运算符的行为如下:

  • 如果运算数是对象,返回 false
  • 如果运算数是数字 0,返回 true
  • 如果运算数是 0 以外的任何数字,返回 false
  • 如果运算数是 null,返回 true
  • 如果运算数是 NaN,返回 true
  • 如果运算数是 undefined,发生错误

 

逻辑 AND 运算符用双和号(&&)表示:

 

 

逻辑 AND 运算的运算数可以是任何类型的,不止是 Boolean 值。

如果某个运算数不是原始的 Boolean 型值,逻辑 AND 运算并不一定返回 Boolean 值:

  • 如果一个运算数是对象,另一个是 Boolean 值,返回该对象。
  • 如果两个运算数都是对象,返回第二个对象。
  • 如果某个运算数是 null,返回 null。
  • 如果某个运算数是 NaN,返回 NaN。
  • 如果某个运算数是 undefined,发生错误。

 

如果第一个运算数决定了结果,就不再计算第二个运算数。

 

ECMAScript 中的逻辑 OR 运算符与 Java 中的相同,都由双竖线(||)表示:

与逻辑 AND 运算符相似,如果某个运算数不是 Boolean 值,逻辑 OR 运算并不一定返回 Boolean 值:

  • 如果一个运算数是对象,并且该对象左边的运算数值均为 false,则返回该对象。
  • 如果两个运算数都是对象,返回第一个对象。
  • 如果最后一个运算数是 null,并且其他运算数值均为 false,则返回 null。
  • 如果最后一个运算数是 NaN,并且其他运算数值均为 false,则返回 NaN。
  • 如果某个运算数是 undefined,发生错误。

与逻辑 AND 运算符一样,逻辑 OR 运算也是简便运算。对于逻辑 OR 运算符来说,如果第一个运算数值为 true,就不再计算第二个运算数。

 

乘法元算符的特殊性:

  • 如果结果太大或太小,那么生成的结果是 Infinity 或 -Infinity。
  • 如果某个运算数是 NaN,结果为 NaN。
  • Infinity 乘以 0,结果为 NaN。
  • Infinity 乘以 0 以外的任何数字,结果为 Infinity 或 -Infinity。
  • Infinity 乘以 Infinity,结果为 Infinity。

     

    除法运算符的特性:

    • 如果结果太大或太小,那么生成的结果是 Infinity 或 -Infinity。
    • 如果某个运算数是 NaN,结果为 NaN。
    • Infinity 被 Infinity 除,结果为 NaN。
    • Infinity 被任何数字除,结果为 Infinity。
    • 0 除一个任何非无穷大的数字,结果为 NaN。
    • Infinity 被 0 以外的任何数字除,结果为 Infinity 或 -Infinity。

    取模运算符的特性:

  • 如果被除数是 Infinity,或除数是 0,结果为 NaN。
  • Infinity 被 Infinity 除,结果为 NaN。
  • 如果除数是无穷大的数,结果为被除数。
  • 如果被除数为 0,结果为 0。

     

    加法运算符的特性:

    • 某个运算数是 NaN,那么结果为 NaN。
    • -Infinity 加 -Infinity,结果为 -Infinity。
    • Infinity 加 -Infinity,结果为 NaN。
    • +0 加 +0,结果为 +0。
    • -0 加 +0,结果为 +0。
    • -0 加 -0,结果为 -0。

    不过,如果某个运算数是字符串,那么采用下列规则:

    • 如果两个运算数都是字符串,把第二个字符串连接到第一个上。
    • 如果只有一个运算数是字符串,把另一个运算数转换成字符串,结果是两个字符串连接成的字符串。

    减法运算符的特性:

  • 某个运算数是 NaN,那么结果为 NaN。
  • Infinity 减 Infinity,结果为 NaN。
  • -Infinity 减 -Infinity,结果为 NaN。
  • Infinity 减 -Infinity,结果为 Infinity。
  • -Infinity 减 Infinity,结果为 -Infinity。
  • +0 减 +0,结果为 +0。
  • -0 减 -0,结果为 -0。
  • +0 减 -0,结果为 +0。
  • 某个运算符不是数字,那么结果为 NaN。

     

     

    关系运算符的特性:

    比较都返回bool值

    数字和字符比较, 把字符转换成数字,再比较, 对于不能转换成数字的,  返回false

     

     

     

    ECMAScript 提供了两套等性运算符:等号和非等号用于处理原始值,全等号和非全等号用于处理对象。

     

    等号与非等号的特性:

    执行类型转换的规则如下:

    • 如果一个运算数是 Boolean 值,在检查相等性之前,把它转换成数字值。false 转换成 0,true 为 1。
    • 如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。
    • 如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。
    • 如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字。

    在比较时,该运算符还遵守下列规则:

    • 值 null 和 undefined 相等。
    • 在检查相等性时,不能把 null 和 undefined 转换成其他值。
    • 如果某个运算数是 NaN,等号将返回 false,非等号将返回 true。
    • 如果两个运算数都是对象,那么比较的是它们的引用值。如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。

    即使两个数都是 NaN,等号仍然返回 false,因为根据规则,NaN 不等于 NaN。

    下表列出了一些特殊情况,以及它们的结果:

    表达式
    null == undefined true
    "NaN" == NaN false
    5 == NaN false
    NaN == NaN false
    NaN != NaN true
    false == 0 true
    true == 1 true
    true == 2 false
    undefined == 0 false
    null == 0 false
    "5" == 5 true

     

    全等号和非全等号:

    这两个运算符所做的与等号和非等号相同,只是它们在检查相等性前,不执行类型转换。

    全等号由三个等号表示(===),只有在无需类型转换运算数就相等的情况下,才返回 true。

    非全等号由感叹号加两个等号(!==)表示,只有在无需类型转换运算数不相等的情况下,才返回 true。

     

    符条件运算符(跟其它语言类似):

    variable = boolean_expression ? true_value : false_value;

     

     

    复合赋值运算符:

    • 乘法/赋值(*=)
    • 除法/赋值(/=)
    • 取模/赋值(%=)
    • 加法/赋值(+=)
    • 减法/赋值(-=)
    • 左移/赋值(<<=)
    • 有符号右移/赋值(>>=)
    • 无符号右移/赋值(>>>=)

    if (条件1){条件1成立时执行代码}

    else if (条件2){条件2成立时执行代码}

    else{条件1和条件2均不成立时执行代码}

     

    switch(n) { case 1: 执行代码块 1 break case 2: 执行代码块 2 break default: 如果n即不是1也不是2,则执行此代码 }

     

     

    可以在 JavaScript 中创建三种消息框:警告框(alert)、确认框(confirm)、提示框(prompt)。

     

    function prod(a,b){x=a*breturn x}

     

    for循环:

    for (变量=开始值;变量<=结束值;变量=变量+步进值)

    { 需执行的代码}

     

    while循环:

    while (变量<=结束值)

    { 需执行的代码}

     

    do

    { 需执行的代码}

    while (变量<=结束值)

     

     

    For...In 声明用于遍历数组或者对象的属性(对数组或者对象的属性进行循环操作)。

     

    for (变量 in 对象)

    { 在此执行代码}

     

    <script type="text/javascript">

    var xvar mycars = new Array()

    mycars[0] = "Saab"

    mycars[1] = "Volvo"

    mycars[2] = "BMW"

    for (x in mycars)

    {document.write(mycars[x] + "<br />")}

    </script>

     

    返回的是数组的index!!!!

     

     try

  • { //在此运行代码}

  • catch(err)

  • { //在此处理错误}

     

     

     try

    { if(x>10)

    throw "Err1"

    else if(x<0)

    throw "Err2"}

    catch(er)

    {

    if(er=="Err1")

    alert("Error! The value is too high")

    if(er == "Err2")

    alert("Error! The value is too low")

    }

     

     <html>

    <head>

    <script type="text/javascript">

    onerror=handleErrvar

    txt=""

    function handleErr(msg,url,l)

    {

    txt="There was an error on this page.\n\n"

    txt+="Error: " + msg + "\n"

    txt+="URL: " + url + "\n"

    txt+="Line: " + l + "\n\n"

    txt+="Click OK to continue.\n\n"

    alert(txt)return true

    }

    function message()

    {

    adddlert("Welcome guest!")

    }</script>

    </head>

    <body>

    <input type="button" value="View message" onclick="message()" />

    </body>

    </html>

     

     js中的一些特殊字符转义:

    下面的表格列出了其余的特殊字符,这些特殊字符都可以使用反斜杠来添加到文本字符串中:

    代码 输出
    \' 单引号
    \" 双引号
    \& 和号
    \\ 反斜杠
    \n 换行符
    \r 回车符
    \t 制表符
    \b 退格符
    \f 换页符

     

     

    您可以在文本字符串内部使用反斜杠对代码进行折行。下面的例子是正确的:

    document.write("Hello \
    World!")

    但是不能像这样折行:

    document.write \
    ("Hello World!")

     

    js字符串indexOf方法:

    indexOf() 方法
    如何使用 indexOf() 来定位字符串中某一个指定的字符首次出现的位置

     

    如何使用 match() 来查找字符串中特定的字符,并且如果找到的话,则返回这个字符, 否则返回nul

     

    几种内嵌的js对象:

    string, date, 数组对象, boolean, Math,

     

    数组对象:

    var mycars = new Array()
    mycars[0] = "Saab"
    mycars[1] = "Volvo"
    mycars[2] = "BMW"

     该对象的join函数可以连接数组元素成字串, join参数指连接符, 默认逗号

     

    Boolean(逻辑)对象用于将非逻辑值转换为逻辑值(true 或者 false)。

    Math的特殊性在于,一般直接用Math加方法来调用。

     

    其他对象(dom对象):

    对象 描述
    Window JavaScript 层级中的顶层对象。Window 对象表示浏览器窗口。每当 <body> 或者 <frameset> 标签出现,Window 对象就会被自动创建。
    Navigator 包含客户端浏览器的信息。
    Screen 包含客户端显示屏的信息。
    History 包含了浏览器窗口访问过的 URL。
    Location 包含了当前URL的信息。

     

    对象 描述
    Document 代表整个 HTML 文档,用来访问页面中的所有元素。
    Anchor 代表 <a> 元素。
    Area 代表图像地图中的 <area> 元素。
    Base 代表 <base> 元素。
    Body 代表图像地图中的 <body> 元素。
    Button 代表 <button> 元素。
    Event 代表事件的状态
    Form 代表 <form> 元素
    Frame 代表 <frame> 元素
    Frameset 代表 <frameset> 元素
    Iframe 代表 <iframe> 元素
    Image 代表 <img> 元素
    Input button 代表 HTML 表单中的按钮
    Input checkbox 代表 HTML 表单中的选择框
    Input file 代表 HTML 表单中的 fileupload 。
    Input hidden 代表 HTML 表单中的隐藏域。
    Input password 代表 HTML 表单中的密码域。
    Input radio 代表 HTML 表单中的单选框。
    Input reset 代表 HTML 表单中的重置按钮。
    Input submit 代表 HTML 表单中的确认按钮。
    Input text 代表 HTML 表单中的文本输入域。
    Link 代表 <link> 元素
    Meta 代表 <meta> 元素
    Object 代表一个 <Object> 元素
    Option 代表 <option> 元素
    Select 代表 HTML 表单中的选择列表。
    Style 代表某个单独的样式声明。
    Table 代表 <table> 元素。
    TableData 代表 <td> 元素。
    TableRow 代表 <tr> 元素。
    Textarea 代表 <textarea> 元素。

     

     

    cookie是documnt的成员, document.cookie, 用于保存小的信息, 存在本地。保存例如: 名字, 密码, 日期等。

     

    js高级:

    dom level 1: 基本的html, xml结构视图

    dom level 2: 增加了描述跟踪文档的视图, 事件处理, 样式, 遍历

    dom level 3: 引入了以统一的方式载入和保持文档的方法(包含在新模块 DOM Load and Save)以及验证文档(DOM Validation)的方法,从而进一步扩展了 DOM。在 Level 3 中,DOM Core 被扩展为支持所有的 XML 1.0 特性,包括 XML Infoset、XPath 和 XML Base。

    javascript学习_第1张图片

     

     

    原始值
    存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。
    引用值
    存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。

    ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。EMCA-262 把术语类型(type)定义为值的一个集合,每种原始类型定义了它包含的值的范围及其字面量表示形式。

    ECMAScript 提供了 typeof 运算符来判断一个值是否在某种类型的范围内。可以用这种运算符判断一个值是否表示一种原始类型:如果它是原始类型,还可以判断它表示哪种原始类型。

     

    对变量或值调用 typeof 运算符将返回下列值之一:

    • undefined - 如果变量是 Undefined 类型的
    • boolean - 如果变量是 Boolean 类型的
    • number - 如果变量是 Number 类型的
    • string - 如果变量是 String 类型的
    • object - 如果变量是一种引用类型或 Null 类型的

     

     

    Null 类型

    另一种只有一个值的类型是 Null,它只有一个专用值 null,即它的字面量。值 undefined 实际上是从值 null 派生来的,因此 ECMAScript 把它们定义为相等的。

    alert(null == undefined);  //输出 "true"
    

    尽管这两个值相等,但它们的含义不同。undefined 是声明了变量但未对其初始化时赋予该变量的值,null 则用于表示尚未存在的对象(在讨论 typeof 运算符时,简单地介绍过这一点)。如果函数或方法要返回的是对象,那么找不到该对象时,返回的通常是 null。

     

     

    可以对任何数调用 isFinite() 方法,以确保该数不是无穷大。例如:

    var iResult = iNum * some_really_large_number;
    
    if (isFinite(iResult)) {
        alert("finite");
    }
    
    else {
        alert("infinite");
    }
    

     

     

    一个特殊值是 NaN,表示非数(Not a Number)。NaN 是个奇怪的特殊值。一般说来,这种情况发生在类型(String、Boolean 等)转换失败时。例如,要把单词 blue 转换成数值就会失败,因为没有与之等价的数值。

     

    NaN 的另一个奇特之处在于,它与自身不相等,这意味着下面的代码将返回 false:

    alert(NaN == NaN);  //输出 "false"

     

     

    下面列出了 ECMAScript 的字符字面量:

    字面量 含义
    \n 换行
    \t 制表符
    \b 空格
    \r 回车
    \f 换页符
    \\ 反斜杠
    \' 单引号
    \" 双引号
    \0nnn 八进制代码 nnn 表示的字符(n 是 0 到 7 中的一个八进制数字)
    \xnn 十六进制代码 nn 表示的字符(n 是 0 到 F 中的一个十六进制数字)
    \unnnn 十六进制代码 nnnn 表示的 Unicode 字符(n 是 0 到 F 中的一个十六进制数字)

     

     

     

    对象是由 new 运算符加上要实例化的对象的名字创建的。例如,下面的代码创建 Object 对象的实例:

    var o = new Object();

    尽管括号不是必需的,但是为了避免混乱,最好使用括号。

     

    ECMAScript 中的所有对象都由object对象继承而来,Object 对象中的所有属性和方法都会出现在其他对象中,所以理解了 Object 对象,就可以更好地理解其他对象。

     

    Object 对象具有下列属性:

    constructor
    对创建对象的函数的引用(指针)。对于 Object 对象,该指针指向原始的 Object() 函数。
    Prototype
    对该对象的对象原型的引用。对于所有的对象,它默认返回 Object 对象的一个实例。

    Object 对象还具有几个方法:

    hasOwnProperty(property)
    判断对象是否有某个特定的属性。必须用字符串指定该属性。(例如,o.hasOwnProperty("name"))
    IsPrototypeOf(object)
    判断该对象是否为另一个对象的原型。
    PropertyIsEnumerable
    判断给定的属性是否可以用 for...in 语句进行枚举。
    ToString()
    返回对象的原始字符串表示。对于 Object 对象,ECMA-262 没有定义这个值,所以不同的 ECMAScript 实现具有不同的值。
    ValueOf()
    返回最适合该对象的原始值。对于许多对象,该方法返回的值都与 ToString() 的返回值相同。

     

    下面几个内嵌对象(他们会有一些方法):

    Boolean 对象

     

    Number 对象

     

    String 对象

    更多,可参考下面的连接:

    http://www.w3school.com.cn/js/js_reference.asp

     

    函数的参数的arguments对象, 可用arguments[0], arguments[1]等访问

    模拟重载的方法:

    function doAdd() {

    if(arguments.length == 1) { alert(arguments[0] + 5); }

    else if(arguments.length == 2) { alert(arguments[0] + arguments[1]); }

    }

     

     

    可使用函数对象, 形如:

    var function_name = new function(arg1, arg2, ..., argN, function_body)

     

    例如:

    var sayHi = new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");

     

     

    ECMAScript 定义函数对象的属性 length 声明了函数期望的参数个数。

     

    在 ECMAScript 中使用全局变量是一个简单的闭包(closure, 访问体外变量)实例。请思考下面这段代码:

    var sMessage = "hello world";
    
    function sayHelloWorld() {
      alert(sMessage);
    }
    
    sayHelloWorld();
    

     

     

    面向对象语言的要求

    一种面向对象语言需要向开发者提供四种基本能力:

    1. 封装 - 把相关的信息(无论数据或方法)存储在对象中的能力
    2. 聚集 - 把一个对象存储在另一个对象内的能力
    3. 继承 - 由另一个类(或多个类)得来类的属性和方法的能力
    4. 多态 - 编写能以多种方法运行的函数或方法的能力

       

       

      oObject = null;//删除对象引用

       

      早绑定和晚绑定

      所谓绑定(binding),即把对象的接口与对象实例结合在一起的方法。

      早绑定(early binding)是指在实例化对象之前定义它的属性和方法,这样编译器或解释程序就能够提前转换机器代码。在 Java 和 Visual Basic 这样的语言中,有了早绑定,就可以在开发环境中使用 IntelliSense(即给开发者提供对象中属性和方法列表的功能)。ECMAScript 不是强类型语言,所以不支持早绑定。

      另一方面,晚绑定(late binding)指的是编译器或解释程序在运行前,不知道对象的类型。使用晚绑定,无需检查对象的类型,只需检查对象是否支持属性和方法即可。ECMAScript 中的所有变量都采用晚绑定方法。这样就允许执行大量的对象操作,而无任何惩罚。

       

       

      宿主对象

      所有非本地对象都是宿主对象(host object),即由 ECMAScript 实现的宿主环境提供的对象。

      所有 BOM 和 DOM 对象都是宿主对象。

       

       

      ECMAScript 只有公用作用域

       

      obj._color_ = "blue";

      这段代码中,属性 color 是私有的。注意,下划线并不改变属性是公用属性的事实,它只是告诉其他开发者,应该把该属性看作私有的。

       

       

      严格来说,ECMAScript 并没有静态作用域。不过,它可以给构造函数提供属性和方法。还记得吗,构造函数只是函数。函数是对象,对象可以有属性和方法。例如:

      function sayHello() {
        alert("hello");
      }
      
      sayHello.alternate = function() {
        alert("hi");
      }
      
      sayHello();		//输出 "hello"
      sayHello.alternate();	//输出 "hi"
      

       

       

      关键字 this 总是指向调用该方法的对象

      为什么使用 this 呢?因为在实例化对象时,总是不能确定开发者会使用什么样的变量名。使用 this,即可在任何多个地方重用同一个函数。

       

       

    创建对象的方法:

    原始的方式:

    var oCar = new Object;oCar.color = "blue";oCar.doors = 4;oCar.mpg = 25;oCar.showColor = function() { alert(this.color);};

     

    function createCar() {

    var oTempCar = new Object;

    oTempCar.color = "blue";

    oTempCar.doors = 4;

    oTempCar.mpg = 25;

    oTempCar.showColor = function() {

    alert(this.color); };

    return oTempCar;

    }

    var oCar1 = createCar();

    var oCar2 = createCar();

     

    工厂方法之外定义:

    function showColor()

    { alert(this.color);}

     

    function createCar(sColor,iDoors,iMpg)

    {

     var oTempCar = new Object; oTempCar.color = sColor; oTempCar.doors = iDoors; oTempCar.mpg = iMpg;

    oTempCar.showColor = showColor;

    return oTempCar;

    }

    var oCar1 = createCar("red",4,23);

    var oCar2 = createCar("blue",3,25);

    oCar1.showColor(); //输出 "red"

    oCar2.showColor(); //输出 "blue"

     

     

     

    开发者定义的构造函数方式:

    function Car(sColor,iDoors,iMpg)

    { this.color = sColor; this.doors = iDoors; this.mpg = iMpg;

    this.showColor = function() { alert(this.color);

    };

    }var oCar1 = new Car("red",4,23);

    var oCar2 = new Car("blue",3,25);

    就像工厂函数,构造函数会重复生成函数

    原型方式:

    function Car() {}

    Car.prototype.color = "blue";Car.prototype.doors = 4;Car.prototype.mpg = 25;

    Car.prototype.showColor = function() { alert(this.color);};

    var oCar1 = new Car();

    var oCar2 = new Car();

     

    alert(oCar1 instanceof Car); //使用instanceof检查对象原型

    原型方式的缺点:

    首先,这个构造函数没有参数。

     

    真正的问题出现在属性指向的是对象,而不是函数时。函数共享不会造成问题,但对象却很少被多个实例共享。

     

    function Car() {}

    Car.prototype.color = "blue";Car.prototype.doors = 4;Car.prototype.mpg = 25;

    Car.prototype.drivers = new Array("Mike","John");

    Car.prototype.showColor = function() { alert(this.color);};

    var oCar1 = new Car();

    var oCar2 = new Car();

    oCar1.drivers.push("Bill");

    alert(oCar1.drivers); //输出 "Mike,John,Bill"

    alert(oCar2.drivers); //输出 "Mike,John,Bill"

    这里的driver输出相同。

     

     

    混合的构造函数/原型方式:

    function Car(sColor,iDoors,iMpg)

    { this.color = sColor; this.doors = iDoors; this.mpg = iMpg;

    this.drivers = new Array("Mike","John");

    }

    Car.prototype.showColor = function() { alert(this.color);};

    var oCar1 = new Car("red",4,23);

    var oCar2 = new Car("blue",3,25);

    oCar1.drivers.push("Bill");

    alert(oCar1.drivers); //输出 "Mike,John,Bill"

    alert(oCar2.drivers); //输出 "Mike,John"

     

    这就对了。

     

    动态原型方法(实际上是构造函数方法的改进):

    function Car(sColor,iDoors,iMpg)

    { this.color = sColor; this.doors = iDoors; this.mpg = iMpg;

    this.drivers = new Array("Mike","John");

    if (typeof Car._initialized == "undefined")

    {

    Car.prototype.showColor = function()

    { alert(this.color); };

    Car._initialized = true;

     }}

     

    混合工厂方式:

    function Car()

    { var oTempCar = new Object;

    oTempCar.color = "blue"; oTempCar.doors = 4; oTempCar.mpg = 25; oTempCar.showColor = function() { alert(this.color); };

    return oTempCar;}

    与经典方式不同,这种方式使用 new 运算符,使它看起来像真正的构造函数:

    var car = new Car();

    这种方式在对象方法的内部管理方面与经典方式有着相同的问题。强烈建议:除非万不得已,还是避免使用这种方式。

     

    给对象添加新方法:

    Number.prototype.toHexString = function() { return this.toString(16);};

     

    这种可以添加修改对象的能力, 给ECMAScript带来极晚绑定(Very Late Binding)的能力

     

     

    几种对象继承方法:

    对象冒充:

    function ClassA(sColor)

    { this.color = sColor; this.sayColor = function () { alert(this.color); };}

    function ClassB(sColor)

    { this.newMethod = ClassA; this.newMethod(sColor);

     delete this.newMethod;}

    classB的新方法属性应在newMothod之后定义

     

    对象冒充可以实现多重继承

     

     

    call() 方法:

    call() 方法是与经典的对象冒充方法最相似的方法。它的第一个参数用作 this 的对象。其他参数都直接传递给函数自身。例如:

    function sayColor(sPrefix,sSuffix) {
        alert(sPrefix + this.color + sSuffix);
    };
    
    var obj = new Object();
    obj.color = "blue";
    
    sayColor.call(obj, "The color is ", "a very nice color indeed.");
    

    在这个例子中,函数 sayColor() 在对象外定义,即使它不属于任何对象,也可以引用关键字 this。对象 obj 的 color 属性等于 blue。调用 call() 方法时,第一个参数是 obj,说明应该赋予 sayColor() 函数中的 this 关键字值是 obj。第二个和第三个参数是字符串。它们与 sayColor() 函数中的参数 sPrefix 和 sSuffix 匹配,最后生成的消息 "The color is blue, a very nice color indeed." 将被显示出来。

    要与继承机制的对象冒充方法一起使用该方法,只需将前三行的赋值、调用和删除代码替换即可:

    function ClassB(sColor, sName) {
        //this.newMethod = ClassA;
        //this.newMethod(color);
        //delete this.newMethod;
        ClassA.call(this, sColor);
    
        this.name = sName;
        this.sayName = function () {
            alert(this.name);
        };
    }
    

     

     

     

    apply() 方法

    apply() 方法有两个参数,用作 this 的对象和要传递给函数的参数的数组。例如:

    function sayColor(sPrefix,sSuffix) {
        alert(sPrefix + this.color + sSuffix);
    };
    
    var obj = new Object();
    obj.color = "blue";
    
    sayColor.apply(obj, new Array("The color is ", "a very nice color indeed."));
    

    这个例子与前面的例子相同,只是现在调用的是 apply() 方法。调用 apply() 方法时,第一个参数仍是 obj,说明应该赋予 sayColor() 函数中的 this 关键字值是 obj。第二个参数是由两个字符串构成的数组,与 sayColor() 函数中的参数 sPrefix 和 sSuffix 匹配,最后生成的消息仍是 "The color is blue, a very nice color indeed.",将被显示出来。

    该方法也用于替换前三行的赋值、调用和删除新方法的代码:

    function ClassB(sColor, sName) {
        //this.newMethod = ClassA;
        //this.newMethod(color);
        //delete this.newMethod;
        ClassA.apply(this, new Array(sColor));
    
        this.name = sName;
        this.sayName = function () {
            alert(this.name);
        };
    }
    

    同样的,第一个参数仍是 this,第二个参数是只有一个值 color 的数组。可以把 ClassB 的整个 arguments 对象作为第二个参数传递给 apply() 方法:

    function ClassB(sColor, sName) {
        //this.newMethod = ClassA;
        //this.newMethod(color);
        //delete this.newMethod;
        ClassA.apply(this, arguments);
    
        this.name = sName;
        this.sayName = function () {
            alert(this.name);
        };
    }
    

     

     

    原型链(prototype chaining)

    继承这种形式在 ECMAScript 中原本是用于原型链的。上一章介绍了定义类的原型方式。原型链扩展了这种方式,以一种有趣的方式实现继承机制。

    在上一章学过,prototype 对象是个模板,要实例化的对象都以这个模板为基础。总而言之,prototype 对象的任何属性和方法都被传递给那个类的所有实例。原型链利用这种功能来实现继承机制。

    如果用原型方式重定义前面例子中的类,它们将变为下列形式:

    function ClassA() {
    }
    
    ClassA.prototype.color = "blue";
    ClassA.prototype.sayColor = function () {
        alert(this.color);
    };
    
    function ClassB() {
    }
    
    ClassB.prototype = new ClassA();
    

    原型方式的神奇之处在于突出显示的蓝色代码行。这里,把 ClassB 的 prototype 属性设置成 ClassA 的实例。这很有意思,因为想要 ClassA 的所有属性和方法,但又不想逐个将它们 ClassB 的 prototype 属性。还有比把 ClassA 的实例赋予 prototype 属性更好的方法吗?

    注意:调用 ClassA 的构造函数,没有给它传递参数。这在原型链中是标准做法。要确保构造函数没有任何参数。

    与对象冒充相似,子类的所有属性和方法都必须出现在 prototype 属性被赋值后,因为在它之前赋值的所有方法都会被删除。为什么?因为 prototype 属性被替换成了新对象,添加了新方法的原始对象将被销毁。所以,为 ClassB 类添加 name 属性和 sayName() 方法的代码如下:

    function ClassB() {
    }
    
    ClassB.prototype = new ClassA();
    
    ClassB.prototype.name = "";
    ClassB.prototype.sayName = function () {
        alert(this.name);
    };
    

     

     

    混合方式

    这种继承方式使用构造函数定义类,并非使用任何原型。对象冒充的主要问题是必须使用构造函数方式,这不是最好的选择。不过如果使用原型链,就无法使用带参数的构造函数了。开发者如何选择呢?答案很简单,两者都用。

    在前一章,我们曾经讲解过创建类的最好方式是用构造函数定义属性,用原型定义方法。这种方式同样适用于继承机制,用对象冒充继承构造函数的属性,用原型链继承 prototype 对象的方法。用这两种方式重写前面的例子,代码如下:

    function ClassA(sColor) {
        this.color = sColor;
    }
    
    ClassA.prototype.sayColor = function () {
        alert(this.color);
    };
    
    function ClassB(sColor, sName) {
        ClassA.call(this, sColor);
        this.name = sName;
    }
    
    ClassB.prototype = new ClassA();
    
    ClassB.prototype.sayName = function () {
        alert(this.name);
    };
    

    在此例子中,继承机制由两行突出显示的蓝色代码实现。在第一行突出显示的代码中,在 ClassB 构造函数中,用对象冒充继承 ClassA 类的 sColor 属性。在第二行突出显示的代码中,用原型链继承 ClassA 类的方法。由于这种混合方式使用了原型链,所以 instanceof 运算符仍能正确运行。

     

     

     

     

     

     

     

     

     

     

     

     

     link: 讲解npapi plugin:

     http://wenku.baidu.com/view/53375002bed5b9f3f90f1c2a.html

     

     

  • 你可能感兴趣的:(JavaScript,function,object,prototype,null,binding)