';这';关键字返回对象内的窗口对象';什么是Javascript中的原型?

';这';关键字返回对象内的窗口对象';什么是Javascript中的原型?,javascript,prototypejs,this,prototype,function-prototypes,Javascript,Prototypejs,This,Prototype,Function Prototypes,我在类中具有以下函数: MyClass.prototype.myFunction = function(item, args) { console.log(this); } 此函数是从我无权更改的外部库调用的。调用时,控制台将“this”记录为窗口对象,而不是实际的实例化对象。在搜索stackoverflow时,我发现以下报价: 这是根据调用方法的方式设置的,而不是根据编写方法的方式设置的。因此,对于obj.method(),它将在method()内部设置为obj。对于

我在类中具有以下函数:

MyClass.prototype.myFunction = function(item, args) 
{       
    console.log(this);
}
此函数是从我无权更改的外部库调用的。调用时,控制台将“this”记录为窗口对象,而不是实际的实例化对象。在搜索stackoverflow时,我发现以下报价:

这是根据调用方法的方式设置的,而不是根据编写方法的方式设置的。因此,对于obj.method(),它将在method()内部设置为obj。对于obj.method.call(x),该方法()的内部将设置为x。这取决于它的名称。这也意味着,如果您将其作为回调传递给例如onclick,它将被设置为全局窗口对象,而不是您期望的对象


我假设这就是正在发生的事情,我不能改变它的命名方式。我的问题是,不管调用方式如何,是否仍然可以将对象的实例放入其中?

可能会将函数引用传递给要调用的其他函数,而另一个函数类似于:

function otherFunction(args, fn) {
    ...
    fn();
    ...
}
要确保方法获得它所需的
,可以执行以下操作:

// 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)})
现在
这个
myMethod
中将是任何
实例
引用。请注意,如果在调用
otherFunction
之后和调用方法之前更改
instance
的值,
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    

一种修复方法是为每个实例创建一个
myFunction()
副本,即在构造函数中创建它,而不是在原型中创建它,因为这样您就可以在构造函数中将对该
的引用存储为局部变量:

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);
}

这是Javascript的常见混淆。很容易认为它们的行为类似于其他语言中的扩展方法,但在Javascript中,很容易更改
this
的上下文,这常常是偶然的

因此:

然后,您可以使用以下命令调用此命令:

var x = new MyClass();
x.myFunction(args)
但是,在Javascript中调用函数的方式可以更改此
所指的内容:

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
会破坏jQuery可能并不明显。他们可以通过以下方式解决这一问题(假设他们知道实施情况):

如果希望您的
MyClass
能够适应这样的调用,那么不要使用
prototype
——而是使用对象的属性:

function MyClass() {
    var self = this;
    // ...
    this.myFunction = function(args) 
    {
        // [self] will always refer to the current instance of MyClass
        self.somePropertyOfMyClass;
    };
}
请注意,更现代的浏览器Javascript引擎在优化此类调用方面非常出色,因此我不会将
原型作为优化使用,除非您已经确定需要额外的性能。

规则是:

当从函数调用
时,它指的是全局对象(通常为
窗口
)。
当从方法调用此
时,它指的是所有者对象(即使用该方法的当前对象)。

例如:

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
的方法中。因此
这个
将引用对象本身(即
myinstance

调用
.method2()
时,此方法将调用名为
func2()
的对象
myinstance
中的本地函数。此函数
func2()
是一个函数而不是一个方法,因此
引用全局对象
窗口

调用
.method3()
时,此方法将调用名为
func3()
的对象
myinstance
中的本地函数。此函数
func3()
是一个函数而不是一个方法,因此
This
引用全局对象
窗口(如
func2()
)。但是在
func3()
中,我们显示了
that
的内容,它是
myinstance
对象中的一个局部变量<当
this
引用所有者对象(即
myinstance
)时,该
是一个已使用
this
值初始化的对象。在JavaScript中,如果您使用
object1
object2=object1
)的值初始化
object2
),那么当您更改一个对象的值时,另一个对象的值也会更改。因此,即使
this
的值发生变化,
this
的值也将始终引用
myinstance
的值记住
这个
是一个引用对象的关键字,它不是变量

你的情况如何?

您从函数调用了
this
,因此
this
引用全局对象(
窗口

@Keith建议了可以做的事情,即创建一个对象,其中您将创建一个与您感兴趣的实例的
this
相等的
self
(或
)对象,然后在函数中使用
self
对象(它将引用您感兴趣的
this
对象)
function MyClass() {
    var self = this;
    // ...
    this.myFunction = function(args) 
    {
        // [self] will always refer to the current instance of MyClass
        self.somePropertyOfMyClass;
    };
}
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'