天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

this和執(zhí)行上下文實現(xiàn)代碼

函數(shù)的執(zhí)行上下文由當前的運行環(huán)境而定:
1. 全局變量和全局函數(shù)附屬于全局對象(window),因此使用”var”或”this”兩種方法定義全局變量是等效的。
2. 執(zhí)行上下文和作用域不同。執(zhí)行上下文在運行時確定,隨時可能改變,而作用域則在定義時確定,永遠不會變。
3. 如果當前執(zhí)行的是一個對象的方法,則執(zhí)行上下文就是這個方法所附屬的對象。
4. 如果當前是一個創(chuàng)建對象的過程或者執(zhí)行一個對象的方法,則執(zhí)行上下文就是這個正在被創(chuàng)建的對象。
5. 如果一個方法在執(zhí)行時沒有明確指定附屬對象,則這個方法的上下文為全局對象。
6. 使用call和apply可以改變對象的執(zhí)行上下文。
看下面的例子:
復制代碼 代碼如下:
var v1 = "global variable"; //全局變量附屬于對象
//this.v1 = "global variable with this"; //全局變量定義時使用var v1和this.v1兩種方法等效。
function func1(){
var v1 = "part variable";
writeHtml(v1);
writeHtml(this.v1);
}
func1(); //part variable
//global variable

因為func1中有和全局對象同名的v1變量,所以在func1中直接引用v1引用的是func1中定義的變量。Javascript同樣有局部變量隱藏全局變量的特性。但func1沒有明確的指定附屬對象,因此他的執(zhí)行上下文是全局對象,使用this引用變量的是全局變量。
再看一個稍微復雜一點的例子:
復制代碼 代碼如下:
function ftest(){
var v = "v1v1v1";
this.this_v = "this_v";
return function(){
writeHtml(v);
writeHtml(this.this_v);
}
}
var a = ftest();
var v = "v2v2v2";
writeHtml(this_v); // this_v
a(); //v1v1v1
//this_v

當ftest當做函數(shù)來執(zhí)行時,上下文為全局對象。所以在ftest中使用this定義的變量成為了全局變量。所以我們在ftest外面直接使用變量名訪問this_v的值。但是,由于ftest中返回的匿名函數(shù)是定義在ftest內(nèi)部的,所以這個匿名函數(shù)的作用域就是在ftest內(nèi)部。因此當有全局變量v和局部變量v同名時,這個匿名函數(shù)訪問到的是ftest內(nèi)部定義的變量v。
接下來把ftest當做類,使用new關鍵字來實例化:
復制代碼 代碼如下:
function ftest(){
var v = "v1v1v1";
this.this_v = "this_v";
return function(){
writeHtml(v);
writeHtml(this.this_v);
}
}
var a = new ftest();
var v = "v2v2v2";
//writeHtml(this_v); // 錯誤:this_v未定義
a(); //v1v1v1
//undefined

把ftest當做對象來實例化時,在對象的創(chuàng)建過程中,上下文為被創(chuàng)建的對象本身。注意,這個時候創(chuàng)建的對象是ftest的實例,而創(chuàng)建完成以后又返回了一個函數(shù),這導致了new ftest()實例化后返回的是一個函數(shù),而不是ftest()實例化后對象的引用。因此,這個已經(jīng)實例化的對象無法被引用。當我們定義這個被返回的函數(shù)時,因為沒有用this指定這個函數(shù)的上下文,因此這個被返回的函數(shù)上下文為全局對象,作用域為ftest()函數(shù)內(nèi)部。所以函數(shù)a()執(zhí)行時的由于上下文中沒有定義this_v變量,導致了訪問錯誤。
注意,上面的代碼:
復制代碼 代碼如下:
function ftest(){
return function(){
}
}

