Javascript:为什么"这个“;内部私有函数指的是全局范围

Javascript: why "this" inside the private function refers to the global scope?

本文关键字:函数 范围 全局 内部 为什么 quot 这个 Javascript      更新时间:2023-09-26

考虑以下代码:

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

为什么函数"f"内部的"this"引用全局作用域?为什么它不在函数"A"的范围内?

JavaScript对特殊名称this的含义有不同的概念与大多数其他编程语言相比CCD_ 2的值可以在语言中绑定的方式。

全球范围

this;

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

调用函数

foo();

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

ES5注意:在严格模式下,全局事例不再存在。在这种情况下,CCD_ 5将具有CCD_ 6的值。

调用方法

test.foo(); 

在本例中,this将指代test

调用构造函数

new foo(); 

前面有new关键字的函数调用充当构造函数。在函数内部,this将参考到新创建的CCD_ 11。

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

当使用Function.prototypecallapply方法时被调用函数内的this显式设置为的第一个参数对应函数调用的。

因此,在上面的示例中,方法用例不适用,并且this则CCD_ 18的内部将被设置为CCD_。

注意:this0不能用于引用Object内部的对象字面意义的因此var obj = {me: this}而不是导致me引用obj,因为this只被列出的五个案例中的一个绑定。

常见陷阱

虽然这些情况中的大多数都有道理,但第一种情况将被视为另一种情况语言的错误设计,因为它从来没有任何实际用途。

Foo.method = function() {
    function test() {
        // this is set to the global object
    }
    test();
}

一个常见的误解是test内部的this指的是Foo;在事实上,它不是。

为了从test中访问Foo,有必要创建引用CCD_ 32的CCD_ 31内部的局部变量。

Foo.method = function() {
    var that = this;
    function test() {
        // Use that instead of this here
    }
    test();
}

that只是一个普通的变量名,但它通常用于引用外CCD_ 34。与闭包相结合,它还可以可用于传递周围的CCD_ 35值。

指定方法

在JavaScript中不起作用的另一件事是函数别名,它是为变量分配方法。

var test = someObject.methodTest;
test();

由于第一种情况,test现在的作用就像一个普通的函数调用;因此其内部的CCD_ 37将不再引用CCD_。

虽然this的后期结合起初可能看起来是个坏主意,但在事实上,正是它让原型继承发挥了作用。

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

methodBar的实例上被调用时,this现在将引用正是这样。

免责声明:羞耻从我自己的资源中窃取http://bonsaiden.github.com/JavaScript-Garden/#function.this

原因是您调用f作为function而不是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();

所有函数的作用域都是window

为了避免这种情况,你可以这样做:

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

因为在没有任何对象引用的情况下不会调用函数f()。试试,

f.apply(this);