简体   繁体   English

构造函数原型上的方法在调用时抛出 TypeError

[英]Method on constructor’s prototype throws TypeError when called

I have created a function constructor which returns a new array with given parameters.我创建了一个 function 构造函数,它返回一个具有给定参数的新数组。 I am trying to add a custom method sumUp using the prototype property.我正在尝试使用prototype属性添加自定义方法sumUp The function constructor returns the array as expected. function 构造函数按预期返回数组。 But when I call that method it is throwing the error:但是当我调用该方法时,它会抛出错误:

TypeError: newArr.sumUp is not a 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);

Your SurajArray function just returns a plain array, which won't use SurajArray.prototype as its prototype, so won't have a sumUp function on it, so the result of calling it (whether via new or otherwise) won't have a sumUp function.您的SurajArray function 只返回一个普通数组,它不会使用SurajArray.prototype作为其原型,因此不会有sumUp function ,因此调用它的结果(无论是通过new还是其他方式)不会有sumUp (There's also no global sumUp function, so the code looking for one won't find it.) (也没有全局sumUp function,所以查找的代码找不到。)

To correctly subclass an array, use class syntax and extends要正确子类化数组,请使用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);

Or more simply:或者更简单地说:

 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. ¹ 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. (Prior to ES2015, you couldn't properly subclass Array .) Just for completeness, this is what it looks like: (在 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);

(Note that additional methods it defines can't correctly use super , though.) (请注意,它定义的其他方法无法正确使用super 。)

A constructor does not need a return value.构造函数不需要返回值。 The prototype of a constructor function can be used to manipulate instance values ( this... ).构造函数 function 的原型可用于操作实例值( this... )。 So, the most simple and prototypal translation of your function(s) will be:因此,您的函数的最简单和原型翻译将是:

 // 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM