Недопустимый вызов для функции window ['document'] ['body'] ['append'] - PullRequest
2 голосов
/ 01 марта 2020

(я думаю) Я пробовал каждую .bind, .call() или .apply версию,

Но я не могу заставить F2("World!") работать

var F1 = window["document"]["body"];

// works fine:
F1["append"]("Hello")

var F2 = F1["append"];

// valid function append() 
console.log( F2 );

// Illegal invocation
F2("World!");

Хотелось бы заставить его работать в:


let D=["document", "body", "append"];
([0,1,2].reduce((root, x) => root[D[x]], window))('World!');

1 Ответ

2 голосов
/ 01 марта 2020

F1["append"] является только ссылкой на Element.prototype.append:

var F1 = window["document"]["body"];
var F2 = F1["append"];
console.log(F2 === Element.prototype.append);

Для этой функции требуется контекст вызова - значение this - чтобы функция знала, что такое родительский элемент, к которому будет добавлен дочерний элемент. С

F1["append"]("Hello")

Объектом, для которого вызывается функция, является F1, значение this, которое видит функция, так что все работает как положено. Но с

F2("World!");

контекст вызова отсутствует - вызываемая функция не вызывается как часть объекта, и функция не была связана, поэтому внутренний Element.prototype.append не знает, какой родительский элемент, к которому должен быть добавлен дочерний элемент.

.bind работает, как и .call, как и создание функции, которая вызывает F1 с соответствующим контекстом вызова:

var F1 = window["document"]["body"];

// works fine:
F1["append"]("Hello")

var F2 = F1["append"];
F2.call(F1, "World!");

var F1 = window["document"]["body"];

// works fine:
F1["append"]("Hello")

var F2 = child => F1["append"](child);
F2("World!");

Чтобы сделать это с reduce, сначала .pop отключите последнее свойство. Затем используйте reduce, чтобы перейти к последнему последнему свойству (объекту, для которого должна быть вызвана функция). Затем вы можете вызвать функцию с нужным контекстом вызова через скобки:

const paths = ["document", "body", "append"];
const fnProp = paths.pop();
const lastObj = paths.reduce((parent, nextProp) => parent[nextProp], window);
lastObj[fnProp]('World');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...