1

它在第 9 章关于类和模块的第 200-201 页。在我看来,下面的这种方法更简单,但下面的注释输出行由于未知原因不起作用:

Range.prototype = {
  includes: function(x) {
    return this.from <= x && x <= this.to;
  },

  foreach: function(f) {
    for (var x = Math.ceil(this.from); x <= this.to; x++) f(x);
  },

  toString: function() {
    return "(" + this.from + "..." + this.to + ")";
  },

  Z: "ZZZZZZZZZZZZZZZZZZZ",    
}

function Range(from,to) {
  this.from = from
  this.to = to
}

var r = new Range(1,3)

console.log(Range.prototype.Z)
console.log(r.constructor.prototype.Z)  //undefined 
console.log(r.Z)
console.log(r.includes(2));
console.log(r.toString());
console.log(r);  // Does not use Range.toString 
r.foreach(console.log); // TypeError 
4

1 回答 1

1

1)console.log(r.constructor.prototype.Z) //undefined

问题在于,r.constructor === Object而不是Range. 这是因为该值是从对象继承而来的prototype,该对象本身具有constructorof Object

您必须在原型中覆盖它才能Range按预期引用它:

Range.prototype = {
  constructor: Range,
  ...
}

[编辑]或者,您可以扩展现有对象,而不是将整个设置prototype为新对象:

Range.prototype.includes = function ...;
Range.prototype.foreach = function ...;
Range.prototype.toString = function ...;
Range.prototype.Z = "ZZZZZZZZZZZZZZZZZZZ";

有了这个,任何预设键,如constructor,仍然是 的一部分,prototype而无需自己设置。


2)console.log(r); // Does not use Range.toString

控制台根本不使用toString(). 相反,它将实例列为可浏览的,因此您可以查看其所有属性及其值。

如果您希望它显示 的结果toString(),则必须像之前在行中所做的那样自己调用它:

console.log(r.toString());

3)r.foreach(console.log); // TypeError

log特别需要它的上下文(的值this)为console,但它被作为没有上下文的简单函数引用传递。

您要么必须将其包装在另一个函数中,以便可以将其作为方法调用,要么bind将其用于console

r.foreach(function (n) { console.log(n); });
r.foreach(console.log.bind(console));
于 2012-07-10T20:01:12.680 回答