编程语言
首页 > 编程语言> > javascript-一些带有“ with”语句和调用的复杂行为

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