- with语句 扩展一个语句的作用域链 参考链接
语法:
with (expression) {
statement
}
expression
将给定的表达式(对象)添加到在评估语句时使用的作用域链上。
statement
任何语句。要执行多个语句,请使用一个块语句 ({ … })对这些语句进行分组。
- Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)。参考链接
语法:
let p = new Proxy(target, handler);
target:用Proxy包装的目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)。
handler:一个对象,其属性是当执行一个操作时定义代理的行为的函数。
- 属性描述符参考链接
let obj={name:"hello",
_c:function (s1,s2){ console.log(s1+" "+s2);}}
var name="names";
Object.defineProperty(obj,"name",{
enumerable: true,
configurable: true,
get: function reactiveGetter () {
return "get Value "+name;
}
})
hander = {
has (target, key) {
const has = key in target
console.log("proxy hander "+has);
return has
}
}
let p=new Proxy(obj,hander); //with(p){ name }才会调用这个
with(obj){
return _c('div',name)
}
上面这段代码运行结果如下:
let obj={name:"hello",
_c:function (s1,s2){ console.log(s1+" "+s2);}}
var name="names";
Object.defineProperty(obj,"name",{
enumerable: true,
configurable: true,
get: function reactiveGetter () {
return "get Value "+name;
}
})
hander = {
has (target, key) {
const has = key in target
console.log("proxy hander "+has);
return has
}
}
let proxy=new Proxy(obj,hander);
with(proxy){
// _c('div',name);
console.log(name);
//console.log(name in p);
}
上面这段代码截图:
这两段代码的不同之处在于,with语句中使用的对象不一样,一个是obj对象,一个是Proxy 对象。
这里的执行proxy.has的顺序是从外到内,即console.log---->name.
至于为什么proxy.has为什么会劫持with语句,请仔细查看Proxy参考链接中的MDN文档。
另外请认真学习,js的作用域链&变量对象相关知识(可以参考红宝书:javascript高级程序设计。)