JS对象调用Math.max/min计算三角形宽高返回NaN问题
问题根源
计算结果返回NaN由两个核心错误导致:
this指向不符合预期:使用普通工厂函数返回对象字面量时,对象初始化阶段的this并不指向即将返回的新对象。无new关键字调用普通函数时,非严格模式下this绑定到全局对象,严格模式下为undefined,两种场景下都无法读取到挂载在实例上的x/y坐标数组,读取到的值为undefined,传入数学计算方法后必然返回NaN。Math.max/Math.min传参方式错误:两个方法原生接收数值类型的可变参数,不支持直接传入数组作为入参。即使修复this指向问题,直接传入数组仍然无法正确计算极值,会返回NaN。
额外存在一处笔误:getHeight方法错误使用x坐标数组计算高度,即使前两个问题修复,返回的高度值也不正确。
修正方案
- 避免在对象字面量初始化阶段通过
this引用自身属性,直接使用函数入参arrayX、arrayY计算初始宽高,从根源规避this绑定问题 - 调用
Math.max/Math.min时,通过展开运算符...将数组拆分为单个数值参数传入 - 修正
getHeight方法的笔误,使用y坐标数组计算高度
修正后的可运行代码:
function Triangle(name, arrayX, arrayY){ // 直接使用入参计算初始宽高,不依赖this指向 const initWidth = Math.max(...arrayX) - Math.min(...arrayX); const initHeight = Math.max(...arrayY) - Math.min(...arrayY); return { name, x: arrayX, y: arrayY, width: initWidth, height: initHeight, getWidth() { return Math.max(...this.x) - Math.min(...this.x) }, getHeight() { // 注意此处使用y坐标数组,不要误写为x return Math.max(...this.y) - Math.min(...this.y) } } } const tri = Triangle('tri', [15, 42, 84], [10, 37, 48]) console.log(tri.width) // 69(84-15) console.log(tri.getWidth()) // 69 console.log(tri.height) // 38(48-10) console.log(tri.getHeight()) // 38
你项目中使用继承逻辑的版本问题完全一致:ShapeTriangle函数内给tri.width赋值时引用的this.x,同样不指向新创建的tri实例,直接使用函数接收的坐标参数计算即可,修正逻辑和上述精简版完全相同。
兼容提示:如果需要适配不支持ES6展开运算符的环境,可以将
Math.max(...arr)替换为Math.max.apply(null, arr),计算效果完全一致。
内容的提问来源于stack exchange,提问作者jean3xw
相关产品推荐
相关产品推荐

