【发布时间】:2021-10-14 03:13:52
【问题描述】:
我还没有找到答案。 JavaScript 中的对象有一个继承链;任何函数的链都是Function => Object,TypeError 实例的链是TypeError => Error => Object,而TypeError 的链奇怪的是Function => Function => Object。
我查看了如何使构造的对象除了直接构造函数之外还从另一个函数继承属性,期望得到的继承链是object => constructor => second function,并且这是一个构造函数扩展另一个构造函数的方式。我找到的解决方案是在构造函数的主体内调用<second function>.<call or apply>(this[, optional arguments...]),但object instanceof <second function> 最终返回false。
进一步的研究揭示了大多数使用类语法或 Object.create 的答案,但这些都是新的,并且自 JavaScript 语言创建以来,一个“类”在 JavaScript 中扩展另一个“类”就已经存在,所以还有其他一些方法可以做到这一点.这些信息应该与 JavaScript 构造函数的基本解释一起提到,但事实并非如此。扩展“类”(不是实际的类语法)导致更深的继承链的主要方法是什么?
示例结果:
// Square is the subclass
// Rectangle is the superclass
var rectangle = new Rectangle(1, 1);
var square = new Square(1);
rectangle instanceof Rectangle; // true
rectangle instanceof Square; // false
square instanceof Rectangle; // true
square instanceof Square; // true
Square instanceof Rectangle; // true
错误解决方案:
function F () {
this.value = 0;
}
function G () {
F.apply(this);
}
var f = new F();
var g = new G();
// g gets the same properties from F that f gets.
"value" in f; // true
"value" in g; // true
// But neither g nor G are instances of F.
g instanceof G; // true
g instanceof F; // false
G instanceof F; // false
【问题讨论】:
-
"我找到的解决方案" - 你能分享一下你找到了什么以及在哪里找到的吗?请注意,
Parent.call(this, ...arguments)仅等效于super()调用,而不是extends子句。 -
Object.create并不新鲜。它从 ES5 开始就存在了,比class语法长得多。 -
在
Object.create、newwas used to create the prototype object 之前,但是it's never been an exact replacement 和正确的操作方式很复杂。此外,使用复杂的类层次结构从未流行过。 -
"TypeError 实例的链是 TypeError => Error => Object" - 不完全是。我很困惑你的帖子怎么从来没有在任何地方提到
.prototype对象。属性不是从函数继承的。你了解类实例的原型链是如何工作的,new关键字与它有什么关系吗? -
@RBarryYoung 当
A是一个对象/函数并且B和C是不同的构造函数时,A instanceof B、A instanceof C和B instanceof C都可以返回true。我认为这在 ES5 之前是可能的。我说B扩展了C,因为我不知道还能怎么称呼它。那么,这是如何实现的呢?
标签: javascript prototype prototypal-inheritance extending-classes ecmascript-3