Javascript“this”运算符如何处理范围?

时间:2010-10-18 17:29:29

标签: javascript scope operators this

编辑:我要道歉,我发布的问题实际上并不存在于我发布的代码中,因为我过分简化了它。我稍后会尝试发布一些内容。

删除也没关系,但目前答案太多,所以我不能自己做。

编辑2:好的,这里是:

让,

function F() {

    this.field = "value" ;

    var init = function(value) {
        this.field = value ;
    } ;

    this.method = function() {
        return this.field ;
    } ;

    init( arguments[0] ) ;

} 

现在,实例化F类型,

var f = new F("newValue") ;

会将值设置为Window对象,因为this在从闭包调用时指向它。

this绑定到Function

function F() {

    var self = this ;

    this.field = "value" ;

    var init = function(value) {
        self.field = value ;
    } ;

    this.method = function() {
        return this.field ;
    } ;

    init( arguments[0] ) ;

}

将解决问题。

仍然,这是什么原因 - 这种奇怪的行为?

5 个答案:

答案 0 :(得分:2)

这是(引用)调用函数的对象。

因此,在f.method()来电中,this为“f”。不是“F”。

var self = this;有效的事实不是由于此声明本身,而是由于method2() closure

更具体地说,self中的变量method2()的范围由F()确定 - 换句话说,method2()中的“自我”将始终引用当定义“F”时存在的self的值(当时,当然是“F”,因为此时当前对象上下文是“F”)。

答案 1 :(得分:1)

this称为“运营商”是不正确的。它是运行时在函数激活时建立的对象引用。

Javascript只是一种以不同方式处理事物的不同语言。 this受到程序员的控制非常强大。

此外,除非您发布的其他内容为“F”设置原型对象,否则该代码肯定不起作用。 “method”和“method2”都不能从对“F”实例的引用中调用。

答案 2 :(得分:1)

对于方法的定义,您可能希望执行更类似的操作:

this.method = function()
{
    return this.field;
}

答案 3 :(得分:1)

这是你要找的例子吗?

var F = function() {

     var self = this ; //!! points correctly to the Function Object

     this.field = "someValue" ;

     var helper1 = function(){
         return self.field;
     }
     var helper2 = function(){
         return this.field;  
     } 
     this.method = function(){
         return helper1();
     }
     this.method2 = function(){
         return helper2();
     }
 }

 var f = new F() ;
     console.log(f.method()) ; 
     console.log(f.method2()) ; 

在方法的情况下,它调用使用self的helper,它在创建时指向f,因此它可以工作。

在method2的情况下,它使用helper2,它使用它。但是在helper2内部的含义是'全局'范围,因此返回undefined。

答案 4 :(得分:1)

事实证明,这是ECMAScript(因此JavaScript)的ECMA规范的一个黑暗角落:

  

最后,为this关键字指定一个值。如果赋值已引用对象,则属性访问器以该对象的this关键字引用属性为前缀。如果分配的值(内部)为null,则this关键字将引用全局对象。

(http://jibbering.com/faq/notes/closures/;感谢@ Brian Flanagan的链接)

显然,在执行分配给变量的函数(在另一个Function内)时,上下文丢失,因此范围设置为null,this将引用{{1 }} Window


我不太确定这是否可以从Object初始化为局部变量。通常情况下,我希望闭包能够访问它在内存中创建的范围,包括它在范围链中的前身。

此行为与Function Function属性的函数不同,其中上下文不会丢失,Object将正确指向成员this的所有者(Function Function或成员,具体取决于有多少层。


此问题的解决方案(同时维护私有Object成员,即只能从Function范围内访问的成员)使用{将函数包装在另一个Function内{1}}(或Function)手动设置上下文:

Function.prototype.apply

这类似于JavaScript 1.85以及PrototypeJS库中引入的Function.prototype.call

编辑function F() { this.field = "value" ; var self = this ; var init = function(value) { (function() { this.field = value ; }).apply(self,value) ; } ; this.method = function() { return this.field ; } ; init( arguments[0] ) ; } 中所附功能周围的圆括号。这将产生Function.prototype.bind