javascript-一些带有“ with”语句和调用的复杂行为
作者:互联网
var a = ({
x: 10,
foo: function () {
function bar() {
console.log(x);
console.log(y);
console.log(this.x);
}
with (this) {
var x = 20;
var y = 30;
bar.call(this);
}
}
}).foo();
结果为undefined,30、20.
非常感谢您逐步了解调试方式的工作原理.
解决方法:
好了,让我们先简化一下代码.我已经将foo重构为一种方法,没有必要确实演示意外的行为.
function foo(a) {
// var x, y, bar - hoisting
function bar() {
console.log(x);
console.log(y);
console.log(a.x);
}
with (a) {
var x = 20;
var y = 30;
bar();
}
}
foo({x:10});
那么,当我们调用foo时会发生什么呢?
>设置一个execution context并用声明的函数和变量填充.这就是俗称的“吊装”.在foo中,有功能栏和变量x和y(以及foo本身及其参数a,仅在我的重构版本中).这是酒吧有权访问的范围.
> with statement被执行.它与基于一个对象的词法环境交换当前的词法环境-可以像访问变量一样访问其任何属性.
>将值20分配给x.这是什么x?解析该标识符时,将检查一个对象,并且-哦-该对象具有该名称的绑定!因此,我们将值放在该绑定中,这将把20放在对象的.x属性上.
>将值30分配给y.这是什么再次检查当前的词法环境,但在对象上找不到y属性.因此,我们继续父级环境,即上面创建的带有x,y,bar变量的环境.确实,在这里我们找到了y变量,因此我们将值30放入了该广告位.
>调用酒吧功能.再次,设置一个新的执行上下文(如上),将步骤1中的上下文作为其父范围(由实例化bar函数时foo中bar的词法位置确定-词法闭包).现在,我们记录这三个感兴趣的表达式:
> x解析为foo范围内的变量x,该变量x的值仍未定义.
> y解析为foo范围内的变量y,该变量保存我们刚刚分配的值30.
> a.x解析为a对象的x属性,该属性保存我们刚刚分配的值20.
标签:ecma262,with-statement,javascript 来源: https://codeday.me/bug/20191121/2054452.html