简体   繁体   English

Javascript:使用'this'访问'private'子函数中的外部范围变量时得到'undefined'

[英]Javascript: got 'undefined' when using 'this' to access outer scope variable in 'private' child function

I have a habit of setting all my variables to its parent scope, instead of calling them implicitly: 我习惯将所有变量设置为其父作用域,而不是隐式调用它们:

function outer() {
    var x, y;
    function inner() {
        var x = this.x;
        x = ...// doing stuff here
        y = ....// implicit calling parent variable
    }
}

so that if I mistype my variable, it won't go to global space. 因此,如果我输入错误的变量,它将不会进入全局空间。 But it seems like declare variable with this within private function will return me undefined : 但似乎在私有函数中声明变量与this将返回undefined

function f() {
    var x = [0];
    function f1() { 
        console.log('f1:', this.x, x); 
        f2(); 
    }
    function f2() { 
        console.log('f2:', this.x, x); 
    }
    return { x:x , f1:f1 };
}

var foo = f();    
foo.f1();
    //output
    f1: [0] [0]
    f2: undefined [0]

If I understand it correctly, it shouldn't happen, as both f1 and f2 should have access to its outer scope by using this . 如果我理解正确的话,这是不应该的,因为这两个f1f2应通过访问其外部范围this Is there any concept I am missing here? 我在这里缺少什么概念吗? Or is it something I just have to live with for now? 或者它是我现在必须要忍受的东西?

Update: To clarify, my main concern is why there is the difference between f1 and f2 . 更新:为了澄清,我主要担心的是为什么f1f2之间存在差异。 I prefer to keep f2 hidden because it will do some internal works, and other developers should not use it when they declare something from f() . 我更喜欢保持f2隐藏,因为它会做一些内部工作,而其他开发人员在从f()声明某些东西时不应该使用它。

Also try this: 也试试这个:

function f() {
    var x = [0];
    function f1() { 
        console.log('f1:', this.x, x); 
        f2.call(this); 
    }
    function f2() { 
        console.log('f2:', this.x, x); 
    }
    return { x:x , f1:f1 };
}

var foo = f();    
foo.f1();

This way the context of f2 will be properly set. 这样就可以正确设置f2的上下文。

In your code this in f2 refers to the window object, because f2 wasn't declared as a method. 在你的代码中, this在f2中引用了window对象,因为f2没有被声明为方法。 f1 was declared as a method of the returned object when writing { x:x , f1:f1 } . 在写{ x:x , f1:f1 }时,f1被声明为返回对象的方法。 In f2 x is visible not because it is run in the scope of f() but because f2 gets it as a closure. 在f2中,x是可见的,不是因为它在f()的范围内运行,而是因为f2将它作为闭包。 That means in f2, all variables will be visible that was in the same scope when it was created. 这意味着在f2中,所有变量都是可见的,它们在创建时处于相同的范围内。

What the this refers to will be set at invocation time. this引用的内容将在调用时设置。 If you run a function as property of an object like foo.f1() it is considered as a method, and this will be set to the object. 如果您运行的功能就像一个对象的属性foo.f1()它被认为是一种方法,而this将被设置为对象。 But when you just invoke a function like f2() the scope will be the same it was invoked in, in your case it is the window object, because foo is a global in the window object. 但是当你调用像f2()这样的函数时,范围将与调用它一样,在你的情况下它是window对象,因为foo是window对象中的全局。

In f1 this refers to the hidden f(), therefore if you want f2 also be run in that scope you can use f2.call(this) . 在f1中,这指的是隐藏的f(),因此如果你想在该范围内运行f2,你可以使用f2.call(this) The argument of .call() will be the this of the function when run. .CALL()的参数将是this功能在运行时。

When your f function returns an object, it doesn't have f2 method. f函数返回一个对象时,它没有f2方法。 f2 method is an inner method of f and exists only in its scope. f2方法是f的内部方法,仅存在于其范围内。

If you use this code: 如果您使用此代码:

function f() {
    var x = [0];
    function f1() { 

        console.log('f1:', this.x, x); 
        this.f2(); 
    }
    function f2() { 
        console.log('f2:', this.x, x); 
    }
    return { x:x , f1:f1, f2:f2};
}

var foo = f();    
foo.f1();

then this in f1 method will have access to the f2 method of this , and object's f2 method will return the correct x . 那么thisf1方法将有机会获得f2的方法this和对象的f2方法将返回正确的x

You returned this from the function: 你从函数中返回了这个:

{ x : x, f1 : f1 }

This sets the the this objects properties to the above. this对象属性设置为上述。 f2 is not apart of the object so it can't access the this that it refers to. f2是不分开的物体的,因此它不能访问this ,它指的是。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM