本文主要总结了javascript中一些不起眼的地方。虽然不起眼,但有时这些细节很重要。知识点来源于《Javascript权威指南第五版》和个人的一些实践经验。
细节一:typeof 的返回值
大家都知道typeof 返回的是字符串(嗯!废话)。但有一些特别的对象,它的返回值是需要留意的。有一点很重要:所有的构造函数都是Function 的实例 ,包括Object /String /Array /Date /Number ...的内部对象构造函数名。看下面代码和注释:
alert(typeof null); //值为"object" alert(typeof undefined);//值为"undefined" alert(typeof [1,2,3]);//值为"object" alert(typeof function(){});//值为"function" alert(typeof Object);//值为"function"。原因是Object是一个构造函数,所以typeof String/Array...都是function
细节二:== ,!= ,=== ,!== 之间的区别
== /!= 与=== /!== 唯一的区别就是== /!=认为 undefined 和null相等,而 === /!==则不相等 !看下面代码和注释
alert(null==undefined);//值为true; alert(null!=undefined);//值为false; alert(null===undefined);//值为false; alert(null!==undefined);//值为true;
细节三:in ,for in ,hasOwnProperty ,propertyIsEnumerable ,isPrototypeOf
in :判断一个对象中是否包含有该属性或方法(包含对象的一切属性,包括内部类型属性或方法:valueOf ,toString ,toLocalString ,hasOwnProperty 等等)
in /for in :枚举一个对象内的属性或方法(包括该对象原型中的属性或方法和该对象实例的属性或方法,但不包括内部类型属性或方法:valueOf ,toString ,toLocalString ,hasOwnProperty 等等 。但有一点很奇怪,当重写内部类型的属性或方法后,firefox能检出重写的属性,而IE不能) 。
hasOwnProperty (x):该方法继承自Object,判断当前对象是否包含名字为x的属性或方法(不包括从原型中继承来的属性)。
propertyIsEnumerable (x):继承自Object,判断属性x是否为实例属性(不包括从原型中继承的属性或方法)并且该属性是否能枚举。
isPrototypeOf (o):判断当前对象是不是o的原型对象。
具体请看下面代码和注释:
//定义一个Rectangle对象并创建它的一个实例rectangle; function Rectangle(w,h){ this.w=w; this.h=h; } Rectangle.prototype.area=function(return this.w*this.h); Rectangle.prototype.color="red"; var rectangle=new Rectangle(10,20); rectangle.border=1; //测试in alert("w" in rectangle);//true alert("color" in rectangle);//true alert("border" in rectangle);//true alert("toString" in rectangle);//true alert("isOwnProperty" in rectangle);//true //测试for in var names=[]; for(var name in rectangle){ names.push(name); } alert(names);//结果:['w','h','area','color','border'](顺序未必一样) //测试hasOwnProperty alert(rectangle.hasOwnProperty("w"));//true alert(rectangle.hasOwnProperty("color"));//false alert(rectangle.hasOwnProperty("area"));//false alert(rectangle.hasOwnProperty("border"));//true //测试propertyIsEnumerable alert(rectangle.propertyIsEnumerable("w"));//true alert(rectangle.propertyIsEnumerable("color"));//false alert(rectangle.propertyIsEnumerable("area"));//false alert(rectangle.propertyIsEnumerable("border"));//true //测试isPrototypeOf。要判断一个对象A.prototype为对象B的原型的充分条件是B.constructor==A alert(Rectangle.prototype.isPrototypeOf(rectangle));//true:rectangle.constructor==Rectangle alert(Function.prototype.isPrototypeOf(Object));//true:Object.constructor==Function
细节四:var 对全局,局部变量的影响
当变量在一个局部作用区域中定义时,不带var将会把该变量定义为全局变量。代码如下:
(function(){ global="I'm global variable!"; var local="I'm local variable!"; })(); alert(global);//I'm global variable! alert(local);//Error occor:local is undefined
细节五:|| 运算符在赋值语句中的作用
|| 应用在赋值语名中时,会从左到右地检测各个表达式,返回第一个为true 的表达式,否则返回最后一个表达式。
var a,b=0,c=1,d; x=a||b||c||d;//x的值为1;实际上是x=c; var e=0,f=0,g=0,h; y=e||f||g||h;//y的值为undefined;实际上是y=h;
细节六:“” ,null ,undefined 在一个逻辑表达式内返回false
直接看代码和注释吧:
alert(""||null||undefined);//false