3

我习惯将所有变量设置为其父范围,而不是隐式调用它们:

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

这样如果我输入错误的变量,它就不会进入全局空间。但似乎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]

如果我理解正确,它不应该发生,因为两者都f1应该f2使用this. 我在这里缺少任何概念吗?还是我现在只能忍受?

f1更新:澄清一下,我主要关心的是为什么和之间存在差异f2。我更喜欢保持f2隐藏,因为它会做一些内部工作,而其他开发人员在声明来自f().

4

3 回答 3

4

也试试这个:

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();

这样 f2 的上下文将被正确设置。

在您的代码this中 f2 指的是窗口对象,因为 f2 没有被声明为方法。f1 在编写时被声明为返回对象的方法{ x:x , f1:f1 }。在 f2 中 x 是可见的,不是因为它在 f() 的范围内运行,而是因为 f2 将它作为闭包。这意味着在 f2 中,创建时位于同一范围内的所有变量都是可见的。

引用的this内容将在调用时设置。如果您将函数作为对象的属性运行,foo.f1()则将其视为方法,this并将被设置为对象。但是,当您只调用一个函数时,f2()其作用域将与调用它的作用域相同,在您的情况下它是窗口对象,因为 foo 是窗口对象中的全局对象。

在 f1 中 this 指的是隐藏的 f(),因此如果您希望 f2 也可以在该范围内运行,您可以使用f2.call(this). .call() 的参数将是this运行时函数的参数。

于 2013-03-18T21:20:14.123 回答
0

当您的f函数返回一个对象时,它没有f2方法。f2方法是内部方法,f只存在于其范围内。

如果您使用此代码:

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();

然后thisinf1方法将可以访问 的f2方法this,并且对象的f2方法将返回正确的x

于 2013-03-18T21:12:24.467 回答
0

你从函数中返回了这个:

{ x : x, f1 : f1 }

这会将this对象属性设置为上述内容。f2不是对象的一部分,因此它无法访问this它所引用的。

于 2013-03-18T21:15:44.883 回答