'this'关键字在Javascript中返回对象原型中的窗口对象?

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,这将被设置为全局窗口对象而不是你期望的.

我假设这是正在发生的事情,我无法改变它的调用方式.我的问题是,无论如何,无论如何调用对象的实例,它是否存在?

Kei*_*ith 6

这是与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作为优化。


Rob*_*obG 4

据推测,函数引用被传递给其他函数来调用,而另一个函数类似于:

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)

现在thismyMethod有任何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)