simpleapples

重装过100次XP,打过10年红警。

Javascript中new操作符的探究

| 评论

Javascript中有一个很有意思的new操作符,在《Javascript语言精粹》(Javascript:The Good Parts)中,new被列为了不推荐的操作符。下面对于new的使用进行一些探究。
先来一段代码:

function test() {
    var foo1 = new function () {
        this.i = 1;
    }
    var foo2 = function () {  
        this.i = 2;
    }
    M.dis(foo1.i);      //1
    M.dis(foo2.i);      //undefined
    M.dis(this.i);      //undefined
    foo2();
    M.dis(foo2.i);      //undefined
    M.dis(this.i);      //2
    M.dis(foo1.prototype);  //undefined
    M.dis(foo2.prototype);  //[object Object]
}

*代码中的M.dis() = document.writeln()
上面代码很能说明使用new操作符和不使用new操作符的区别。
以下是本人根据以上结果对使用new操作符和不使用new操作符的一些理解。

  1. 使用new操作符函数会被立刻执行。不使用new操作符,函数会在被调用时执行。
    foo1在定义的时候就被执行了,所以输出foo1.i = 1,而foo2在定义时未被执行,所以输出foo2的结果为undefinedfoo2var foo2 = function () {}的定义形式和function foo2 () {}的效果是一样的。

  2. 使用new操作符后this会被绑定到函数本身。

这一点很好理解,首先foo1的定义方式中,foo1是立刻执行的,那么为了方便理解可以看成foo1是function的执行空间,this自然就会绑定到foo1上,也就是绑定到function自身上。于是输出foo1.i可以得到结果。而不使用new操作符时,函数没有立即执行,当调用该函数(即foo2)时,执行空间是test()函数,所以在test()中输出this.i才能得到结果。至于foo2.iundefined的情况也好理解,这样的执行方式相当于执行foo2().i,显然,没有这种用法。

3.使用new操作符和不使用new操作符的原型差异。

使用new操作符时,相当于讲一个构造函数实例化了,那么它的prototype自然是undefined的。
而不使用new操作符时,foo2就是一个function,foo2的prototype就是function的prototype。
关于使用new和不使用new的原型问题,请参考淘宝UED团队的一篇文章:

http://ued.taobao.com/blog/2007/05/15/你真的会写javascript吗?

update1:

对于new操作符的探究目前仅限于new function,而对于new Array()和[] 的区别以及new Object()和{}的区别,本人认为并没有new function和function的区别这么大,但也有人说new Array()和[]是有区别的(见《你真的会写javascript吗?》评论)。

update2:

new Array()和字面量定义Array还有一个很重要的区别,比如想定义一个只有一个元素3的数组,看代码:

var a = new Array(3); //这样只能定义一个长度为3的数组
var b = [3]; //正确!

可见,只有字面量可以定义一个元素的数组。

评论