[关闭]
@greenfavo 2015-12-14T14:38:58.000000Z 字数 1270 阅读 653

js变量与声明提前

博客


一,null与undefined区别

1,null是js语言的关键字,是一个特殊的对象值,含义是“非对象”,常用来描述“空值”。对null执行typeof运算返回字符串“object”。
typeof(null);//=>"object"
2,null可以表示数字,字符串和对象的“无值”。null用来表示尚未存在的对象,常用来表示函数企图返回一个不存在的对象。
3,null可作为对象的参数,表示该函数的对象不是参数。
4,null可作为对象原型链的终点。
5,undefined是变量的一种取值,表明变量没有初始化。
6,undefined是预定义的全局变量,不是js关键字,它的意思是“未定义”。
7,如果要查询对象属性或数组元素的值时返回undefined则说明该值不存在。
8,如果函数没有返回值,则返回undefined。
9,null是一个表示”无”的对象,转为数值时为0;undefined是一个表示”无”的原始值,转为数值时为NaN。

总结:null总是和对象有关,表示不是对象或不存在该对象或空对象。undefined总是和值有关,表示缺少值,即此处应该有一个值,但还没有定义。

二,函数作用域和声明提前

与C语言不同,js没有块级作用域,而是使用了函数作用域,即变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。
js的函数作用域是指在函数内声明的所有变量在函数体内任意位置都是可见的。这意味着变量在声明之前甚至已经可用。js的这个特性被非正式地成为声明提前,即js函数里声明的所有变量(但不涉及赋值)都被“提前”至函数体的顶部。

    var scope="global";
    function f(){
        console.log(scope);//=>undefined
        var scope="local";
        console.log(scope);//=>local
    }
    f();

当函数内部的变量与全局变量同名时,全局变量会被覆盖,所以函数第一行的scope变量不是指全局的scope变量。由于声明提前,函数内声明的scope被提前到函数顶部,但赋值并未提前,赋值还是在原来的地方起作用,所以第一个console执行时scope只是被声明了,还没有被赋值,所以会输出undefined。第二个console输出local也是理所当然了,此处的scope已经被声明且赋值了。

总结:虽然可以在使用时再声明该变量,但特意将变量的声明放在函数顶部有利于非常直观地反映真实的变量作用域。

三,避免污染全局命名空间

  1. //反例
  2. function foo(){
  3. var a=b=1;
  4. //...
  5. }

此时b是未声明的,是全局变量,成为全局变量window的属性。a是局部变量。因为表达式是从右往左赋值。

通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的。
无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的。
这表明,在技术上,隐式全局变量并不是真正的全局变量,但它们是全局对象的属性。属性是可以通过delete操作符删除的,而变量是不能的:

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注