能否在构造函数调用前重新定位Function对象的this引用?
解决JavaScript沙箱中Function构造函数的this指向与作用域访问问题
先拆解你最初的代码为什么达不到预期效果:
当你调用foo.call()时,因为没有传入第一个参数,在非严格模式下函数内部的this会指向全局对象(浏览器环境是window,Node.js环境是global),而非foo这个Function实例。所以this.baz = this.mux实际上是给全局对象添加了baz属性,不是给foo,这就导致console.log(foo.baz)输出undefined。
方案1:让Function内部的this指向自身
你只需要在调用call时,把foo作为第一个参数传入,强制函数内部的this指向foo本身:
var foo = new Function(" this.baz = this.mux; return this "); foo.mux = "mux"; foo.call(foo); // 显式绑定this到foo console.log(foo.baz); // 输出 "mux" console.log(foo.toString());
这样函数内部的this就会指向foo,this.baz = this.mux会直接给foo添加baz属性,值为foo.mux。
方案2:在内部构造函数中访问外层Function实例的属性
你补充的需求里,想在Function构造的内部函数中访问外层foo的属性,但Function构造的函数运行在全局作用域,无法直接引用外层的foo变量。这时可以通过参数传递的方式,把foo的引用传入内部函数:
var foo = new Function("ctx", ` return new function() { this.baz = ctx.mux; // 通过ctx参数访问外层foo的mux属性 return this; } `); foo.mux = "mux"; var innerInstance = foo.call(null, foo); // 将foo作为ctx参数传入 console.log(innerInstance.baz); // 输出 "mux"
这里我们给Function构造函数添加了ctx参数,调用foo时把foo本身作为ctx传进去,内部构造函数就能通过ctx访问到foo的属性了。
如果你的沙箱场景需要更严格的隔离,也可以考虑用Proxy或者iframe实现,但针对当前Function构造函数的问题,上面两种方案已经能解决核心需求。
内容的提问来源于stack exchange,提问作者Sir Galahad
相关产品推荐
相关产品推荐