這樣的形式并不是一個靜態(tài)封裝環(huán)境,靜態(tài)封裝環(huán)境應該是:在一個函數(shù)定義完成后立即執(zhí)行,并且執(zhí)行完成后返回函數(shù)中的某一個內(nèi)部函數(shù)。
我們看下面一個例子,觀察作用域和上下文對變量引用的影響。
復制代碼 代碼如下:
var v = "global variable";
function method(){
writeHtml(v);
writeHtml(this.v);
}
var Class1 = function(){
var v = "private variable";
this.v = "object variable";

var method2 = method;
this.method2 = method;

var method3 = function(){
writeHtml(v);
writeHtml(this.v);
}
this.method3 = function(){
writeHtml(v);
writeHtml(this.v);
}

method2(); //global variable
//global variable
this.method2(); //global variable
//object variable
method3(); //private variable
//global variable
this.method3();//private variable
//object variable
}
var obj = new Class1();


由于method在全局中定義,所以method的作用域在定義的時候就被確定為全局的。所以method2在Class1內(nèi)部被調(diào)用時,其作用域與是全局,上下文是全局對象。因此,在函數(shù)中訪問到的變量都是全局變量。
同理,this.method2在被調(diào)用時,其作用域是全局,但是由于該函數(shù)在定義時使用this關鍵字指明了其上下文為Class1的對象,所以在該函數(shù)訪問沒有上下文限定的變量時訪問到的是全局變量,訪問有上下文限定的變量時為訪問到的是當前上下文中對應的變量。
在調(diào)用method3和this.method3時,在訪問沒有上下文限定的變量時訪問到的是局部變量,因為局部變量隱藏了全局變量。有上下文限定時和method2相同,訪問到的是當前上下問文中的變量。
使用call和apply可以改變執(zhí)行上下文,由于call和apply只是參數(shù)類型不一樣,因此例子下面都用call來演示。
復制代碼 代碼如下:
var v = "global variable";
var method = function(){
writeHtml(this.v);
}
var Class2 = function(){
this.v = "object variable in instance of Class2";
this.method = function(){
writeHtml(this.v);
}
}
var Class3 = function(){
this.v = "object variable in instance of Class3";
this.method = function(){
writeHtml(this.v);
}
}

var obj2 = new Class2();
var obj3 = new Class3();

method(); //global variable
obj2.method(); //object variable in instance of Class2
obj3.method(); //object variable in instance of Class3

method.call(obj2); //object variable in instance of Class2
method.call(obj3); //object variable in instance of Class3
obj2.method.call(obj3); //object variable in instance of Class3
obj2.method.call(this); //global variable
obj3.method.call(obj2); //object variable in instance of Class2
obj3.method.call(this); //global variable


可以看到,使用call或apply可以將方法綁定到指定的上下文中。在全局環(huán)境中this指向的上下文為全局對象。

JavaScript技術(shù)this和執(zhí)行上下文實現(xiàn)代碼,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 婷婷六月激情综合一区 | 激情A片久久久久久久 | yellow日本高清在线 | 男人J进入女人P免费狂躁 | 亚洲精品天堂无码中文字幕影院 | 亚洲精品成A人在线观看 | 国产99r视频精品免费观看 | 久久怡红院国产精品 | 在线观看国产人视频免费中国 | 国产99精品视频一区二区三区 | 亚洲AV无码一区二区色情蜜芽 | 国产 高清 无码 中文 | 好男人的视频在线观看 | 亚洲精品6久久久久中文字幕 | 欧美精品乱码99久久蜜桃 | 亚洲欧美无码2017在线 | 囯产免费精品一品二区三区视频 | 97无码欧美熟妇人妻蜜 | 成人国产精品玖玖热色欲 | 中文字幕无码乱人伦蜜桃 | 古月娜下面好紧好爽 | 欧美另类摘花hd | 老头扒开粉缝亲我下面 | 亚洲成人免费 | 三叶草成人 | 久久亚洲这里只有精品18 | 秘密影院久久综合亚洲综合 | 灌饱娇嫩H将军公主最新章节 | 亚洲国产精品99久久久久久 | 一本道高清不卡v免费费 | 亚洲AV无码国产精品午夜久久 | 国产不卡无码高清视频 | 国产毛A片久久久久久无码 国产毛A片啊久久久久久A | 丰满少妇69激懒啪啪无码 | 久久亚洲精品成人 | 欧美日韩中文国产一区 | 好紧好湿太硬了我太爽了文字 | 小sao货水好多真紧h的视频 | aaaaaaa一级毛片 | 中文字幕在线视频观看 | 亚洲日韩成人 |