避免在外部称为原型方法中丢失对象实例
Avoiding loss of object instance in externally called prototypal method
对象在下面c
用来克服对象实例丢失的技术b
对我来说有点臭。有没有更可接受的方法?
function A() {
this.prop = "cat";
}
A.prototype.test = function() {
console.log(this.prop);
}
function B() {}
B.prototype.test = function(meth) {
meth();
}
function C() {}
C.prototype.test = function(obj, meth) {
obj[meth]();
}
var a = new A();
var b = new B();
var c = new C();
//tests
b.test(a.test); // undefined
c.test(a, 'test'); // cat
复制自: https://stackoverflow.com/a/16063711/1641941
这个变量
在所有示例代码中,你将看到this
引用当前实例。
this 变量实际上指的是调用对象,它指的是函数之前的对象。
要澄清,请参阅以下代码:
theInvokingObject.thefunction();
这引用错误对象的实例通常是在附加事件侦听器、回调或超时和间隔时。在接下来的 2 行代码中,我们pass
函数,我们不会调用它。传递函数是:someObject.aFunction
,调用它是:someObject.aFunction()
。this
值不是指声明函数的对象,而是指向invokes
函数的对象。
setTimeout(someObject.aFuncton,100);//this in aFunction is window
somebutton.onclick = someObject.aFunction;//this in aFunction is somebutton
要在上述情况下进行this
,请参阅someObject,您可以传递闭包而不是直接传递函数:
setTimeout(function(){someObject.aFuncton();},100);
somebutton.onclick = function(){someObject.aFunction();};
我喜欢定义函数,这些函数在原型上返回闭包函数,以便对闭包范围中包含的变量进行精细控制。
var Hamster = function(name){
var largeVariable = new Array(100000).join("Hello World");
// if I do
// setInterval(function(){this.checkSleep();},100);
// then largeVariable will be in the closure scope as well
this.name=name
setInterval(this.closures.checkSleep(this),1000);
};
Hamster.prototype.closures={
checkSleep:function(hamsterInstance){
return function(){
console.log(typeof largeVariable);//undefined
console.log(hamsterInstance);//instance of Hamster named Betty
hamsterInstance.checkSleep();
};
}
};
Hamster.prototype.checkSleep=function(){
//do stuff assuming this is the Hamster instance
};
var betty = new Hamster("Betty");
不需要传递字符串,您仍然可以传递函数:
C.prototype.test = function(obj, meth) {
meth.call(obj);
}
// ...
c.test(a, a.test); // cat
Function#call
调用一个函数,明确地将调用中的this
设置为您call
给出的第一个参数。(还有Function#apply
;唯一的区别是你如何为函数传递额外的参数。
但通常(并非总是)这被认为是调用者的问题,他们通常会使用 Function#bind
(在支持 ES5 的引擎上或使用填充程序)来解决它:
c.test(a.test.bind(a));
。或使用闭合:
c.test(function() {
a.test();
});
。在这两种情况下,您只需在C.prototype.test
内调用meth()
。
Function#bind
创建一个新函数,该函数在调用时将调用原始函数,并将this
设置为您传递给bind
的值,然后返回该新函数。
我博客上的相关文章:
- 神话般的方法
- 你必须记住
this
- 闭合并不复杂
- 代码挑战:创建一个跟踪对象实例总数的类Foo
- 为什么属性存在于对象实例上,即使其原型发生了更改
- 如何在angularJS中获得对指令对象实例的引用
- 是否有将基于字符串的JSON转换为Mongoose Schema对象实例的本地功能
- 从对象实例中获取变量名称
- 了解 JavaScript 对象实例或工作流
- Javascript:在对象实例方法上使用apply()方法失败
- 多个对象实例发生干扰
- 确定javascript对象实例的类型
- 如何在Javascript中创建多个对象实例
- 在每个循环中创建对象实例
- javascript多个对象实例的时间戳相同
- 使用lodash'扩展JS对象实例;s的extend方法会导致奇怪的结果
- 避免在外部称为原型方法中丢失对象实例
- 不定义类的对象实例
- 对象实例中的方法不执行
- 像PHP一样使用json数组“水合”Javascript对象实例
- Javascript:父/子对象实例化的顺序
- 在 Angular.js 中跨应用程序使用相同的对象实例
- 对象引用未设置为 C# 中的对象实例