我不确定JavaScript中的这一点。我举两个例子。
你可以帮我分析一下吗?非常感谢你。//exmp1
function f1()
{
alert(this);
function f2()
{
alert(this);
}
f2();
}
f1();
//exmp2
var jsn =
{
name : "b",
func : function() // closure
{
alert(this);
return function()
{
return this;
}
}
}
alert(jsn.func()());
答案 0 :(得分:13)
this
在JavaScript中与在C ++或Java等其他语言中的不同。第一个示例中this
的值始终是浏览器上的全局对象(window
)。第二个示例中的this
是第一个警报的jsn
对象,第二个是window
。这是因为this
完全由决定如何调用函数,而不是它被定义的位置。
如果在调用函数时没有做任何特殊操作,this
是全局对象。通过对象属性(jsn.func()
)调用函数时,this
设置为属性来自的对象。 (但不要给人留下错误的印象,func
绝不与jsn
特别相关; JavaScript没有方法,只是函数; details 。)f1
然后返回一个函数,该函数在最终alert
内调用;由于该调用不是通过对象属性,因此将this
设置为全局对象。
一些例子:
// Simple function
function foo() {
alert(this === window);
}
foo(); // true, within the call, `this` === `window`
// Object example, and twist at the end
var obj = {
func: function() {
alert(this === obj);
},
};
obj.func(); // true, within the call, `this` === `obj`
obj["func"](); // true, within the call, `this` === `obj`
var f = obj.func; // Not calling it, just getting a reference to the function
f(); // false, within the call `this` !== `obj` (`this` === `window`)
// Creating functions on the fly, returning them, and how that has
// nothing whatsoever to do with how `this` gets set:
var obj = {
func: function() {
return function() {
alert("I'm a generated function");
alert(this === obj);
};
}
};
obj.func()(); // alerts the "I'm a generated function", then false; `this` !== `obj`
obj.bar = obj.func();
obj.bar(); // alerts the "I'm a generated function", then true; `this` === `obj`
还有第二种方法来控制函数中的this
:使用JavaScript函数的.call
或.apply
功能:
var obj = {
func: function() {
alert(this === obj);
}
};
function foo(a, b) {
alert(this === obj); // Yes, really obj; see below
alert(a);
alert(b);
}
foo(1, 2); // alerts false (`this` !== `obj`), then 1, then 2
obj.func(); // alerts true, `this` === `obj`
foo.call(obj, 3, 4); // alerts true (`this` === `obj`), then 3, then 4
foo.apply(obj, [5, 6]); // alerts true (`this` === `obj`), then 5, then 6
如您所见,call
或apply
的第一个参数是在函数调用中生成this
的对象。 call
和apply
之间的唯一区别是如何指定传递给目标函数的参数:使用call
,您只需在第一个参数之后提供它们;使用apply,您可以将它们作为数组提供。
最后,还有第三种方式:new
关键字。 JavaScript具有构造函数的概念。构造函数的目的是创建以特定方式初始化的对象的实例。这是一个例子:
function Foo(b) {
this.bar = b;
}
var f = new Foo();
从技术上讲,任何函数都可以用作构造函数。惯例是给出用于以大写字母开头的new
名称的函数,以加强我们以特殊方式调用它们。
通过new
调用函数会创建一个新的对象实例,并使该对象成为函数调用中的this
值。所以
function Foo(b) {
alert(this === window);
}
var f = new Foo(); // alerts false, `this` !== `window` (it points to the new object created for the call)
var f = Foo(); // alerts true, `this` === `window` because we didn't use `new`
如您所见,以正确的方式调用函数非常重要。如果它设计为与new
一起使用,请通过new
调用它;如果不是,请不要。
(new
不只是创建一个空白对象;创建的对象还有一些其他方面以某种方式设置。我不会在这里详细介绍,但我不想离开您认为它所做的所有的印象是创建一个新的对象实例。)
答案 1 :(得分:1)
在上一个例子中(json对象中的函数),this
指的是持有该函数的json对象。
在第一个示例中,第一个this
指的是持有f1
的对象,它恰好是全局窗口对象。 this
中的第二个f2
也指向全局对象而不是f1,当您在另一个中定义了一个函数时,这是javascript 中的已知错误。
一个常见的解决方法是这个(没有双关语):
function f1() {
alert (this);
var that = this;
function f2() {
alert (that);
}
f2();
}
请注意,如果在json对象中定义一个函数,它仍然可以“移动”,this
的上下文将会改变。例如:
var car1 = {
color: "red",
f: function () { alert (this.color); }
}
car1.f(); // prints "red"
var car2 = {
color: "blue",
}
car2.f = car1.f;
car2.f(); // prints "blue"
答案 2 :(得分:1)
在JavaScript中,“this”总是指“拥有”该函数的对象,或者更确切地说,是指函数在调用时通过属性绑定到的对象。考虑这个例子:
var f = function() { alert(this); }
f(); // Alerts the "DOM window" (global) object, which
// is implied if there is no explicit owner.
var o = {toString:function(){return "Foo!";}}
o.func = f;
o.func(); // Alerts the "Foo!" object (o) since the
// function then belongs to it as a member.
现在关于您的具体示例,以下是发生的情况:
//exmp1
function f1() {
alert(this);
function f2() {
alert(this);
}
f2(); // Alerts "the global object", since f2
// is not bound to any object's property.
}
f1(); // Alerts "the global object" (probably DOM window)
// for same reason as above.
//exmp2
var jsn = {
name : "b",
func : function() {
alert(this); // Will alert the "jsn" object, since it
// owns the function in its "func" member.
return function() {
return this; // Returns whoever is calling it!
};
}
}
alert(jsn.func()()); // "jsn.func()" returns a function which gets
// called by the global "DOM window" object.
答案 3 :(得分:0)
当您使用函数作为构造函数时,它指向您正在构造的对象。
function Test() {
this.test = true;
}
t = new Test();
alert(t.test);