JS虽然很烂,但是有些事情还是要知道的
2013-04-02 13:42
246 查看
写惯了c,c++ 实在是不喜欢js这种不严谨的语法和prototype的随处可定义以及唯一作用域。
吐槽完毕,笔记如下:
ECMAScript 有 2 种基本类型:原始与引用(class)。
ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。
ECMAScript
提供了 typeof 运算符来判断一个值是否在某种类型的范围内。可以用这种运算符判断一个值是否表示一种原始类型:如果它是原始类型,还可以判断它表示哪种原始类型。
对变量或值调用 typeof 运算符将返回下列值之一:
undefined - 如果变量是 Undefined 类型的
boolean - 如果变量是 Boolean 类型的
number - 如果变量是 Number 类型的
string - 如果变量是 String 类型的
object - 如果变量是一种引用类型或 Null 类型的
null
被认为是对象的占位符
undefined
是声明了变量但未对其初始化时赋予该变量的值,null 则用于表示尚未存在的对象
最后一个特殊值是
NaN,表示非数(Not a Number)。
不推荐使用 NaN 值本身。函数 isNaN() 会做得相当好:
ECMAScript 中的所有对象都由这个对象继承而来,Object 对象中的所有属性和方法都会出现在其他对象中,所以理解了 Object 对象,就可以更好地理解其他对象。
constructor对创建对象的函数的引用(指针)。对于 Object 对象,该指针指向原始的 Object() 函数。Prototype对该对象的对象原型的引用。对于所有的对象,它默认返回 Object 对象的一个实例。
hasOwnProperty(property)判断对象是否有某个特定的属性。必须用字符串指定该属性。(例如,o.hasOwnProperty("name"))IsPrototypeOf(object)判断该对象是否为另一个对象的原型。PropertyIsEnumerable判断给定的属性是否可以用 for...in 语句进行枚举。ToString()返回对象的原始字符串表示。对于 Object 对象,ECMA-262 没有定义这个值,所以不同的 ECMAScript 实现具有不同的值。ValueOf()返回最适合该对象的原始值。对于许多对象,该方法返回的值都与 ToString() 的返回值相同。
在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 "object"。ECMAScript 引入了另一个 Java 运算符 instanceof 来解决这个问题。
instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。例如:
这段代码问的是“变量 oStringObject 是否为 String 对象的实例?”oStringObject 的确是 String 对象的实例,因此结果是 "true"。尽管不像 typeof 方法那样灵活,但是在 typeof 方法返回 "object" 的情况下,instanceof 方法还是很有用的。
下表列出了一些特殊情况,以及它们的结果:
全等号由三个等号表示(===),只有在无需类型转换运算数就相等的情况下,才返回 true
在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们
ECMAScript 最令人感兴趣的可能莫过于函数实际上是功能完整的对象。
Function 类可以表示开发者定义的任何函数。
用 Function 类直接创建函数的语法如下:
在上面的形式中,每个 arg 都是一个参数,最后一个参数是函数主体(要执行的代码)。这些参数必须是字符串
记得下面这个函数吗?
还可以这样定义它:
虽然由于字符串的关系,这种形式写起来有些困难,但有助于理解函数只不过是一种引用类型,它们的行为与用 Function 类明确创建的函数行为是相同的。
对 ECMAScript 讨论上面这些作用域几乎毫无意义,因为 ECMAScript 中只存在一种作用域 - 公用作用域。ECMAScript 中的所有对象的所有属性和方法都是公用的。因此,定义自己的类和对象时,必须格外小心。记住,所有属性和方法默认都是公用的!
在 ECMAScript 中,要掌握的最重要的概念之一是关键字 this 的用法,它用在对象的方法中。关键字 this 总是指向调用该方法的对象,例如:
};
oCar.showColor(); //输出 "red"[/code]
所有新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法:
call() 方法是与经典的对象冒充方法最相似的方法。它的第一个参数用作 this 的对象。其他参数都直接传递给函数自身。例如:
在这个例子中,函数 sayColor() 在对象外定义,即使它不属于任何对象,也可以引用关键字 this。对象 obj 的 color 属性等于 blue。调用 call() 方法时,第一个参数是 obj,说明应该赋予 sayColor() 函数中的 this 关键字值是 obj。第二个和第三个参数是字符串。它们与 sayColor() 函数中的参数 sPrefix 和 sSuffix 匹配,最后生成的消息 "The color is blue, a very nice color indeed." 将被显示出来。
要与继承机制的对象冒充方法一起使用该方法,只需将前三行的赋值、调用和删除代码替换即可:
继承这种形式在 ECMAScript 中原本是用于原型链的。prototype 对象是个模板,要实例化的对象都以这个模板为基础。总而言之,prototype 对象的任何属性和方法都被传递给那个类的所有实例。原型链利用这种功能来实现继承机制。
如果用原型方式重定义前面例子中的类,它们将变为下列形式:
this.name = sName;
}
ClassB.prototype.sayName = function () {
alert(this.name);
};[/code]
吐槽完毕,笔记如下:
ECMAScript 有 2 种基本类型:原始与引用(class)。
ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。
ECMAScript
提供了 typeof 运算符来判断一个值是否在某种类型的范围内。可以用这种运算符判断一个值是否表示一种原始类型:如果它是原始类型,还可以判断它表示哪种原始类型。
对变量或值调用 typeof 运算符将返回下列值之一:
undefined - 如果变量是 Undefined 类型的
boolean - 如果变量是 Boolean 类型的
number - 如果变量是 Number 类型的
string - 如果变量是 String 类型的
object - 如果变量是一种引用类型或 Null 类型的
null
被认为是对象的占位符
undefined
是声明了变量但未对其初始化时赋予该变量的值,null 则用于表示尚未存在的对象
最后一个特殊值是
NaN,表示非数(Not a Number)。
不推荐使用 NaN 值本身。函数 isNaN() 会做得相当好:
alert(isNaN("blue")); //输出 "true" alert(isNaN("666")); //输出 "false"
Object 对象
ECMAScript 中的所有对象都由这个对象继承而来,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() 的返回值相同。
instanceof 运算符
在使用 typeof 运算符时采用引用类型存储值会出现一个问题,无论引用的是什么类型的对象,它都返回 "object"。ECMAScript 引入了另一个 Java 运算符 instanceof 来解决这个问题。instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。例如:
var oStringObject = new String("hello world"); alert(oStringObject instanceof String); //输出 "true"
这段代码问的是“变量 oStringObject 是否为 String 对象的实例?”oStringObject 的确是 String 对象的实例,因此结果是 "true"。尽管不像 typeof 方法那样灵活,但是在 typeof 方法返回 "object" 的情况下,instanceof 方法还是很有用的。
下表列出了一些特殊情况,以及它们的结果:
表达式 | 值 |
---|---|
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 |
arguments 对象
在函数代码中,使用特殊对象 arguments,开发者无需明确指出参数名,就能访问它们
Function 对象(类)
ECMAScript 最令人感兴趣的可能莫过于函数实际上是功能完整的对象。Function 类可以表示开发者定义的任何函数。
用 Function 类直接创建函数的语法如下:
var function_name = new function(arg1, arg2, ..., argN, function_body)
在上面的形式中,每个 arg 都是一个参数,最后一个参数是函数主体(要执行的代码)。这些参数必须是字符串
记得下面这个函数吗?
function sayHi(sName, sMessage) { alert("Hello " + sName + sMessage); }
还可以这样定义它:
var sayHi = new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");
虽然由于字符串的关系,这种形式写起来有些困难,但有助于理解函数只不过是一种引用类型,它们的行为与用 Function 类明确创建的函数行为是相同的。
ECMAScript 只有公用作用域
对 ECMAScript 讨论上面这些作用域几乎毫无意义,因为 ECMAScript 中只存在一种作用域 - 公用作用域。ECMAScript 中的所有对象的所有属性和方法都是公用的。因此,定义自己的类和对象时,必须格外小心。记住,所有属性和方法默认都是公用的!
关键字 this
this 的功能
在 ECMAScript 中,要掌握的最重要的概念之一是关键字 this 的用法,它用在对象的方法中。关键字 this 总是指向调用该方法的对象,例如:var oCar = new Object; oCar.color = "red"; oCar.showColor = function() { alert([code]this.color);
};
oCar.showColor(); //输出 "red"[/code]
实现继承的方法
对象冒充
所有新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法:function ClassB(sColor, sName) { this.newMethod = ClassA; this.newMethod(sColor); delete this.newMethod; this.name = sName; this.sayName = function () { alert(this.name); }; }
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
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() { } [code]ClassB.prototype = new ClassA();
混合方式
这种继承方式使用构造函数定义类,并非使用任何原型。对象冒充的主要问题是必须使用构造函数方式,这不是最好的选择。不过如果使用原型链,就无法使用带参数的构造函数了。开发者如何选择呢?答案很简单,两者都用。 代码如下: function ClassA(sColor) { this.color = sColor; } ClassA.prototype.sayColor = function () { alert(this.color); }; function ClassB(sColor, sName) { [code]ClassA.call(this, sColor);
this.name = sName;
}
ClassB.prototype = new ClassA();
ClassB.prototype.sayName = function () {
alert(this.name);
};[/code]
相关文章推荐
- .NET的一些但三方组件(虽然链接一些过期的,但是组件确实有些还是好用的,留给自己备忘了)
- Android 进程常驻(使用第三方MarsDaemon)(虽然不可用,但是还是保留下。)
- 果冻新闻的项目,虽然很难,但是,还是坚持下来
- 注册表修改之后,是不会生效的,需要重启,或者执行如下操作(但是有些按这样操作也还是不能立即生效,最保险的方式还是通过重启电脑来实现)
- cpu gpu做矩阵乘法效率比对,虽然如此,但是对需要自己做的算法是否能如此高效的提高还是未知
- 改进iOS客户端的升级提醒功能--(by cos_sin_tan 虽然是转载的,但是我还是很有兴趣实现他的说法。)
- 浏览器的缓存究竟是什么?为什么j2ee的web工程的js明明修改了,但是浏览器中展示的,并没有改变,还是之前的,即和j2ee的web工程的代码中的不一致
- 公历转农历模块,虽然是js文件,不过还是提供了实现方法,感谢提供者。
- 虽然发生了这种事情,不过我还是挺你!
- web项目发布到服务器上,但是修改的css和js文件没有起作用,显示的还是之前没有修改的代码
- 技术之美[程序人生]一篇IT企业工资表,虽然有些不够准确,但还是可以进行参考的
- 对象数组的使用及this指针(自己改的,虽然只是一小点,但是还是有成就感)
- android:finishOnTaskLaunch="true" //虽然这样设置了,但是Back键与Home键还是不同
- 虽然是假的,但是我还是很高兴
- 自己写了一个js,但是最终不能控制住最后后的提交,前面的还是比较完美,大家看到后,能帮我解决一下吗?
- ruby的aop,虽然不知道为什么ruby要用aop但是还是学些下这个思想
- sdwebimagedownloader。m这个文件里面加了user-agent验证就可以了,现在问题虽然解决了。但是还是没搞懂原因
- 虽然我不是windows端程序员,但是这个IOCP讲的还是可以的
- 证明一下余额宝的收益虽然有复利,但是还是赶不上买银行理财
- FTPrep, 116 Populating Next Right Pointers in Each Node, TODO,再多code几遍,虽然总结写得还比较ok,但是还是手感不熟