js禁用的with

1、with 语句用于设置代码在特定对象中的作用域。

例如:

        var obj = {
            name: "obj"
        }
        var name = "window";
        function func(){
            var name = "func";
            with(obj){
                console.log(name);
            }
        }
        func();

打印的结果:obj;

实际上:对于with语句而言,会将指定的对象添加到作用域链中。

        var obj = {
            // name: "obj"
        }
        var name = "window";
        function func(){
            var name = "func";
            with(obj){
                console.log(name);
            }
        }
        func();

打印的结果:func;

2、理解with的作用,理解函数作用域链和this对象

例如:

({
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();

分析:

with的特点:(请完全理解下面的with特点)

作用域链的顶部添加with传入的对象,即:with内先查找和操作该对象的属性,如果该对象没有找到,再往作用域链的下一级查找,然后操作操作。obj作用域——>函数1——>函数2——>...——>window全局作用域)
问题中,变量声明提示和函数声明提升后的实际代码是:

({
x: 10,
foo: function () {
    var x;//默认undefined,等会分析要用到
    var y;//默认undefined
    function bar() {
        console.log(x);
        console.log(y);
        console.log(this.x);
    }
    with (this) {
        x = 20;
        y = 30;
        bar.call(this);
    }
}
}).foo();

var x; x变量的默认值undefined;
var y;y变量的默认值undefined;
等会分析会用到

当代码走到with中时,this是外面的大对象。
(1)x =20
根据with的特点(上面提到的),先在this大对象中找x属性(对象中叫属性,函数叫变量),巧了,this大对象有x:10,将值改为20;
(2)y =30
同样的,在this大对象中找y属性,没有!再去foo函数中y变量,有!设置y为30;
(3)bar.call(this)
大家要注意:call apply bind(ES5)都是只改变this指向,this指向只与this对象相关的操作有关。与函数变量没有一点关系!!!

执行bar函数,call修改this指向,指向大对象。

bar函数执行
(1)打印变量x。bar函数中没有变量x,往上面的作用域找,foo函数中有变量x,x的值是undefined。(with改变的x是指大对象的x属性)
(2)打印变量y。bar函数没有变量y,往上找,foo函数中有变量y,值为30。(with语句改变y的时候,先去大对象中找y属性,没有,再去foo函数中找到y变量,并将其修改为30)
(3)打印this.x。打印大对象的x属性,值为20。

所以结果:

变量x:undefined
变量y:30
this.x:20

猜你喜欢

转载自blog.csdn.net/zyz00000000/article/details/106626766