试图理解 javascript 中的 `this`
Trying to understand `this` in javascript
我有一个具有多种功能的对象:
var someScopeScopedObject = {
myFunction1: function () {
console.log('foo');
},
myFunction2: function () {
this.myFunction1();
}
init: function (callback) {
callback();
}
}
所以如果我调用 someScopeScopedObject.myFunction2
就可以了
但是如果我这样做 someScopeScopedObject.init(someScopeScopedObject.myFunction2)
然后我得到一个错误 this.myFunction1 is undefined
为什么当我以这种方式调用函数时 this
无效?
关键字this
指的是函数作用域。不是全局范围。您声明一个名为 myFunction2
的函数,this
指的是此函数的作用域,而不是声明此函数的作用域。
它不像 C# 这样的语言,其中 this
指的是 class 的当前实例,无论您是在另一个方法中。
this
指的是声明的函数,
所以在你的例子中,
var someScopeScopedObject = {
myFunction1: function () {
console.log('foo');
},
myFunction2: function () {
this.myFunction1();
}
init: function (callback) {
callback();
}
}
myFunction1 没有在 myFunction2 中声明,所以
` myFunction2: function () {
this.myFunction1();
}.
是不可能的,因为 this.myFunction1();
试图调用应该在 myfunction1
中声明的方法 myfunction1 而没有在那里声明。
Edit:
someScopeScopedObject.myFunction2();
是 可能的 因为您正在调用在 someScopeScopedObject
[= 中定义的方法 myFunction1 47=]
someScopeScopedObject.init(someScopeScopedObject.myFunction2);
不可能 因为,在这种情况下,您将 someScopeScopedObject.myFunction2
作为回调函数传递给 init 函数,
init: function (callback) {
callback();
}
然后调用
myFunction2: function () {
this.myFunction1();
}
这里你指的是 this.myFunction1();
--- 这不存在,因为你指的是在 myfunction2 中定义的 myfunction1,而它不存在!
当您将 myFunction2
作为参数传递给某物时,它会丢失对其所属对象的引用。 this
现在指的是函数本身,而不是 someScopeScopedObject
,因此你的问题 :)
这也是为什么一些库为方法采用对象上下文的原因,即。 jasmine 的 spyOn(someScopeScopedObject, "myFunction2")
,以保持范围的正确性。
一个变通方法示例(如 jasmine 使用的变通方法)可能如下所示:
var someScopeScopedObject = {
myFunction1: function () {
console.log('foo');
},
myFunction2: function () {
this.myFunction1();
},
init: function (context, callbackName) {
context[callbackName]();
}
}
这将允许您执行以下操作:
someScopeScopedObject.init(someScopeScopedObject, "myFunction2");
这不是最漂亮的。或者,您可以将对象绑定到函数(因此作用域保持不变)。这假设您的原始代码在 someScopeScopedObject
:
someScopeScopedObject.init(someScopeScopedObject.myFunction2.bind(someScopeScopedObject));
这些都不漂亮,而且,实际上,那是因为从外部 将属于某个对象的函数作为对该对象的回调提供是很奇怪的。
最佳解决方案可能是:
someScopeScopedObject.init(function() {
someScopeScopedObject.myFunction2();
});
我有一个具有多种功能的对象:
var someScopeScopedObject = {
myFunction1: function () {
console.log('foo');
},
myFunction2: function () {
this.myFunction1();
}
init: function (callback) {
callback();
}
}
所以如果我调用 someScopeScopedObject.myFunction2
就可以了
但是如果我这样做 someScopeScopedObject.init(someScopeScopedObject.myFunction2)
然后我得到一个错误 this.myFunction1 is undefined
为什么当我以这种方式调用函数时 this
无效?
关键字this
指的是函数作用域。不是全局范围。您声明一个名为 myFunction2
的函数,this
指的是此函数的作用域,而不是声明此函数的作用域。
它不像 C# 这样的语言,其中 this
指的是 class 的当前实例,无论您是在另一个方法中。
this
指的是声明的函数,
所以在你的例子中,
var someScopeScopedObject = {
myFunction1: function () {
console.log('foo');
},
myFunction2: function () {
this.myFunction1();
}
init: function (callback) {
callback();
}
}
myFunction1 没有在 myFunction2 中声明,所以
` myFunction2: function () {
this.myFunction1();
}.
是不可能的,因为 this.myFunction1();
试图调用应该在 myfunction1
中声明的方法 myfunction1 而没有在那里声明。
Edit:
[= 中定义的方法 myFunction1 47=]someScopeScopedObject.myFunction2();
是 可能的 因为您正在调用在someScopeScopedObject
someScopeScopedObject.init(someScopeScopedObject.myFunction2);
不可能 因为,在这种情况下,您将someScopeScopedObject.myFunction2
作为回调函数传递给 init 函数,
init: function (callback) {
callback();
}
然后调用
myFunction2: function () {
this.myFunction1();
}
这里你指的是 this.myFunction1();
--- 这不存在,因为你指的是在 myfunction2 中定义的 myfunction1,而它不存在!
当您将 myFunction2
作为参数传递给某物时,它会丢失对其所属对象的引用。 this
现在指的是函数本身,而不是 someScopeScopedObject
,因此你的问题 :)
这也是为什么一些库为方法采用对象上下文的原因,即。 jasmine 的 spyOn(someScopeScopedObject, "myFunction2")
,以保持范围的正确性。
一个变通方法示例(如 jasmine 使用的变通方法)可能如下所示:
var someScopeScopedObject = {
myFunction1: function () {
console.log('foo');
},
myFunction2: function () {
this.myFunction1();
},
init: function (context, callbackName) {
context[callbackName]();
}
}
这将允许您执行以下操作:
someScopeScopedObject.init(someScopeScopedObject, "myFunction2");
这不是最漂亮的。或者,您可以将对象绑定到函数(因此作用域保持不变)。这假设您的原始代码在 someScopeScopedObject
:
someScopeScopedObject.init(someScopeScopedObject.myFunction2.bind(someScopeScopedObject));
这些都不漂亮,而且,实际上,那是因为从外部 将属于某个对象的函数作为对该对象的回调提供是很奇怪的。
最佳解决方案可能是:
someScopeScopedObject.init(function() {
someScopeScopedObject.myFunction2();
});