关注前端开发
HTML5、CSS3、Javascript

关于私有函数内部this指向的讨论

看下面这段“诡异”的代码

var ob = function(){

var obj = this;

function fn1(){

alert( obj === window );//false

alert( this === window );//ture

}

fn1();

}

假如我们试图这样操作:new ob(); 大家知道fn1会执行,弹出两个alert, 那么你对那两个alert 的结果感到迷惑吗?如果没有,下面的内容就不用看了,因为你都懂。

关于这个问题,我问了很多人,有两个重要的观点相冲突

Aaron Gustafson ,easy designs 公司的老板,很好的一个朋友,经常帮我解答各种js问题。

他的第一个解释是

Private methods are self-contained objects that exist within the scope of the constructor. They’re not real methods on the prototype, so this within the private method will refer to the private method instance, not the myConstructor instance.

我不太理解,于是问他解释,他回复我说

Ok, so when you create a closure, a lot is determined by the execution context. In the case of the keyword “this,” the global object is assigned to it toward the end of the process (per the internals of the ECMAScript spec) if “this” is unassigned (or null).

其实我还是不太明白,但我试着这样解释

函数是自包含的对象,它创建的时候默认是赋给window全局对象的,当把这个函数赋给另外一个对象的时候,this的指向就会发生改变,我们知道私有函数是严格限制在构造方法里面的,对私有函数来说构造方法只是一个函数,不是对象(他还没被实例化呢),所以它里面的this当然还是指向window。

最终我还是发现我的解释打动不了我,这个时候,我在另外一本书里看到了一个新的解释。

作者是Douglas Crockford,这个人可是js社区里神一级的人物,JOSN 就是这个人发明和维护的。他给出的解释是,

When a function is invoked with this pattern(私有函数), this  is bound to the global object. This was a mistake in the design of the language. Had the language been designed correctly, when the inner function is invoked, this would still be bound to the this variable of the outer function.

简单的说,他认为私有函数创建的时候,this 默认指向全局对象是语言设计的一个错误,他认为正确的模式应该是继承外部函数的this 指向。

这个解释显然更能打动我,于是我询问Aaron,他并不认为这是一个语言设计的错误,但是他也很矛盾,显然他对于自己的解释也不是完全满意,他说他相信Brendan Eich(js创始人)应该有他自己的理由。

讨论还是继续,相信谁的解释取决于读者自己。但是结果就是,如果你想在私有函数内部引用外部对象,唯一的办法就是在外面保存this 的值,你会发现我是这么做的。

this 问题是伪类继承的一个难题,如果你想避开this,我建议你使用js自己的函数式继承,实践证明,借鉴别人的东西不一定是最好的。

转载请注明出处大前端 » 关于私有函数内部this指向的讨论

分享: