Javascript:为什么私有函数里面的"this"指的是全局范围?

Meg*_*ooN 16 javascript scope this

请考虑以下代码:

function A() {}    

A.prototype.go = function() {
    console.log(this); //A { go=function()}

    var f = function() {
         console.log(this);  //Window              
    };

    f();
}

var a = new A();
a.go();
Run Code Online (Sandbox Code Playgroud)

为什么函数'f'中的'this'指的是全局范围?为什么它不是功能'A'的范围?

Ivo*_*zel 36

this与大多数其他编程语言相比,JavaScript对特殊名称所引用的概念有不同的概念.恰好有5种中的值不同的方式this可以在语言的约束.

全球范围

this;
Run Code Online (Sandbox Code Playgroud)

this在全局范围内使用时,它将简单地引用全局对象.

调用函数

foo();
Run Code Online (Sandbox Code Playgroud)

这里,this将再次引用全局对象.

ES5注意:在严格模式下,全局案例不再存在. 在这种情况下,this它将具有价值undefined.

调用方法

test.foo(); 
Run Code Online (Sandbox Code Playgroud)

在这个例子中,this将参考test.

调用构造函数

new foo(); 
Run Code Online (Sandbox Code Playgroud)

new关键字开头的函数调用充当构造函数.在函数内部,this将引用一个新创建的 Object.

显性设置 this

function foo(a, b, c) {}

var bar = {};
foo.apply(bar, [1, 2, 3]); // array will expand to the below
foo.call(bar, 1, 2, 3); // results in a = 1, b = 2, c = 3
Run Code Online (Sandbox Code Playgroud)

当使用callapply方法时Function.prototype,被this调用函数内部的值 被显式设置为相应函数调用的第一个参数.

其结果是,在上面的例子中的方法的情况下不能适用,而this 内部foo将被设定为bar.

注意: this 不能用于引用Object 文字内的对象.因此,var obj = {me: this}不会导致me提到 obj,因为this只有得到由五列有一个约束.

常见的陷阱

虽然大多数这些案例都有意义,但第一个案例被认为是另一种错误的语言设计,因为它从未有任何实际用途.

Foo.method = function() {
    function test() {
        // this is set to the global object
    }
    test();
}
Run Code Online (Sandbox Code Playgroud)

一个常见的误解是this内部test指的是Foo; 事实上,事实并非如此.

为了Foo从内部获得访问权限test,有必要创建一个局部变量,在method其中引用Foo.

Foo.method = function() {
    var that = this;
    function test() {
        // Use that instead of this here
    }
    test();
}
Run Code Online (Sandbox Code Playgroud)

that只是一个普通的变量名,但它通常用于引用外部this.与闭包相结合,它还可用于传递this值.

分配方法

,它的另一件事不是在JavaScript工作功能混淆,这是 分配给一个变量的方法.

var test = someObject.methodTest;
test();
Run Code Online (Sandbox Code Playgroud)

由于第一种情况,test现在就像一个普通的函数调用; 因此, this里面将不再提及someObject.

虽然this最初的绑定可能看起来像一个坏主意,但事实上,这是原型继承工作的原因.

function Foo() {}
Foo.prototype.method = function() {};

function Bar() {}
Bar.prototype = Foo.prototype;

new Bar().method();
Run Code Online (Sandbox Code Playgroud)

method在一个实例上调用时Bar,this现在将引用该实例.

免责声明: Shamelessy从我自己的资源中偷走了http://bonsaiden.github.com/JavaScript-Garden/#function.this


Jar*_*Par 1

原因是您f作为 afunction而不是 a调用method。当作为函数调用时this设置为window在目标执行期间

// Method invocation.  Invoking a member (go) of an object (a).  Hence 
// inside "go" this === a
a.go();

// Function invocation. Invoking a function directly and not as a member
// of an object.  Hence inside "f" this === window
f(); 

// Function invocation. 
var example = a.go;
example();
Run Code Online (Sandbox Code Playgroud)