ser*_*0ne 4 javascript arrays inheritance prototype
我想子类化一个 javascript 数组并将构造函数参数传递给数组。我所拥有的是:
function SubArray(arguments) {
Array.apply(this, arguments);
}
SubArray.prototype = Array.prototype;
Run Code Online (Sandbox Code Playgroud)
测试不表明参数被传递给数组
var x = new SubArray("One", "Two", "Three");
// Object[]
// x.length = 0
Run Code Online (Sandbox Code Playgroud)
而当我用一个数组来做这件事时,我得到了这个
var x = new Array("One", "Two", "Three");
// Object["One", "Two", "Three"]
// x.length = 3
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
在 ES6 中,您可以使用语法扩展Arrayclass
class SubArray extends Array {
constructor() {
super(...arguments);
}
first() {
return this[0];
}
}
Run Code Online (Sandbox Code Playgroud)
长度将按预期工作
var sa = new SubArray('foo', 'bar');
sa[2] = 'baz';
sa.length; // 3
sa.first(); // "foo"
sa instanceof SubArray; // true
Run Code Online (Sandbox Code Playgroud)
直到并包括 ES5,都无法Array在不丢失功能的情况下以通常的构造函数原型方式干净利落地扩展,而是必须向 Array 实例添加属性
function SubArray() {
var arr = Array.apply(null, arguments);
arr.first = function () {return this[0];};
return arr;
}
Run Code Online (Sandbox Code Playgroud)
使用 this 不再需要从函数返回new一个Object,并且instanceof将无法确定SubArray。
var sa = SubArray('foo', 'bar');
sa[2] = 'baz';
sa.length; // 3
sa.first(); // "foo"
sa instanceof SubArray; // false -- this gets broken
Run Code Online (Sandbox Code Playgroud)
在行为比速度更重要的 ES5 环境中,您可以根据需要使用Object.setPrototypeOf (参见 MDN 警告)强制原型链,这是“有点黑客”,看起来像
function SubArray() {
var arr = Array.apply(null, arguments);
Object.setPrototypeOf(arr, SubArray.prototype);
return arr;
}
SubArray.prototype = Object.create(Array.prototype);
SubArray.prototype.first = function () {return this[0];};
Run Code Online (Sandbox Code Playgroud)
同样,new不再需要,但这次实例的行为与正常扩展时的预期完全相同。
var sa = SubArray('foo', 'bar');
sa[2] = 'baz';
sa.length; // 3
sa.first(); // "foo"
sa instanceof SubArray; // true
Run Code Online (Sandbox Code Playgroud)