dal*_*lin 16 javascript prototype this prototypejs function-prototypes
我在类中有以下功能:
MyClass.prototype.myFunction = function(item, args)
{
console.log(this);
}
Run Code Online (Sandbox Code Playgroud)
从我无权更改的外部库调用此函数.当它被调用时,控制台将"this"记录为窗口对象而不是实际的实例化对象.在搜索stackoverflow时,我发现了这个引用:
这是根据方法的调用方式设置的,而不是根据方法的编写方式设置的.所以对于obj.method(),这将在method()中设置为obj.对于obj.method.call(x),method()内部将设置为x.它取决于它的调用方式.这也意味着如果你将它作为回调传递给例如onclick,这将被设置为全局窗口对象而不是你期望的.
我假设这是正在发生的事情,我无法改变它的调用方式.我的问题是,无论如何,无论如何调用对象的实例,它是否存在?
这是与Javascript的常见混淆。可以很容易地认为它们就像其他语言中的扩展方法一样,但是在Javascript中,更改上下文非常容易,this通常是偶然地完成的。
所以:
MyClass.prototype.myFunction = function(args)
{
// You expect [this] to refer to an instance of MyClass
this.somePropertyOfMyClass;
};
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用以下命令进行调用:
var x = new MyClass();
x.myFunction(args)
Run Code Online (Sandbox Code Playgroud)
但是,在Javascript中调用函数的方式可以更改this引用的内容:
var y = somethingElse();
x.myFunction.call(y, args); // now in myFunction [this] refers to y
Run Code Online (Sandbox Code Playgroud)
更有可能的是,许多库将this上下文用于链接和事件-使错误易于产生。例如在jQuery中:
var $thing = $('.selector');
$thing.click(x.myFunction); // now in myFunction [this] refers to $thing
Run Code Online (Sandbox Code Playgroud)
对于编写jQuery的人来说,x.myFunction以这种方式调用会破坏它可能并不明显。他们可以通过以下方法解决此问题(假设他们了解实施情况):
$thing.click(function() { x.myFunction(); });
Run Code Online (Sandbox Code Playgroud)
如果您希望MyClass对这样的调用具有弹性,请不要使用prototype-而是使用对象的属性:
function MyClass() {
var self = this;
// ...
this.myFunction = function(args)
{
// [self] will always refer to the current instance of MyClass
self.somePropertyOfMyClass;
};
}
Run Code Online (Sandbox Code Playgroud)
请注意,更现代的浏览器Javascript引擎在优化此类调用方面非常出色,因此prototype除非您已经确定需要其他性能,否则我不会将Just作为优化。
据推测,函数引用被传递给其他函数来调用,而另一个函数类似于:
function otherFunction(args, fn) {
...
fn();
...
}
Run Code Online (Sandbox Code Playgroud)
为了确保该方法得到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)})
Run Code Online (Sandbox Code Playgroud)
现在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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5291 次 |
| 最近记录: |