简体   繁体   中英

JavaScript Uncaught TypeError: Cannot convert undefined or null to object

I have a question,

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

This will throw Error

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

But this will be fine,

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

And if you bind stack with this referring to itself,

// 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)]

It also works in another way.

How can these happen? What is the difference between a method(case 1) and an arrow function(case 2)?

stack.push references Array.prototype.push . This:

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

doesn't work because it's equivalent to:

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

or

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

which doesn't work because there is no this context of the array to push to.

Method 2 works because you're doing => stack.push(element) - .push is being called with a calling context of stack , rather than stack.push being passed as a callback. (When passed as a callback, the calling context gets lost unless you bind the function, which you do in the 3rd method).

For another example:

 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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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