[英]Javascript: why “this” inside the private function refers to the global scope?
Consider the following code: 请考虑以下代码:
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();
Why does 'this' inside function 'f' refers to the global scope? 为什么函数'f'中的'this'指的是全局范围? Why it is not the scope of function 'A' ?
为什么它不是功能'A'的范围?
JavaScript has a different concept of what the special name this
refers to than most other programming languages do. JavaScript有什么样的特殊名称的不同概念,
this
是指比大多数其他编程语言做。 There are exactly five different ways in which the value of this
can be bound in the language. 有五种不同的方式可以将
this
值绑定在语言中。
this;
When using this
in global scope, it will simply refer to the global object. 当使用
this
在全球范围内,它会简单地引用全局对象。
foo();
Here, this
will again refer to the global object. 在这里,
this
将再次引用全局对象。
ES5 Note: In strict mode, the global case no longer exists.
ES5注意:在严格模式下,全局案例不再存在。
this
will instead have the value ofundefined
in that case.在这种情况下,
this
将取代undefined
的值。
test.foo();
In this example, this
will refer to test
. 在这个例子中,
this
将参考test
。
new foo();
A function call that is preceded by the new
keyword acts as a constructor. 以
new
关键字开头的函数调用充当构造函数。 Inside the function, this
will refer to a newly created Object
. 在函数内部,
this
将引用新创建的 Object
。
this
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
When using the call
or apply
methods of Function.prototype
, the value of this
inside the called function gets explicitly set to the first argument of the corresponding function call. 当使用
Function.prototype
的call
或apply
方法时,被调用函数内的this
值被显式设置为相应函数调用的第一个参数。
As a result, in the above example the method case does not apply, and this
inside of foo
will be set to bar
. 其结果是,在上述例子中所述方法的情况下 不适用,并且
this
内部foo
将被设定为bar
。
Note:
this
cannot be used to refer to the object inside of anObject
literal.注意:
this
不能用于引用Object
文本中的Object
。 Sovar obj = {me: this}
will not result inme
referring toobj
, sincethis
only gets bound by one of the five listed cases.所以
var obj = {me: this}
不会导致me
引用obj
,因为this
只会受到列出的五个案例之一的约束。
While most of these cases make sense, the first one is to be considered another mis-design of the language because it never has any practical use. 虽然大多数这些案例都有意义,但第一个案例被认为是另一种错误的语言设计,因为它从未有任何实际用途。
Foo.method = function() {
function test() {
// this is set to the global object
}
test();
}
A common misconception is that this
inside of test
refers to Foo
; 一个常见的误解是,
this
test
内部是指Foo
; while in fact, it does not . 事实上,事实并非如此 。
In order to gain access to Foo
from within test
, it is necessary to create a local variable inside of method
which refers to Foo
. 为了从
test
获得对Foo
访问,有必要在method
内部创建一个引用Foo
的局部变量。
Foo.method = function() {
var that = this;
function test() {
// Use that instead of this here
}
test();
}
that
is just a normal variable name, but it is commonly used for the reference to an outer this
. that
只是一个普通的变量名,但它通常用于引用外部的this
。 In combination with closures, it can also be used to pass this
values around. 与闭合相结合,它也可用于传递
this
值。
Another thing that does not work in JavaScript is function aliasing, which is assigning a method to a variable. 这并不在JavaScript中工作的另一件事情是功能走样,这是赋值给一个变量的方法。
var test = someObject.methodTest;
test();
Due to the first case, test
now acts like a plain function call; 由于第一种情况,
test
现在就像一个普通的函数调用; therefore, this
inside it will no longer refer to someObject
. 因此,
this
内部将不再引用someObject
。
While the late binding of this
might seem like a bad idea at first, in fact, it is what makes prototypal inheritance work. 虽然后期绑定
this
似乎是一个坏主意,首先,在事实上,这是什么使原型继承工作。
function Foo() {}
Foo.prototype.method = function() {};
function Bar() {}
Bar.prototype = Foo.prototype;
new Bar().method();
When method
gets called on a instance of Bar
, this
will now refer to that very instance. 当
method
被调用上的例子Bar
, this
现在指的是非常的实例。
Disclaimer: Shamelessy stolen from my own resources at http://bonsaiden.github.com/JavaScript-Garden/#function.this 免责声明: Shamelessy从我自己的资源中偷走了http://bonsaiden.github.com/JavaScript-Garden/#function.this
The reason why is you are invoking f
as a function
and not a method
. 你之所以将
f
作为一个function
而不是一个method
来调用。 When invoked as a function this
is set to window
during the execution of the target 当作为函数调用
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();
The scope of all functions is window
. 所有功能的范围都是
window
。
To circumvent that, you can do this: 为了规避这一点,你可以这样做:
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();
}
Because function f()
is not called without any object reference. 因为没有任何对象引用就不会调用函数
f()
。 Try, 尝试,
f.apply(this);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.