我有一个类中的下列功能:
MyClass.prototype.myFunction = function(item, args)
{
console.log(this);
}
这个功能是从我没有权限更改外部库调用。 当它被称为,控制台登录“本”作为窗口对象,而不是实际的实例化对象。 在搜索计算器,我发现这句话:
这是根据该方法如何根据该方法是怎么写的叫,而不是设置。 所以对于obj.method(),这将被设置为方法的内部OBJ()。 对于obj.method.call(x)时,该方法的()内将被设置为x。 它是由它怎么叫确定。 什么也意味着是,如果你把它作为一个回调的onclick例如,这将被设置为全局窗口对象,而不是你所期望的。
我假设这是怎么回事,我不能改变它的调用方式。 我的问题是,反正是有那么得到的对象实例及其不管它怎么叫?
这与JavaScript的共同困惑。 人们很容易把它们当作表现得像扩展方法使用其他语言,但在Javascript中它是那么容易改变的背景下this
,它往往是由意外完成。
所以:
MyClass.prototype.myFunction = function(args)
{
// You expect [this] to refer to an instance of MyClass
this.somePropertyOfMyClass;
};
然后,你可以调用这个:
var x = new MyClass();
x.myFunction(args)
然而,一个函数被调用JavaScript的方式可以改变什么this
是指:
var y = somethingElse();
x.myFunction.call(y, args); // now in myFunction [this] refers to y
更有可能的是,很多图书馆都使用this
上下文链接和事件-犯错容易。 例如jQuery中:
var $thing = $('.selector');
$thing.click(x.myFunction); // now in myFunction [this] refers to $thing
这可能是不明显写了jQuery,调用者x.myFunction
这样会打破它。 他们可以变通方法(假设他们了解的实现)有:
$thing.click(function() { x.myFunction(); });
如果你希望你的MyClass
是有弹性的,以被称为像这样的话就不要用prototype
-而不是使用对象的属性:
function MyClass() {
var self = this;
// ...
this.myFunction = function(args)
{
// [self] will always refer to the current instance of MyClass
self.somePropertyOfMyClass;
};
}
需要注意的是更现代的浏览器的Javascript引擎是为优化这些类型的呼叫不错,所以我不会用的prototype
一样,除非你已经确定你需要额外的性能优化。
大概一个函数引用传递到其他函数来调用,而另一个功能是一样的东西:
function otherFunction(args, fn) {
...
fn();
...
}
为了确保该方法获取this
需要,你可以这样做:
// Create a local variable referencing the `this` you want
var instance = this;
// Pass a function that has a closure to the variable
// and sets the appropriate this in the call
otherFunction(args, function(){myMethod.call(instance)})
现在, this
在myMethod
将是什么instance
的引用。 请注意,如果你改变的值instance
调用后otherFunction
,被称为方法之前, myMethod
将获得新的价值。
你可以处理,太多,如果这是一个问题。
哦,你也可以通过给每个实例它自己的方法,有一个封闭的情况下处理这个构造函数:
function MyObj(name) {
var instance = this;
instance.name = name;
instance.getName = function() {
return instance.name;
}
}
var anObj = new MyObj('fred');
// Call as a method of anObj
alert(anObj.getName()); // fred
// Pass method as a reference
var x = anObj.getName;
// Unqualified call
alert(x()); // fred
规则是:
当this
是从一个函数调用,它指的是全球客体(通常Window
)。
当this
是由方法来调用,它指的是所有者对象(即当前对象在其中所使用的方法)。
例:
function Tryme() {
var that = this
function func2() {
console.log("'this' from 'func2':", this)
}
function func3() {
console.log("'that' from 'func3':", that)
}
this.method1 = function () {
console.log("'this' from 'method1':", this)
}
this.method2 = function () {
func2()
}
this.method3 = function () {
func3()
}
}
myinstance = new Tryme()
myinstance.method1() // displays the object 'myinstance'
myinstance.method2() // displays the object 'Window'
myinstance.method3() // displays the object 'myinstance'
在本例中,会发生什么?
当你调用.method1()
和你显示this
,你是目前在对象的方法myinstance
。 因此, this
将参照对象本身(即myinstance
)。
当你调用.method2()
这个方法会调用该对象中的局部功能myinstance
称为func2()
该函数func2()
是一个函数,而不是一个方法,所以this
是指全局对象Window
。
当你调用.method3()
这个方法会调用该对象中的局部功能myinstance
称为func3()
该函数func3()
是一个函数,而不是一个方法,所以this
是指全局对象Window
(如在func2()
但在func3()
我们正在显示的内容that
,这是内的局部变量myinstance
对象。 that
是已经初始化的值的对象this
当this
指的是所有者对象(即myinstance
)。 在JavaScript中,如果初始化object2
与价值object1
( object2 = object1
),那么当你改变一个对象的值,其他对象的值也可能发生变化。 所以that
总是引用的值this
是的一个myinstance
,即使当值this
变化。 请记住 : this
是指对象关联的关键字,它不是一个变量。
什么你的情况发生?
你叫this
从一个函数,所以this
指的是全局对象( Window
)。
@Keith建议可以做些什么,即。 创建一个对象,其中您将创建一个self
(或者that
)对象,等于this
你感兴趣的,然后使用该实例的self
对象的功能(这将引用this
对象,你有兴趣) 。
更多信息
这里: https://www.w3schools.com/js/js_this.asp
这里: https://crockford.com/javascript/private.html
一个解决将是有副本myFunction()
为每个实例,即在构造函数而不是它的原型创建它,因为这样你可以有一个参考this
存储在构造函数中的局部变量:
function MyClass() {
var self = this;
this.myFunction = function(item, args) {
// use self instead of this
console.log(self);
};
// other constructor code here
}
但当然,创造了每一个实例功能使用更多的内存 - 取决于你的函数的大小可能会或可能不会是一个问题。 一种折衷的可能是把一个包装为你的函数在构造函数中,并定义对样机的实际功能:
function MyClass() {
var self = this;
this.myFunction = function(item, args) {
return self.wrappedMyFunction(item, args);
};
// your other constructor code here
}
MyClass.prototype.wrappedMyFunction = function(item, args)
{
console.log(this);
}
文章来源: The 'this' keyword returns the window object within an object's prototype in Javascript?