此代码有效:
it.cb(h => {
console.log(h);
h.ctn();
});
it.cb(new Function(
'h', [
'console.log(h)',
'h.ctn()'
]
.join(';')
));
这两个测试用例基本相同。但是用这样的数组构造一个字符串很麻烦,而且您无法获得静态分析。所以我当时想做的是这样的:
it.cb(isolated(h => {
console.log(h);
h.ctn();
}));
其中孤立的是一个类似于以下内容的辅助函数:
const isolated = function(fn){
const str = fn.toString();
const paramNames = getParamNames(str);
return new Function(...paramNames.concat(str));
};
最大的问题是Function.prototype.toString()给您整个功能。有谁知道从函数的字符串表示形式获取函数体的好方法?
更新:PRoberts在问这是什么目的,目的很简单:
const foo = 3;
it.cb(isolated(h => {
console.log(foo); // this will throw "ReferenceError: foo is not defined"
h.ctn();
}));
我写了一个版本,isolated()可以处理任何非bind用户定义的函数表达式,并为范围访问抛出自定义错误:
function isolated (fn) {
return new Function(`
with (new Proxy({}, {
has () { return true; },
get (target, property) {
if (typeof property !== 'string') return target[property];
throw new ReferenceError(property + ' accessed from isolated scope');
},
set (target, property) {
throw new ReferenceError(property + ' accessed from isolated scope');
}
})) return ${Function.prototype.toString.call(fn)}
`).call(new Proxy(function () {}, new Proxy({}, {
get() { throw new ReferenceError('this accessed from isolated scope'); }
})));
}
// test functions
[
() => arguments, // fail
() => this, // pass, no way to intercept this
() => this.foo, // fail
() => this.foo = 'bar', // fail
() => this(), // fail
() => new this, // fail
h => h, // pass
h => i, // fail
(a, b) => b > a ? b : a, // pass
].forEach(fn => {
const isolate = isolated(fn);
console.log(isolate.toString());
try {
isolate();
console.log('passed');
} catch (error) {
console.log(`${error.name}: ${error.message}`);
}
})
与尝试解析用户定义函数的参数和主体相比,此实现稍微简单一些,因此不容易出错。
该with语句是一种相对简单的方法,用于在强制隔离的函数中捕获所有作用域的引用并抛出ReferenceError
。它通过Proxy
使用一个get
陷阱将一个中间变量插入到作用域中来实现,该陷阱会拦截所访问的作用域变量名。
在Proxy
作为函数的背景是,这是一个有点棘手来实现,也残缺的唯一部分传递。这是必要的,因为Proxy
提供给with
语句的作用域不会拦截对this
关键字的访问,因此还必须显式包装上下文,以拦截并间接使用this
隔离的箭头函数内部的任何间接用法。
问题内容: 编辑 : 请参阅此问题底部的我的完整答案。 tl; dr答 :Python具有静态嵌套的作用域。的 静态 方面可以与隐变量声明相互作用,产生非显而易见的结果。 (由于该语言通常具有动态特性,所以这尤其令人惊讶)。 我以为我对Python的作用域规则掌握得很好,但是这个问题使我彻底陷入困境,而我的google-fu让我失败了(这并不令我感到惊讶-请看问题标题;) 我将从一些可以按预期工作
问题内容: 我尝试在函数的局部范围内使用eval()。但是,它始终在全局范围内进行评估。 自包含的示例: 1-此代码有效: 2-抛出为 3-与2相同的结果。 问题答案: 保存(或)调用的结果以返回函数的本地范围。否则,在生成器表达式内部将返回gen-expr的本地范围。 顺便说一句,您不需要明确的理解即可构建该命令:
问题内容: 我在HTML的多个位置使用指令。每个人都为自己创建了一个孤立的范围,这显然给我带来了很多麻烦。 例如。 在上面提到的html中,正在创建4个作用域。默认情况下,在定义的父级中创建1个,默认情况下创建3个。 是否有可能阻止自身创建隔离范围?如果不可能,那么是否有解决方法? 问题答案: 您需要创建自己的指令,该指令可以在没有隔离范围的情况下加载指定的模板。 的HTML 指示 工作朋克
问题内容: 我首先尝试使用AngularJS自定义指令。 我在指令的链接功能中使用(或理解…)隔离范围时遇到麻烦。 这是我应用程序这部分的代码: view.html 是在viewCtrl范围内发布的变量,其中包含请求的xml字符串。 rawData.js raw-data.html 我不明白为什么弹出模式时会显示ID正确,但是当我尝试使用它时,其值是不确定的。 也许我对隔离的范围值(和)错了。 感
我试过这个: 但这扩展了弦中的基因,这不是我想要的。