确保原型方法中的“this”上下文

时间:2016-01-21 17:45:41

标签: javascript

对于prototype方法,是否有一种安全的方法可以确保this始终是对象本身(在检查instanceof之外并抛出错误)。

var Dialog = function() {};
Dialog.prototype.open = function() {
  var open = this;
  // how do ensure "this" is always the Dialog
  console.log(open);
};

使用此代码,任何用户都可能错误地“胁迫”上下文不正确。例如:

var pointer = new Dialog().open;
pointer(); // "this" would become Window

我正试图找到一种方法来处理这个内部,这样我就不必抛出错误或依赖用户总是做正确的事情。

用户总是可以调用pointer.call(dialog)但这意味着他们需要一个单独的指针用于对话框,这是用户负担的一个很好的例子,而不是我,作者。

2 个答案:

答案 0 :(得分:1)

使用原型继承获得的性能提升真的很麻烦,但你可以显式绑定构造函数中的每个函数。

function log(obj) {
  document.querySelector('pre').innerText += obj.toString() + '\n';
}

function Dialog() {
  this.open = this.open.bind(this);
}
Dialog.prototype.open = function() {
  log(this);
};
Dialog.prototype.toString = function() {
  return '[object Dialog]';
};

var d = new Dialog();
d.open();
var open = d.open;
open();
<pre></pre>

这将为Dialog的每个实例的每个方法创建唯一的函数对象,但从技术上讲,它可以按预期工作。

答案 1 :(得分:1)

使用原型设计无法真正阻止这种情况。 Mike C的bind建议确实做了这件事,但它基本上是一种非常精细/昂贵的方式来使用装饰模式,这确实解决了范围问题:

function Dialog() {
    var dialog = this;

    dialog.open = function() {
        console.log(dialog, this);
    };
}

var d = new Dialog();
d.open();

var open = d.open();
open();

请记住,这种方法比你问题中的prototype示例的内存效率低得多,所以如果你有很多实例,请不要使用它。