[英]Trying to understand `this` in javascript
I have an object with a number of functions: 我有一个具有许多功能的物体:
var someScopeScopedObject = {
myFunction1: function () {
console.log('foo');
},
myFunction2: function () {
this.myFunction1();
}
init: function (callback) {
callback();
}
}
So if I call someScopeScopedObject.myFunction2
that works fine 因此,如果我调用
someScopeScopedObject.myFunction2
可以正常工作
But If I do someScopeScopedObject.init(someScopeScopedObject.myFunction2)
then I get an error that this.myFunction1 is undefined
但是,如果我执行
someScopeScopedObject.init(someScopeScopedObject.myFunction2)
则会收到错误this.myFunction1 is undefined
Why is this
not valid when I call into the function that way? 当我以这种方式调用函数时,为什么
this
无效?
The keyword this
refer's to the functions scope. this
是功能范围的关键字。 Not the global scope. 不是全球范围。 You declare a function called
myFunction2
, the this
refers to the scope of this function and not the scope in which this function is declared. 您声明调用的函数
myFunction2
,在this
指的是这个功能的范围,而不是在这个函数声明的范围。
It isn't like in languages, like C#, where this
refers to the current instance of the class, whether you are in one another method. 它不喜欢的语言,如C#,其中
this
指的是类的当前实例,无论你是在一个另一种方法。
this
refers to the function in which it is declared, So in your example, this
是指在其中声明的函数,因此在您的示例中,
var someScopeScopedObject = {
myFunction1: function () {
console.log('foo');
},
myFunction2: function () {
this.myFunction1();
}
init: function (callback) {
callback();
}
}
myFunction1 is not declared inside myFunction2, so myFunction1没有在myFunction2内部声明,因此
` myFunction2: function () {
this.myFunction1();
}.
is not possible, because this.myFunction1();
这是不可能的,因为
this.myFunction1();
tries to call method myfunction1 which should be declared inside myfunction1
which is not declared there. 尝试调用方法myfunction1,该方法应在未在其中声明的
myfunction1
内部声明。
Edit:
编辑:
someScopeScopedObject.myFunction2();
is possible because you are calling the method myFunction1 which is defined inside someScopeScopedObject
之所以可行是因为您正在调用在
someScopeScopedObject
内部定义的方法myFunction1
someScopeScopedObject.init(someScopeScopedObject.myFunction2);
is not possible because, you pass someScopeScopedObject.myFunction2
as a callback function in this case here to the init function, 这是不可能的,因为在这种情况下,您将
someScopeScopedObject.myFunction2
作为回调函数传递给了init函数,
init: function (callback) { callback(); }
It then calls 然后调用
myFunction2: function () { this.myFunction1(); }
here you refer this.myFunction1();
在这里您引用
this.myFunction1();
--- This doen not exist, since you are refering to myfunction1 defined inside myfunction2, which is not! ---这个不存在,因为您引用的是在myfunction2内定义的myfunction1,这不是!
When you pass myFunction2
as an argument to something, it loses the reference to the object it belongs to. 当将
myFunction2
作为参数传递给某物时,它将丢失对它所属对象的引用。 this
now refers to the function itself, and not someScopeScopedObject
, hence your problem :) 现在
this
是指函数本身,而不是someScopeScopedObject
,因此是您的问题:)
This is also why some libraries take an object context for methods, ie. 这也是为什么某些库采用对象上下文作为方法的原因。 jasmine's
spyOn(someScopeScopedObject, "myFunction2")
, to keep the scoping correct. 茉莉花的
spyOn(someScopeScopedObject, "myFunction2")
,以保持作用域正确。
An example work-around (like the one used by jasmine) could look like this: 一个变通方法示例(例如茉莉花使用的变通方法)可能如下所示:
var someScopeScopedObject = {
myFunction1: function () {
console.log('foo');
},
myFunction2: function () {
this.myFunction1();
},
init: function (context, callbackName) {
context[callbackName]();
}
}
This would allow you to do the following: 这将允许您执行以下操作:
someScopeScopedObject.init(someScopeScopedObject, "myFunction2");
This is not the prettiest. 这不是最漂亮的。 Alternatively, you can bind the object to the function (so the scope stays the same).
或者,您可以将对象绑定到函数(因此作用域保持不变)。 This assumes your original code in
someScopeScopedObject
: 这假定您的原始代码在
someScopeScopedObject
:
someScopeScopedObject.init(someScopeScopedObject.myFunction2.bind(someScopeScopedObject));
Neither of these are pretty, and, really, that's because it is weird to externally feed a function belonging to an object as a callback to that object. 这些都不是很漂亮,实际上,这是因为从外部提供属于对象的函数作为对该对象的回调很奇怪。
The best solution might be: 最好的解决方案可能是:
someScopeScopedObject.init(function() {
someScopeScopedObject.myFunction2();
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.