Javascript代理和With语句

Javascript代理和With语句,javascript,Javascript,为什么这会引发引用错误 var p = new Proxy({}, { get: function(target, name) { return `hello world ${name}`; } }); with (p) { console.log(a) } 未捕获引用错误:未定义 我认为with可能读取p对象的现有属性,并将它们添加到变量范围中。因此,由于没有实际的属性,因此不会将其添加到范围中 换句话说,此时的a查找调用变量解析,而从不调用属性解析 with

为什么这会引发引用错误

var p = new Proxy({}, {
    get: function(target, name) {
        return `hello world ${name}`;
    }
});
with (p) { console.log(a) }
未捕获引用错误:未定义

我认为with可能读取p对象的现有属性,并将它们添加到变量范围中。因此,由于没有实际的属性,因此不会将其添加到范围中

换句话说,此时的a查找调用变量解析,而从不调用属性解析

with语句将计算对象的对象环境记录添加到正在运行的执行上下文的词法环境中。然后,它使用这个扩展的词汇环境执行一条语句。最后,它恢复了原始的词汇环境

然后在变量解析中,它执行hasBindingname,这对于代理对象将失败,因为没有绑定

HasBindingN确定环境记录是否具有字符串值N的绑定。如果有,则返回true;如果没有,则返回false

我认为with可能读取p对象的现有属性,并将它们添加到变量范围中。因此,由于没有实际的属性,因此不会将其添加到范围中

换句话说,此时的a查找调用变量解析,而从不调用属性解析

with语句将计算对象的对象环境记录添加到正在运行的执行上下文的词法环境中。然后,它使用这个扩展的词汇环境执行一条语句。最后,它恢复了原始的词汇环境

然后在变量解析中,它执行hasBindingname,这对于代理对象将失败,因为没有绑定

HasBindingN确定环境记录是否具有字符串值N的绑定。如果有,则返回true;如果没有,则返回false


这个代码非常愚蠢。然而,它提出的问题非常有趣。事实证明你可以让它工作!您需要使用代理上的has方法告诉javascript对象中有哪些变量可用。此外,由于某些原因,符号不能隐式转换为字符串。所以,为了让这段代码正常工作,你需要这样的东西

var p = new Proxy({}, {
    //we need to identify what elements are available. 
    //this overloads the in operator eg ("foo" in obj)
    has:function(target,name){
        //if we just returned true we would override everything
        //and we need to get to the console
        return name!="console";
    },      
    get: function(target, name) {
        //for some reason the toString is mandatory don't know why 
        //you get "TypeError: Cannot convert a Symbol value to a string" otherwise
        return "Hello world "+name.toString();
    }
});
with (p) { console.log(abc) } 

这个代码非常愚蠢。然而,它提出的问题非常有趣。事实证明你可以让它工作!您需要使用代理上的has方法告诉javascript对象中有哪些变量可用。此外,由于某些原因,符号不能隐式转换为字符串。所以,为了让这段代码正常工作,你需要这样的东西

var p = new Proxy({}, {
    //we need to identify what elements are available. 
    //this overloads the in operator eg ("foo" in obj)
    has:function(target,name){
        //if we just returned true we would override everything
        //and we need to get to the console
        return name!="console";
    },      
    get: function(target, name) {
        //for some reason the toString is mandatory don't know why 
        //you get "TypeError: Cannot convert a Symbol value to a string" otherwise
        return "Hello world "+name.toString();
    }
});
with (p) { console.log(abc) } 

您正在尝试运行console.loga,但从未定义。我假设您打算运行console.logp。虽然这可能会以某种方式起作用,但不要这样做@戴夫:是的,你好,世界a@Santi:其想法是他的代理应该捕获属性访问,并且应该尝试从p访问。所以在with或proxies的语义中,这是被阻止的。这里不太清楚的是为什么要这样做……您正在尝试运行console.loga,但从未定义过。我假设您打算运行console.logp。虽然这可能会以某种方式起作用,但不要这样做@戴夫:是的,你好,世界a@Santi:其想法是他的代理应该捕获属性访问,并且应该尝试从p访问。所以在with或proxy的语义中,这是被阻止的。这里不太清楚的是为什么你会这样做。。。