JavaScript中normalize函数调用输出异常,请求错误原因解析
这是个很典型的JavaScript中this指向的坑,我来给你拆解一下问题原因和解决办法:
先看你的代码和问题
function normalize() { console.log(this.coords.map(function(x){ return x/this.length; })); } normalize.call({coords: [0, 2, 3], length: 5});
预期输出:
[0,0.4,0.6]
实际输出:[NaN, Infinity, Infinity]
错误原因
核心问题出在嵌套函数的this指向不继承外层函数:
- 当你用
normalize.call(...)调用时,normalize函数内部的this确实指向了你传入的{coords: [0,2,3], length:5}对象,所以this.coords能正确拿到数组。 - 但
map的回调函数是一个独立的普通函数,它的this并不会自动继承外层normalize的this。在非严格模式下,这个回调里的this会指向全局对象(浏览器里是window,Node.js里是global),而全局对象上没有length属性,所以this.length等于undefined。 - 计算时就会出现:
0 / undefined→NaN2 / undefined和3 / undefined→Infinity(正数除以undefined等价于除以0,结果是正无穷)
几种解决办法
1. 用变量保存外层this
在normalize里先把当前this存到一个变量,回调里用这个变量代替this:
function normalize() { const self = this; // 保存外层的this console.log(this.coords.map(function(x){ return x/self.length; })); } normalize.call({coords: [0, 2, 3], length: 5});
2. 利用map的第二个参数指定this
Array.prototype.map支持第二个参数,用来设置回调函数执行时的this指向:
function normalize() { console.log(this.coords.map(function(x){ return x/this.length; }, this)); // 把normalize的this传给map作为回调的this } normalize.call({coords: [0, 2, 3], length: 5});
3. 使用箭头函数
箭头函数不会绑定自己的this,它会直接继承外层作用域的this,写法最简洁:
function normalize() { console.log(this.coords.map(x => x/this.length)); } normalize.call({coords: [0, 2, 3], length: 5});
内容的提问来源于stack exchange,提问作者usr123
相关产品推荐
相关产品推荐

