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