调用summableNum.sum()报错TypeError: this.reduce is not a function,求助解决
解决summableNum.sum()报错的问题
嘿,这个问题我之前踩过坑!咱们先搞清楚为啥会报错,再给你几个靠谱的解决方案~
为啥会报错?
你用Object.assign({}, numbers, {...})把数组numbers的元素复制到了一个普通空对象里,最后得到的summableNum本质是Object类型,不再是Array了。
数组的reduce方法是挂载在Array.prototype上的,普通对象根本没有这个方法。当你调用summableNum.sum()时,this指向的是这个普通对象,自然就会抛出this.reduce is not a function的错误。
解决方案
根据你的需求,这里有几种不同的处理方式:
方案1:直接给数组添加方法(不转成对象)
如果不需要把数组变成普通对象,直接在数组实例上添加sum方法最简单:
let numbers = [1, 2, 3]; // 给数组添加sum方法,此时this指向数组本身,能正常调用reduce numbers.sum = function() { return this.reduce((a, b) => a + b); }; console.log(numbers.sum()); // 输出6 console.log(numbers[0]); // 输出1
要是不想污染原数组,可以先复制一份数组再添加方法:
let numbers = [1, 2, 3]; let summableNum = [...numbers]; // 浅拷贝原数组 summableNum.sum = function() { return this.reduce((a, b) => a + b); };
方案2:如果必须用普通对象的形式
如果你一定要保持summableNum是普通对象,可以在sum方法里手动把对象的数值属性转成数组再计算:
let numbers = [1, 2, 3]; let summableNum = Object.assign({}, numbers, { sum: function() { // 提取对象里的数值属性,过滤掉sum方法本身 return Object.values(this) .filter(val => typeof val === 'number') .reduce((a, b) => a + b); } }); console.log(summableNum.sum()); // 输出6 console.log(summableNum[0]); // 输出1
方案3:用类继承实现可求和的数组(最优雅)
如果需要频繁使用这种带求和功能的数组,用ES6类继承Array是最佳实践,既能保留数组的所有特性,又能自定义方法:
class SummableArray extends Array { sum() { return this.reduce((a, b) => a + b); } } // 创建自定义数组实例 let summableNum = new SummableArray(1, 2, 3); console.log(summableNum.sum()); // 输出6 console.log(summableNum[0]); // 输出1 // 还能正常使用数组的原生方法 console.log(summableNum.map(x => x * 2)); // 输出[2, 4, 6]
内容的提问来源于stack exchange,提问作者Khaled Ayed
相关产品推荐
相关产品推荐

