javascript - 非法调用窗口 ['document' ] ['body' ] ['append' ] 函数

标签 javascript ecmascript-6

(我认为)我已经尝试了每个 .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/

相关文章:

javascript - 从 React Component 关闭 React Modal

javascript - AngularJS:页面加载时使用服务器数据更改输入值

Javascript:使用 `.includes` 查找对象数组是否包含特定对象

javascript - 使用 Webpack 和 Babel 的 ES6 动态导入

javascript - 完成可写流

javascript - 悬停时按钮向右移动

javascript - 如何使用 jquery 从左到右或从右到左为 2 个 css 布局设置动画?

javascript - 函数在参数可用之前运行

Javascript ES6 - 类内部的枚举像静态枚举一样在外部使用

ruby-on-rails - Sprockets 无法找到从 rails 4.2 升级到 rails 5.0 的 .es6 文件