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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章