Javascript:为什么“这个"私有函数里面是指全局作用域吗? [英] Javascript: why "this" inside the private function refers to the global scope?
问题描述
考虑以下代码:
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'的作用域?
Why does 'this' inside function 'f' refers to the global scope? Why it is not the scope of function 'A' ?
推荐答案
JavaScript 对于特殊名称 this
所指的内容有不同的概念与大多数其他编程语言相比.正好有五个不同的this
的值可以在语言中绑定的方式.
JavaScript has a different concept of what the special name this
refers to
than most other programming languages do. There are exactly five different
ways in which the value of this
can be bound in the language.
this;
在全局范围内使用 this
时,它只会引用 global 对象.
When using this
in global scope, it will simply refer to the global object.
foo();
这里,this
将再次引用全局对象.
Here, this
will again refer to the global object.
ES5 注意:在严格模式下,全局大小写不再存在.在这种情况下,this
将改为具有 undefined
的值.
ES5 Note: In strict mode, the global case no longer exists.
this
will instead have the value ofundefined
in that case.
调用方法
test.foo();
在这个例子中,this
将引用 test
.
In this example, this
will refer to test
.
new foo();
以 new
关键字开头的函数调用充当一个构造函数.在函数内部,this
将引用到一个新创建的 Object
.
A function call that is preceded by the new
keyword acts as
a constructor. Inside the function, this
will refer
to a newly created Object
.
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.prototype
的call
或apply
方法时,被调用函数内的 this
被显式设置到第一个参数对应的函数调用.
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.
因此,在上面的例子中,方法案例不适用,而this
foo
的内部将被设置为 bar
.
As a result, in the above example the method case does not apply, and this
inside of foo
will be set to bar
.
注意: this
不能用于引用Object
内部的对象文字.所以 var obj = {me: this}
将 not 导致 me
引用obj
,因为 this
只受到列出的五种情况之一的约束.
Note:
this
cannot be used to refer to the object inside of anObject
literal. Sovar obj = {me: this}
will not result inme
referring toobj
, sincethis
only gets bound by one of the five listed cases.
常见的陷阱
虽然大多数情况都有意义,但第一种情况被视为另一种情况语言的错误设计,因为它从未有任何实际用途.
Foo.method = function() {
function test() {
// this is set to the global object
}
test();
}
一个常见的误解是test
中的this
指的是Foo
;而在事实上,它没有.
A common misconception is that this
inside of test
refers to Foo
; while in
fact, it does not.
为了从 test
中访问 Foo
,有必要创建一个method
内部的局部变量,引用 Foo
.
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
.
Foo.method = function() {
var that = this;
function test() {
// Use that instead of this here
}
test();
}
that
只是一个普通的变量名,但它通常用于引用一个外部 this
.结合闭包,它还可以用于传递 this
值.
that
is just a normal variable name, but it is commonly used for the reference to an
outer this
. In combination with closures, it can also
be used to pass this
values around.
在 JavaScript 中不的另一件事是函数别名,即为变量赋值方法.
Another thing that does not work in JavaScript is function aliasing, which is assigning a method to a variable.
var test = someObject.methodTest;
test();
由于第一种情况,test
现在就像一个普通的函数调用;所以,里面的this
将不再引用someObject
.
Due to the first case, test
now acts like a plain function call; therefore,
this
inside it will no longer refer to someObject
.
虽然 this
的后期绑定乍一看似乎是个坏主意,但在事实上,这就是原型继承起作用的原因.
While the late binding of this
might seem like a bad idea at first, in
fact, it is what makes prototypal inheritance work.
function Foo() {}
Foo.prototype.method = function() {};
function Bar() {}
Bar.prototype = Foo.prototype;
new Bar().method();
当在 Bar
的实例上调用 method
时,this
现在将引用那个非常实例.
When method
gets called on a instance of Bar
, this
will now refer to that
very instance.
免责声明:无耻从我在 http://bonsaiden 上的资源中窃取.github.com/JavaScript-Garden/#function.this
这篇关于Javascript:为什么“这个"私有函数里面是指全局作用域吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!