(我认为)我已经尝试了每个 .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!');
最佳答案
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!");
没有调用上下文——被调用的函数不是作为对象的一部分被调用的,函数也没有被绑定(bind),所以内部 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');
关于javascript - 非法调用窗口 ['document' ] ['body' ] ['append' ] 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60475522/