关于JavaScript的十个古怪之处和秘密
关于JavaScript的十个古怪之处和秘密这是此书的第四章,Andy Croxall说:js,奇异而美丽,如同是巴勃罗毕加索发明了这门语言一般.Null显然是一个对象,空数组显然等于false,函数像网球一样随意传递.
数据类型和定义中的奇异之处
1.Null是一个对象
null是最具争议性的对象.
alert( typeof null); //alerts 'object'
尽管如此,null并不被看作是对象的实例(重提一下,在js中,值是基准对象的实例.因此,数值是Number对象的实例,所有对象均是Object对象的实例).
让我们推算一下,如果null表示没有值,那么很明显它不能作为任何东西的实例.因此,下式等于false:
alert( null instanceof Object); //false
instanceof运算符用于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置
2.NaN是一个数字
NaN(not a number)不是一个数字,就像女人有时候会骂她的男盆友,你不是个男人一样,实际上,他还是个男人,NaN也还是个数字!而且NaN不被认为等于自身.
alert( typeof NaN); //'Number' alert( NaN === NaN ); //false
确实一个数据类型为NaN的唯一方法是通过调用isNaN()函数
3.[]==false
这是另一个很受喜爱的js古怪之处
alert( [] == false ); //true
为了明白这里发生什么,你需要明白在js中所有非布尔类型值都有一个内置的布尔标志,当需要被当作布尔值时就调用这个布尔标志.因为不同数据类型无法直接进行比较,所以js需要进行不同类型的数进行比较时,需要将其强制转化为通用数据类型.
这里空数组先转换成空字符串,空字符串再转换为布尔值false.
false,0,null,undefined,”和NaN都变成false.
但你可能注意到我再false列表中并没给出空数组空数组非常奇特:它实际上等于true,但是在于布尔值比较是,却被看作false,请看下例
var someVar = [];
alert(someVar==false); //true if(someVar)alert('hello'); //alert hello
为了避免强制类型转换,你可以使用值,类型比较操作符”===”,(与”==”不同,它只比较值).所以
var someVar = []; alert(someVar==false); //true alert(someVar===false); //false
函数及范围的奇异之处
4.你可以伪造范围
范围定义了变量的可被调用的区域.独立的js(即不在函数内部运行的js)在window对象的全局范围内有效,可被全局访问.而在函数内部声明的局部变量只能在函数内部访问,不能再外部访问.
var animal = 'dog'; function getAnimal(adj){alert( adj +' '+ 'this.animal')} getAnimal('lovely'); //alerts 'loverly dog'
这里我们再全局范围内声明变量和函数,因为一直指向当前范围,本例中this指向getAnimal的范围window,因此函数寻找window.animal很正常,但是我们可以改变函数在不同的范围内运行时的情况,而不是在其当前范围内.我们利用内置的call()方法进行调用,而不是利用函数本身:
var animal = 'dog'; function getAnimal(adj){alert( adj +' '+ 'this.animal')} var myObj = {animal:'camel'} getAnimal.call(myObj,'lovely'); //alerts 'loverly camel'
这里我们就改变了函数getAnimal的范围,在myObj中运行.本质上call方法将函数变成了myObj的一个方法.
我曾听到js开发人员说他们有很多年没有使用这个技巧了,那是因为好的代码设计不需要你采用这种伪造手段,但这依然是非常有趣的知识.
浙公网安备 33010602011771号