[英]Why is my alternate version of a JavaScript Definitive Guide class example not working
Its on pp 200-201 of Chapter 9 on Classes and Modules. 它在第9章“类和模块”的第200-201页上。 This approach below occured to me as being more straightforward, but the commented output lines below are not working for unknown reasons:
我认为以下这种方法更简单,但是由于未知原因,以下注释的输出行不起作用:
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
1) console.log(r.constructor.prototype.Z) //undefined
1)
console.log(r.constructor.prototype.Z) //undefined
The issue is that r.constructor === Object
rather than Range
. 问题是
r.constructor === Object
而不是Range
。 This is because the value is inherited from the prototype
object, which itself has a constructor
of Object
. 这是因为该值是从
prototype
对象继承的, prototype
对象本身具有Object
的constructor
。
You'll have to override it within the prototype for it to reference Range
as you expected: 您必须在原型中覆盖它,以使其按预期引用
Range
:
Range.prototype = {
constructor: Range,
...
}
[ Edit ] Or, rather than setting the entire prototype
to a new object, you can extend the existing object: [ 编辑 ]或者,您可以扩展现有对象,而不是将整个
prototype
设置为一个新对象:
Range.prototype.includes = function ...;
Range.prototype.foreach = function ...;
Range.prototype.toString = function ...;
Range.prototype.Z = "ZZZZZZZZZZZZZZZZZZZ";
With this, any preset keys, like constructor
, are still part of the prototype
without having to set them yourself. 这样,任何预置键(如
constructor
)仍然是prototype
一部分,而无需自己进行设置。
2) console.log(r); // Does not use Range.toString
2)
console.log(r); // Does not use Range.toString
console.log(r); // Does not use Range.toString
The console simply doesn't use toString()
. 控制台根本不使用
toString()
。 It instead lists the instance as browsable so you can see all of its properties and their values. 而是将实例列出为可浏览,以便您可以查看其所有属性及其值。
If you want it to show the result of toString()
, you have to call it yourself as you did on the line before: 如果希望它显示
toString()
的结果,则必须像在前面的代码行中那样自己调用它:
console.log(r.toString());
3) r.foreach(console.log); // TypeError
3)
r.foreach(console.log); // TypeError
r.foreach(console.log); // TypeError
log
specifically needs its context (the value of this
) to be console
, but it's being passed as a simple function reference without a context. log
特别需要它的上下文( this
的值)作为console
,但是它是作为没有上下文的简单函数引用传递的。
You'll either have to wrap it in another function so it can be called as a method or bind
it to console
: 您必须将其包装在另一个函数中,以便可以将其作为方法调用或
bind
其bind
到console
:
r.foreach(function (n) { console.log(n); });
r.foreach(console.log.bind(console));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.