JavaScript 未捕获的 TypeError:无法将 undefined 或 null 转换为对象

JavaScript Uncaught TypeError: Cannot convert undefined or null to object

提问人:cesc 提问时间:6/4/2021 更新时间:6/4/2021 访问量:547

问:

我有一个问题,

// case 1
const stack = [];
[1,2,3].forEach(stack.push);

这将抛出错误

Uncaught TypeError: Cannot convert undefined or null to object
    at push (<anonymous>)
    at Array.forEach (<anonymous>)
    at <anonymous>:1:9

但这会没事的,

// case 2
const stack = [];
[1,2,3].forEach(element => stack.push(element));
console.log(stack); // [1,2,3]

如果你将堆栈与引用自身绑定,this

// case 3
const stack = [];
[1,2,3].forEach(stack.push.bind(stack));
console.log(stack); // (9) [1, 0, Array(3), 2, 1, Array(3), 3, 2, Array(3)]

它也以另一种方式工作。

这些怎么会发生?方法(案例 1)和箭头函数(案例 2)有什么区别?

javascript foreach 绑定

评论


答:

2赞 CertainPerformance 6/4/2021 #1

stack.push引用。这:Array.prototype.push

const stack = [];
[1,2,3].forEach(stack.push);

不起作用,因为它等同于:

const stack = [];
[1,2,3].forEach(Array.prototype.push);

const callback = Array.prototype.push;
callback(1, 0, [1, 2, 3]);
callback(2, 1, [1, 2, 3]);
callback(3, 2, [1, 2, 3]);

这不起作用,因为没有要推送到的数组的上下文。this

方法 2 之所以有效,是因为您正在执行 - 使用调用上下文 进行调用,而不是作为回调传递。(当作为回调传递时,调用上下文会丢失,除非您绑定函数,这是在第 3 个方法中执行的)。=> stack.push(element).pushstackstack.push

再举一个例子:

const obj = {
  fn() {
    console.log('fn. this is:', this);
  }
};

const callback = obj.fn;
// this does not refer to the object now:
callback();

// but this will:
obj.fn();