';这';关键字返回对象内的窗口对象';什么是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'