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

时间:2012-03-12 20:23:46

标签: 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();

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

4 个答案:

答案 0 :(得分:35)

JavaScript对特殊名称this所指的内容有不同的概念 比大多数其他编程语言。确切地说不同 this的值可以用语言绑定的方式。

全球范围

this;

在全局范围内使用this时,它只会引用全局对象。

调用函数

foo();

此处,this将再次引用全局对象。

  

ES5注意:在严格模式下,全局案例不再存在。   在这种情况下,this的值将为undefined

调用方法

test.foo(); 

在此示例中,this将引用test

调用构造函数

new foo(); 

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

使用call的{​​{1}}或apply方法时,值为。{ 被调用函数内的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(); } 内的this指的是test;而在 事实上,

要从Foo内获取对Foo的访问权限,必须创建一个 test内的局部变量,指的是method

Foo

Foo.method = function() { var that = this; function test() { // Use that instead of this here } test(); } 只是一个普通的变量名,但它通常用于引用 外that。与封闭相结合,它也可以 用于传递this值。

分配方法

在JavaScript中工作的另一件事是函数别名,即 为变量分配方法。

this

由于第一种情况,var test = someObject.methodTest; test(); 现在就像一个普通的函数调用;因此, 其中的test将不再引用this

虽然someObject的后期绑定起初可能看起来不是一个坏主意,但是 事实上,它是原型继承工作的原因。

this

function Foo() {} Foo.prototype.method = function() {}; function Bar() {} Bar.prototype = Foo.prototype; new Bar().method(); 的实例上调用method时,Bar现在会引用该this 非常实例。

免责声明: http://bonsaiden.github.com/JavaScript-Garden/#function.this

从我自己的资源中偷走了无耻

答案 1 :(得分:1)

您之所以将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();

答案 2 :(得分:1)

所有功能的范围是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();
}

答案 3 :(得分:1)

因为没有任何对象引用而不调用函数f()。尝试,

f.apply(this);