0

下面的对象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
4

2 回答 2

1

复制自:https ://stackoverflow.com/a/16063711/1641941

这个变量

在所有示例代码中,您将看到this引用当前实例。

this 变量实际上是指调用对象,它指的是函数之前的对象。

要澄清,请参阅以下代码:

theInvokingObject.thefunction();

this 引用错误对象的实例通常是在附加事件侦听器、回调或超时和间隔时。在接下来的两行代码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");
于 2013-11-10T17:32:57.917 回答
1

无需传递字符串,您仍然可以传递函数:

C.prototype.test = function(obj, meth) {
    meth.call(obj);
}

// ...

c.test(a, a.test);  // cat

Function#call调用在调用中显式设置的函数this作为您给出的第一个参数call。(还有Function#apply; 唯一的区别是你如何为函数传递额外的参数。)

但通常(并非总是)这被认为是调用者的问题,他们通常会使用Function#bind(在启用 ES5 的引擎上或使用 shim)来解决它:

c.test(a.test.bind(a));

...或使用闭包:

c.test(function() {
    a.test();
});

...在这两种情况下,您只需调用meth()within C.prototype.test

Function#bind创建一个新函数,在调用该函数时,将调用原始函数并将其this设置为您传入的值bind,然后返回该新函数。

我博客上的相关帖子:

于 2013-11-10T12:47:11.010 回答