функция typeof не является функцией - PullRequest
0 голосов
/ 16 мая 2018

Коллега показал мне следующий код, который поразил меня:

const x = Object.create(function() {});
// variant: const x = Object.create(Array);
console.log(x.call) // ƒ call() { [native code] }
console.log(typeof x.call) // "function"
console.log(x.call instanceof Function) // true
x.call() // Uncaught TypeError: x.call is not a function

Я понимаю, что x.call является прототипом function, он не принадлежит x свойству:

x.hasOwnProperty('call') // false

Но почему x.call не может быть на самом деле казнен? Это связано с ключевым словом call ?

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Основная идея Object.create сводится к следующему:

function create(prt){
    var noOP = function(){};
    noOP.prototype = prt;
    return new noOP;
}

Таким образом, возвращаемое значение НЕ является функцией, это объект.Для иллюстрации я сначала сохраню функцию:

var u = function(){return 5}

Теперь я буду использовать Object.create для нее:

var res = create(u);

Утешение даст вам >noOP {}, поэтомуэто простой объект.Проблема начинается отсюда:

res.hasOwnProperty("prototype") //false

Таким образом, вновь созданный объект имеет «прототип», но на самом деле он унаследован от u:

res.prototype === u.prototype //true

Аналогично, «вызов»снова унаследовано от u, которое, в свою очередь, унаследовано от прототипа его (Function) конструктора:

res.call === u.call //true
res.call === Function.prototype.call //also true

И вот ваша проблема, если вы посмотрите на реализацию EcmaScript call, она ожидает thisи this должен вызываться.Изолировать call от res:

var x = res.call; //ƒ call() { [native code] }

Теперь я "вызову" вызов, мы передадим 3 аргумента, 1-й для вызова, 2-й для установки this внутри этого вызываемого, 3-йи так далее для аргументов для вызываемого:

x.call(function(a){console.log("hey");console.log(a);console.log(this);},5,5)
//hey
//5
//Number {5}

Теперь попробуйте то же самое на созданном объекте res либо res.call или x.call:

x.call(res,5,5) //TypeError: x.call is not a function

Вконец, это сводится к возвращенному объекту из Object.create, не вызываемому.

0 голосов
/ 16 мая 2018

Причина x - это объект, который наследует call от Function.prototype, однако call предназначен для вызова функции, поэтому происходит сбой, если вы пытаетесь выполнить его на обычном объекте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...