而今

导航

关于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开发人员说他们有很多年没有使用这个技巧了,那是因为好的代码设计不需要你采用这种伪造手段,但这依然是非常有趣的知识.

posted on 2019-11-27 19:22  而今  阅读(275)  评论(0)    收藏  举报