[英]Newly added function to the prototype of the constructor doesn't work when it's called on objects
[英]Method on constructor’s prototype throws TypeError when called
我創建了一個 function 構造函數,它返回一個具有給定參數的新數組。 我正在嘗試使用prototype
屬性添加自定義方法sumUp
。 function 構造函數按預期返回數組。 但是當我調用該方法時,它會拋出錯誤:
類型錯誤:
newArr.sumUp
不是 function
function SurajArray(...array) { let arr = []; for (let i = 0; i < array.length; i++) { arr.push(array[i]); } return arr; } SurajArray.prototype.sumUp = function() { let ans = this.reduce((result, value) => { result = result + value; return result; }, 0); return ans; } let newArr = new SurajArray(1, 2, 3, 4, 5); console.log(newArr); // gives correct array console.log(typeof sumUp); // gives undefined let sum = newArr.sumUp(); // This gives an error console.log(sum);
您的SurajArray
function 只返回一個普通數組,它不會使用SurajArray.prototype
作為其原型,因此不會有sumUp
function ,因此調用它的結果(無論是通過new
還是其他方式)不會有sumUp
。 (也沒有全局sumUp
function,所以查找的代碼找不到。)
要正確子類化數組,請使用class
語法並extends
:¹
class SurajArray extends Array { sumUp() { let ans = this.reduce((result, value) => { result = result + value; return result; }, 0); return ans; } } const newArr = new SurajArray(1, 2, 3, 4, 5); const sum = newArr.sumUp(); console.log(sum);
或者更簡單地說:
class SurajArray extends Array { sumUp() { let sum = 0; for (const value of this) { sum += value; } return sum; } } const newArr = new SurajArray(1, 2, 3, 4, 5); const sum = newArr.sumUp(); console.log(sum);
¹ It's also possible, in ES2015 and later, to subclass Array
with function
syntax and Reflect.construct
, but it's simpler with class
and if you're going to use new
anyway, it makes sense to go with simple. (在 ES2015 之前,您不能正確地繼承Array
。)為了完整起見,這就是它的樣子:
// The constructor function SurajArray(...args) { return Reflect.construct(Array, args, SurajArray); } // A correctly-set up `SurajArray.prototype` object SurajArray.prototype = Object.create(Array.prototype); SurajArray.prototype.constructor = SurajArray; // A method -- by default, instance methods should be non-enumerable // as this one is (because the default for the `enumerable` flag is // false) Object.defineProperty(SurajArray.prototype, "sumUp", { value() { let sum = 0; for (const value of this) { sum += value; } return sum; }, configurable: true, writable: true, }); // Usage example const newArr = new SurajArray(1, 2, 3, 4, 5); const sum = newArr.sumUp(); console.log(sum);
(請注意,它定義的其他方法無法正確使用super
。)
構造函數不需要返回值。 構造函數 function 的原型可用於操作實例值( this...
)。 因此,您的函數的最簡單和原型翻譯將是:
// the constructor function SurajArray(...array) { // assign array to the instance (this) this.arr = array; // if sumUp does not exist in the prototype, create it SurajArray.prototype.sumUp = SurajArray.prototype.sumUp || function() { return this.arr.reduce( (acc, val) => acc + val, 0); // ^ the instance value }; // Note: this is mostly done outside the constructor function, // but this also works } // create 2 instances const sa1 = new SurajArray(21, 23, 45); const sa2 = new SurajArray(300, 17, 98); console.log(sa1.sumUp()); console.log(sa2.sumUp());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.