首先,JavaScript 中的对象继承自其他对象,而不是构造函数。因此,“但令人惊奇的是它不是 Array 对象的实例”这句话是错误的。
假设您有一个对象rectangle
,如下所示:
var rectangle = {
height: 5,
width: 10
};
rectangle.area = function () {
return this.width * this.height;
};
现在我可以通过调用方法来计算这个矩形的面积rectangle.area
。但是说我想用不同的width
和创建一个新的矩形height
。这就是我要做的:
var rectangle2 = Object.create(rectangle);
rectangle2.height = 8;
rectangle2.width = 20;
alert(rectangle2.area());
这里的 objectrectangle2
继承自 object rectangle
。所以你看到对象实际上继承自其他对象,而不是构造函数。阅读以下主题以获取更多详细信息:
关于原型函数的问题
当您在函数调用之前使用new
关键字 JavaScript 会创建一个继承自函数的新对象prototype
。因此,实例实际上继承自prototype
.
如果对象位于 object 的原型链中,则对象仅从对象a
继承。b
b
a
这就是我们有isPrototypeOf
方法的原因。
接下来要记住的是,instanceof
操作员实际上并没有任何意义。它可以在 JavaScript 中实现如下:
function instanceOf(obj, func) {
return Object.prototype.isPrototypeOf.call(func.prototype, obj);
}
因此,您可以清楚地看到,只有从该函数的 继承的对象才有资格作为函数的“实例”prototype
。
Array.prototype instanceof Array
这就是返回的原因false
——对象不能从自身继承。
有关instanceof
操作员如何工作的更多信息,请阅读以下线程:
JavaScript 继承和构造函数属性
最后,length
数组的属性总是比数组的最大数字索引大一。例如:
var a = [];
alert(a.length); // 0
a[99999] = null;
alert(a.length); // 100000
Array.prototype.length
这就是原因0
-Array.prototype
没有数字键。但是,如果您为其分配一个数字键,则该length
属性将相应更改:
Array.prototype[99999] = null;
alert(Array.prototype.length); // 100000
这同样适用于x
- 属性"a"
并且"b"
不是数字。因此它们不会影响length
数组的。
顺便说一句,如果您对原型继承感兴趣,那么您应该阅读我关于原型继承为何重要的博文。