`
王世纪
  • 浏览: 17260 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JavaScript null 与0

阅读更多

  得到便利,总是要付出代价的!!

本周遇到一个JavaScript问题,思来想去只能用这句话来总结了。

简单来说,就是将某一个值和0进行比较,但是有些异常情况导致结果怪异,最后发现是在某些情况下那个值有可能是’’,也就是空值,而空值和0JavaScript中是相等的,这个之前由于研究的不深,不知道这个内容,感觉有些不可思议,就问了下虞青,查了些资料,不敢独享,如果已知,敬请忽略。

 

首先从JavaScript中的对象说起,JavaScript有六种对象 numberstringobject 以及 Boolean 类型,其他两种类型为 null undefined

String 字符串类型:字符串是用单引号或双引号来说明的。

数值数据类型:JavaScript 支持整数和浮点数。

Boolean 类型:可能的 Boolean 值有 true false

Undefined 数据类型:一个为 undefined 的值就是指在变量被创建后,但未给该变量赋值以前所具有的值。

Null 数据类型:null 值就是没有任何值,什么也不表示。

object类型:除了上面提到的各种常用类型外,都是object

<script type="text/javascript">

    alert(typeof(false) === 'boolean');

    alert(typeof(0) === 'number');

    alert(typeof("") === 'string');

    alert(typeof(null) === 'object');

    alert(typeof undefined === 'undefined');   

</script>

alert(typeof(null) === 'object');JavaScript最初实现的一个错误,然后被ECMAScript沿用了,也就成为了现在的标准。因此js中虽然有null类型,但是typeof null却是object

undefinednull都表示空值

由于JavaScript是弱类型的,因此var  v1;无法确定v1的类型,在Javascript中对于这种声明后没有给定初始值的变量,就给他一个undefined

也就是  var v1;

alert(v1)   //undefined

也就是声明后没有赋值的就是undefined,但是对于没有声明就直接用的,就会报错,

比如alert(v2) //error

JavaScript中对于object 类型的变量,他有两种情况,一种是他是一个对象的实例,另一种他是一个空引用null,熟悉类似Java这样面向对象语言的应该很容易理解。对于这两种情况,他们的类型都是object

var  v2 = new Date();

alert(type(v2)) //object

v2=null;

alert(type(v2)) //object

并且null参与数值运算的时候自动转换为0,因此123+null =123;123*null=0

另外nulljs的关键字

undefined不是关键字,但却是一个属性,而且是全局对象(window)的属性

alert('undefined' in window); //输出:true

alert(undefined in window); //输出:true

随便说一下,NaN是全局对象(window)的另一个特殊属性,Infinity也是。这些特殊属性都不是JavaScript的保留关键字!

另外再扯远一点,当我们将一个变量或值与undefined比较时,实际上是与window对象的undefined属性比较。

由于window对象的属性值是非常多的,在每一次与undefined的比较中,搜索window对象的undefined属性都会花费时间。在需要频繁与undefined进行比较的函数中,这可能会是一个性能问题点。因此,在这种情况下,我们可以自行定义一个局部的undefined变量,来加快对undefined的比较速度。

因为作用域上的变量数量会远远少于window对象的属性,搜索变量的速度会极大提高。这就是许多前端JS框架为什么常常要自己定义一个局部undefined变量的原因!

下面再来说下 Javascript中的等号运算符,

以下参考自http://www.w3school.com.cn/js/pro_js_operators_equality.asp

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

ECMAScript 中,等号由双等号(==)表示,看好了了是两个等号,当且仅当两个运算数相等时,它返回 true。非等号由感叹号加等号(!=)表示,当且仅当两个运算数不相等时,它返回 true。为确定两个运算数是否相等,这两个运算符都会进行类型转换。

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

1.如果一个运算数是 Boolean 值,在检查相等性之前,把它转换成数字值。false 转换成 0true 1

2.如果一个运算数是字符串,另一个是数字,在检查相等性之前,要尝试把字符串转换成数字。

3.如果一个运算数是对象,另一个是字符串,在检查相等性之前,要尝试把对象转换成字符串。

4.如果一个运算数是对象,另一个是数字,在检查相等性之前,要尝试把对象转换成数字(通过toString()或者valueOf()方法)

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

5. null undefined 相等。

6.在检查相等性时,不能把 null undefined 转换成其他值。

7.如果某个运算数是 NaN,等号将返回 false,非等号将返回 true

8.如果两个运算数都是对象,那么比较的是它们的引用值。如果两个运算数指向同一对象,那么等号返回 true,否则两个运算数不等。

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

obj1是一个对象,而obj2是一个结构与之完全不同的字符串,而如果用相等操作符来判断,则两者是完全相同的,因为obj1重载了顶层对象的toString()方法。

<scripttype="text/javascript">

    alert(false == undefined);     //false

alert(false == null);           //false

alert(false == 0);             //true

    alert(false == "");            //true

alert(null == undefined);      //true

alert('' == 0);                //true

alert('0' == 0);               //true

alert('' == '0');               //false

 

var obj1 = {id : "self", 

     toString : function(){ 

       return "object 1"; 

    } 

}

var obj2 = "object 1"; 

alert(obj1 == obj2);           //true

alert(obj1 === obj2);          //false

</script>

alert('' == 0);alert('0' == 0); alert('' == '0');   这几个的比较大家要好好思考了,哈哈

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

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

<scripttype="text/javascript">

    alert(false === undefined);     //true

alert(false === null);           //false

alert(false === 0);             // false

    alert(false === "");            // false

alert(null === undefined);      // false

alert('' === 0);                // false

alert('0' === 0);               // false

alert('' === '0');               //false

</script>

alert(false === undefined);  返回为true,大家可以想想为什么,留个思考题吧

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics