摘要:但是有一個總的原則,那就是指的是,調(diào)用函數(shù)的那個對象作為函數(shù)調(diào)用在函數(shù)被直接調(diào)用時綁定到全局對象。這一過程分為三步創(chuàng)建類的實例。這步是把一個空的對象的屬性設(shè)置為。函數(shù)被傳入?yún)?shù)并調(diào)用,關(guān)鍵字被設(shè)定為該實例。
this 的值到底是什么?一次說清楚
你怎么還沒搞懂 this?
this、apply、call、bind
由于運行期綁定的特性,JavaScript 中的 this 含義非常多,它可以是全局對象、當前對象或者任意對象,這完全取決于函數(shù)的調(diào)用方式
隨著函數(shù)使用場合的不同,this的值會發(fā)生變化。但是有一個總的原則,那就是this指的是,調(diào)用函數(shù)的那個對象
1、作為函數(shù)調(diào)用在函數(shù)被直接調(diào)用時this綁定到全局對象。在瀏覽器中,window 就是該全局對象
console.log(this); //window function fn1(){ console.log(this); } fn1(); //window2、內(nèi)部函數(shù)
函數(shù)嵌套產(chǎn)生的內(nèi)部函數(shù)的this不是其父函數(shù),仍然是全局變量
function fn0(){ function fn(){ console.log(this); } fn(); } fn0();
//window
3、setTimeout、setInterval這兩個方法執(zhí)行的函數(shù)this也是全局對象
document.addEventListener("click", function(e){
console.log(this); //document setTimeout(function(){ console.log(this); //window }, 200);
}, false);
4、作為構(gòu)造函數(shù)調(diào)用所謂構(gòu)造函數(shù),就是通過這個函數(shù)生成一個新對象(object)。這時,this就指這個新對象
new 運算符接受一個函數(shù) F 及其參數(shù):new F(arguments...)。這一過程分為三步:
創(chuàng)建類的實例。這步是把一個空的對象的 proto 屬性設(shè)置為 F.prototype 。
初始化實例。函數(shù) F 被傳入?yún)?shù)并調(diào)用,關(guān)鍵字 this 被設(shè)定為該實例。
返回實例。
看例子
function Person(name){ this.name = name; } Person.prototype.printName = function(){ console.log(this.name); }; var p1 = new Person("Byron"); var p2 = new Person("Casper"); var p3 = new Person("Vincent"); p1.printName(); //Byron p2.printName(); //Casper p3.printName(); //Vincent5、作為對象方法調(diào)用
在 JavaScript 中,函數(shù)也是對象,因此函數(shù)可以作為一個對象的屬性,此時該函數(shù)被稱為該對象的方法,在使用這種調(diào)用方式時,this 被自然綁定到該對象
var obj1 = { name: "Byron", fn : function(){ console.log(this); //obj1 } }; obj1.fn();
小陷阱
var fn2 = obj1.fn; fn2(); //window
因為fn2等于? (){console.log(this)},所以this指向的是全局變量
6、DOM對象綁定事件在事件處理程序中this代表事件源DOM對象(低版本IE有bug,指向了window)
document.addEventListener("click", function(e){ console.log(this); //document var _document = this; setTimeout(function(){ console.log(this); //window console.log(_document); //document }, 200); }, false);
解決方案
輸出結(jié)果//document//document//document
bind,返回一個新函數(shù),并且使函數(shù)內(nèi)部的this為傳入的第一個參數(shù)
bind的用法是給 函數(shù)名.bind(參數(shù))返回的是一個函數(shù),加()才立即執(zhí)行
var obj1 = { name: "Byron", fn : function(){ console.log(this); } }; var fn3 = obj1.fn.bind()() //window var fn4 = obj1.fn.bind(obj1)() //obj1
例二
首先bind的this.sayhello沒有指向page,而是指向的this.node
解決方案一:
解決方案二,,this.sayhello,但是這個方案有問題,在執(zhí)行sayhello函數(shù)時,函數(shù)內(nèi)部的this是指向this.node(document.body),而不是指向page的
解決方案三:
解決方案二的問題,我們用bind函數(shù)傳遞了this參數(shù),sayhello函數(shù)內(nèi)部this就還是指向page的了
call apply,調(diào)用一個函數(shù),傳入函數(shù)執(zhí)行上下文及參數(shù)
fn.call(context, param1, param2...) fn.apply(context, paramArray)
語法很簡單,第一個參數(shù)都是希望設(shè)置的this對象,不同之處在于call方法接收參數(shù)列表,而apply接收參數(shù)數(shù)組
fn2.call(obj1); fn2.apply(obj1);
難得舉例了,直接看這篇文章寫的更好this、apply、call、bind
二、函數(shù)的執(zhí)行環(huán)境和變量 1、函數(shù)的執(zhí)行環(huán)境一個函數(shù)被執(zhí)行時,會創(chuàng)建一個執(zhí)行環(huán)境(ExecutionContext),函數(shù)的所有的行為均發(fā)生在此執(zhí)行環(huán)境中,構(gòu)建該執(zhí)行環(huán)境時,JavaScript 首先會創(chuàng)建 arguments變量,其中包含調(diào)用函數(shù)時傳入的參數(shù)
接下來創(chuàng)建作用域鏈,然后初始化變量。首先初始化函數(shù)的形參表,值為 arguments變量中對應的值,如果 arguments變量中沒有對應值,則該形參初始化為 undefined。
如果該函數(shù)中含有內(nèi)部函數(shù),則初始化這些內(nèi)部函數(shù)。如果沒有,繼續(xù)初始化該函數(shù)內(nèi)定義的局部變量,需要注意的是此時這些變量初始化為 undefined,其賦值操作在執(zhí)行環(huán)境(ExecutionContext)創(chuàng)建成功后,函數(shù)執(zhí)行時才會執(zhí)行,這點對于我們理解JavaScript中的變量作用域非常重要,最后為this變量賦值,會根據(jù)函數(shù)調(diào)用方式的不同,賦給this全局對象,當前對象等
至此函數(shù)的執(zhí)行環(huán)境(ExecutionContext)創(chuàng)建成功,函數(shù)開始逐行執(zhí)行,所需變量均從之前構(gòu)建好的執(zhí)行環(huán)境(ExecutionContext)中讀取
2、三種變量(名稱有點不規(guī)范,暫時可以不管名稱)實例變量:(this)類的實例才能訪問到的變量
靜態(tài)變量:(屬性)直接類型對象能訪問到的變量
私有變量:(局部變量)當前作用域內(nèi)有效的變量
看個例子
function ClassA(){
var a = 1; //私有變量,只有函數(shù)內(nèi)部可以訪問.外部無法訪問,外部要訪問的話需要返回 this.b = 2; //實例變量,只有實例可以訪問
}
ClassA.c = 3; // 靜態(tài)變量,也就是給函數(shù)對象增加了屬性
console.log(a); // error無法訪問局部變量
console.log(ClassA.b) // undefined this.b并不是給函數(shù)賦值的屬性,而是
console.log(ClassA.c) //3
var classa = new ClassA();
console.log(classa.a);//undefined 無法訪問局部變量
console.log(classa.b);// 2
console.log(classa.c);//undefined ClassA.c只是函數(shù)上的c屬性和classa這個對象沒有關(guān)系
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/100751.html
摘要:新搭建的個人博客,本文地址學習筆記用重寫在一開始的時候配置中我們就加入了的支持,就是下面的配置,但之前的學習筆記都使用的完成,所以專門作一篇筆記,記錄使用完成創(chuàng)建相關(guān)文件修改,增加該入口文件修改,引入該文件做個簡單的測試,看下瀏覽器全部用來 新搭建的個人博客,本文地址:React學習筆記3:用es2015(ES6)重寫CommentBox在一開始的時候webpack配置中我們就加入了e...
摘要:方法在中定義的函數(shù)。這種聲明方式會定義一個生成器函數(shù),它返回一個對象。類用定義的類,實際上也是函數(shù)。調(diào)用函數(shù)時使用的引用,決定了函數(shù)執(zhí)行時刻的值。表示當為時,取全局對象,對應了普通函數(shù)。四操作的內(nèi)置函數(shù)和可以指定函數(shù)調(diào)用時傳入的值。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學習過程的一些要...
摘要:方法在中定義的函數(shù)。這種聲明方式會定義一個生成器函數(shù),它返回一個對象。類用定義的類,實際上也是函數(shù)。調(diào)用函數(shù)時使用的引用,決定了函數(shù)執(zhí)行時刻的值。表示當為時,取全局對象,對應了普通函數(shù)。四操作的內(nèi)置函數(shù)和可以指定函數(shù)調(diào)用時傳入的值。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學習過程的一些要...
摘要:方法在中定義的函數(shù)。這種聲明方式會定義一個生成器函數(shù),它返回一個對象。類用定義的類,實際上也是函數(shù)。調(diào)用函數(shù)時使用的引用,決定了函數(shù)執(zhí)行時刻的值。表示當為時,取全局對象,對應了普通函數(shù)。四操作的內(nèi)置函數(shù)和可以指定函數(shù)調(diào)用時傳入的值。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學習過程的一些要...
摘要:學習筆記頂層對象雖然是筆記但是基本是抄了一次大師的文章了頂層對象頂層對象,在瀏覽器環(huán)境指的是對象,在指的是對象。之中,頂層對象的屬性與全局變量是等價的。的寫法模塊的寫法上面代碼將頂層對象放入變量。參考引用頂層對象實戰(zhàn) es6學習筆記-頂層對象_v1.0 (雖然是筆記,但是基本是抄了一次ruan大師的文章了) 頂層對象 頂層對象,在瀏覽器環(huán)境指的是window對象,在Node指的是gl...
閱讀 1542·2021-11-17 09:33
閱讀 1292·2021-10-11 10:59
閱讀 2925·2021-09-30 09:48
閱讀 1932·2021-09-30 09:47
閱讀 3061·2019-08-30 15:55
閱讀 2361·2019-08-30 15:54
閱讀 1515·2019-08-29 15:25
閱讀 1672·2019-08-29 10:57