给数组 a 扩展一个方法,使其具备 multiply 方法,详见案例
const a = [1, 2, 3, 4, 5];
a.multiply();
console.log(a); // [1, 2, 3, 4, 5, 1, 4, 9, 16, 25]
1.直接在原型上扩充
const a = [1, 2, 3, 4, 5];
Array.prototype.multiply = function() {
this.splice(this.length, 0, ...this.map(item => item * item));
}
a.multiply();
console.log(a); // [1, 2, 3, 4, 5, 1, 4, 9, 16, 25]
因为 a. proto === Array.prototype 故也可以采用以下写法
const a = [1, 2, 3, 4, 5];
a.__proto__.multiply = function() {
this.splice(this.length, 0, ...this.map(item => item * item));
}
a.multiply();
console.log(a); // [1, 2, 3, 4, 5, 1, 4, 9, 16, 25]
上述解法优点是实现起来较简单,缺点是整个数组都具备了这个方法,如果出题人的本意只是对 a 扩充该方法的话,上述解法就带有侵入性了
2.只对 a 扩充
采用 Object.defineProperty 对 a 扩充一个不可枚举属性
const a = [1, 2, 3, 4, 5];
Object.defineProperty(a, 'multiply', {
value: function() {
this.splice(this.length, 0, ...this.map(item => item * item));
},
enumerable: false,
})
a.multiply();
console.log(a); // [1, 2, 3, 4, 5, 1, 4, 9, 16, 25]
还可以改写 a 的原型对象
// 创建一个对象,让 Array.prototype 作为原型对象
const arrProto = Object.create(Array.prototype);
// multiply 作为 arrProto 的一个方法而不是 Array.prototype 的方法
arrProto.multiply = function() {
this.splice(this.length, 0, ...this.map(item => item * item))
}
const a = [1, 2, 3, 4, 5];
// a 的原型改为 arrProto,而不是 Array.prototype
a.__proto__ = arrProto;
a.multiply()
console.log(a); // [1, 2, 3, 4, 5, 1, 4, 9, 16, 25]
console.log(a.__proto__ === Array.prototype); // false
console.log(a.__proto__ instanceof Array); // true
如果觉得上述写法太啰嗦,也可以尝试 Object.create 第二个参数
const arrProto = Object.create(Array.prototype, {
multiply: {
value: function() {
this.splice(this.length, 0, ...this.map(item => item * item))
},
enumerable: false,
}
});
const a = [1, 2, 3, 4, 5];
// a 的原型改为 arrProto,而不是 Array.prototype
a.__proto__ = arrProto;
a.multiply()
console.log(a); // [1, 2, 3, 4, 5, 1, 4, 9, 16, 25]
console.log(a.__proto__ === Array.prototype); // false
console.log(a.__proto__ instanceof Array); // true