摘要:目錄一理解指針意義二用解決指針指向問題三的使用場景與少用之處一理解指針意義讓我們先理解好指針的定義引用的是函數(shù)執(zhí)行的環(huán)境對象永遠指向的是最后調用它的對象,也就是看它執(zhí)行的時候是誰調用的通俗地講,就是誰調用,就指向誰我們分類舉例舉例前先看下本
目錄
一.理解this指針意義
二.用call(),apply(),bind()解決指針指向問題
三.bind()的使用場景與少用之處
讓我們先理解好this指針的定義:
this引用的是函數(shù)執(zhí)行的環(huán)境對象
this永遠指向的是最后調用它的對象,也就是看它執(zhí)行的時候是誰調用的
通俗地講,就是誰調用this,this就指向誰,我們分類舉例
舉例前先看下本文會一直用到的變量及定義的函數(shù)
var theName = "Joe"; //全局變量 function showName() { var theName = "Li"; alert(this.theName); }1.全局直接調用方法
showName(); //彈出“Joe”
因為是window對象調用showName(),所以this指向window啦,故彈出"Joe"
2.對象中調用全局下的方法var student1 = { theGrade : 100, theName : "Han", showName : showName, showGrade : function () { alert(this.theGrade); } }; student1.showName();//彈出“Han” student1.showGrade();//彈出“100”
因為是在student1對象調用函數(shù),故彈出的是對應student1對象中的"Han"和“100”啦
3.對象中調用其他對象的方法var student2 = { theGrade: 60, showGrade: student1.showGrade }; student2.showGrade(); //彈出"60"
即使student2對象調用了student1對象下的方法showGrade(),因為是student2對象調用,故彈出的仍是student2的"60"
4.對象的方法賦給全局變量執(zhí)行var outFunction = student1.showGrade; outFunction();//彈出“undefined”
將sutdent1對象的函數(shù)賦值給oufFuncction,而outFunction是在window對象下調用的,故彈出“undefined”
5.構造函數(shù)下的this指針function setStudent() { this.theName = "Ming"; } var student3 = new setStudent(); alert(student3.theName);//彈出“Ming”,new改變this指向
構造函數(shù)下,new改變了指針指向,指向了student3
6.事件監(jiān)聽中創(chuàng)建閉包的this指針關鍵:閉包保存創(chuàng)建時的環(huán)境!!!
舉個例子
為了更好理解閉包與指針的關系,我們先定義一個全局變量,一個函數(shù),和一個對象
var example = "window";//全局變量 function showExample() { console.log(this.example); } var exampleObject = { example : "Object", showExample_in_Object : function (arg1, arg2) { console.log(this.example); console.log(arg1,arg2) } };
接著,我們設置一個事件監(jiān)聽來說明問題:
//事件監(jiān)聽 var btn = document.getElementById("btn"); btn.onclick = function (ev) { console.log(this); //this指向按鈕,執(zhí)行匿名函數(shù)的是btn this.example = "ele"; console.log(this.example);//彈出"ele" showExample(); //閉包保存函數(shù)創(chuàng)建時的環(huán)境,故this指向window對象 exampleObject.showExample_in_Object();//this指向exampleObject };
結果:
接下來分段說明各個指針
其中
????this.example = "ele"; ????console.log(this.example);
其中的this指向btn,所以顯示的是‘ele’
而
????showExample(); ?? ?? ????exampleObject.showExample_in_Object();?? ?
在匿名函數(shù)中為閉包,閉包保存函數(shù)創(chuàng)建時的環(huán)境,故this分別指向window和exampleObject
補充對閉包中this的理解:https://segmentfault.com/q/10...
以上是部分this指針的理解
如果我在事件監(jiān)聽中想要減少代碼重復,或者是調用其他對象的屬性呢?
如果我想用btn.addEventListener()時指向的某個特定對象呢?
這就可以引出下面call(),apply()與bind()的應用了
7.函數(shù)中自執(zhí)行函數(shù)指向function User(id){ this.id = id; } User.prototype.test = function(){ console.log(this);//指向b對象 (function(){ console.log(this) //指向window })() } var a = new User("a") a.test();
因為自執(zhí)行函數(shù)是由window執(zhí)行的
如果此時使用箭頭函數(shù)
function User2(id){ this.id = id; } User.prototype.test = function(){ console.log(this); //指向b對象 (() =>{ console.log(this) //指向b對象 })() } var b = new User2("b"); b.test();
因為箭頭函數(shù)不會綁定this,所以指向上一層的b對象
二.用call(),apply(),bind()解決指針指向問題 1.call()與apply()call()與apply()的作用都是在特定的作用域中調用函數(shù),實際上等于設置函數(shù)體內設置this對象的值
簡單地說,就是可以改變函數(shù)的執(zhí)行環(huán)境
call()與allpy()效果相同,僅是傳參形式不同,如下所示
call(): fun.call(thisArg,?arg1,?arg2, ...) thisArg : fun函數(shù)運行時指定的this值 arg1,arg2,.. (可選):指定的各個參數(shù)
apply(): func.apply(thisArg, [argsArray]) thisArg : fun函數(shù)運行時指定的this值 [argsArray](可選) : 傳參數(shù)組或者傳參類數(shù)組
下面直接看例子吧
我們以上面的例子進行修改,為了對比傳參的形式,我們對showExample函數(shù)添加兩個參數(shù)
function showExample(arg1,arg2) { console.log(this.example); console.log(arg1,arg2); }
接下來便是btn的點擊事件函數(shù)修改,我們令showExample函數(shù)指向exampleObject
//call與apply的應用 btn.onclick = function (ev) { showExample.call(exampleObject,111,222); //彈出"Object" ,111與222是傳參示例 showExample.apply(exampleObject,[111,222]); //彈出"Object" ,[111,222]是傳參示例 }; 彈出"Object" ,111與222是傳參示例 showExample.apply(exampleObject,[111,222]); //彈出"Object" ,[111,222]是傳參示例 };
如上,通過call()與apply()的應用,可以改變函數(shù)的指向而多次運用
如果我想便于調試想使用ele.addEventListener()嘞?
這就要用上bind()方法了
2.bind()的運用fun.bind(thisArg[, arg1[, arg2[, ...]]])
MDN?: bind()方法創(chuàng)建一個新的函數(shù), 當被調用時,將其this關鍵字設置為提供的值, ,在調用新函數(shù)時,在任何提供之前提供一個給定的參數(shù)序列。
我們再舉個簡單的例子,將exampleObject簡單修改下
var exampleObject = { example : "Object", showExample_in_Object : function (arg1, arg2) { console.log(this); console.log("example:"+ this.example); console.log("arg1:" + arg1); console.log("arg2:" + arg2); } };
并把showExample_in_Object()函數(shù)添加給btn
注意這里的是函數(shù),不是閉包!
btn.addEventListener("click",exampleObject.showExample_in_Object);
控制臺顯示如下
?? ??? ??? ?
可以看出this指向的是btn,而無法滿足我們使用exampleObject中屬性的需要,同時也無法進行傳參(用call()與apply()就直接執(zhí)行函數(shù)了!)
(這里的沒有對第一個參數(shù)arg1進行傳參,故默認顯示MouseEvent對象)
這時我們可以用bind()方法創(chuàng)建一個新的函數(shù),并讓其指針指向exampleObject,并傳兩個新的參數(shù)進去
btn.addEventListener("click",exampleObject.showExample_in_Object.bind(exampleObject,111,222));
當當~指針指向了exampleObject,傳參也成功了~
另外,這里也有個可以不使用bind()的方法,就是也用閉包啦
btn.addEventListener("click",function () { exampleObject.showExample_in_Object(111,222); });
結果一樣,但這種方法不利于代碼的維護,同時也無法指向特定的對象? ??
三.bind()的使用場景與少用之處使用場景:主要用于如上的事件監(jiān)聽,以及setTimeout()和setInterval()
少用之處:被綁定的函數(shù)與普通函數(shù)相比有更多的開銷,它們需要更多的內存,同時也因為多重函數(shù)調用稍微慢一點,所以最好只在必要時使用
以上,如有不對之處,請大家指教
參考資料:? ??徹底理解this指針:? ??https://www.cnblogs.com/pssp/...
? ? MDN:bind():?? ?https://developer.mozilla.org...
?? ?MDN:apply():https://developer.mozilla.org...
?? ?MDN:call():?? ?https://developer.mozilla.org...
?? ?《JavaScript高級程序設計(第3版)》
?? ?《JavaScript語言精粹》
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108554.html
摘要:它代表函數(shù)運行時,自動生成的一個內部對象,只能在函數(shù)內部使用類似的還有。總結關鍵字就是,誰調用我,我就指向誰。注意由于已經(jīng)被定義為函數(shù)內的一個變量。因此通過關鍵字定義或者將聲明為一個形式參數(shù),都將導致原生的不會被創(chuàng)建。 題目 封裝函數(shù) f,使 f 的 this 指向指定的對象 。 輸入例子 bindThis(function(a, b) { return this.test +...
摘要:詞法熟悉語法的開發(fā)者,箭頭函數(shù)在涉及綁定時的行為和普通函數(shù)的行為完全不一致。被忽略的作為的綁定對象傳入,使用的是默認綁定規(guī)則。使用內置遍歷數(shù)組返回迭代器函數(shù)普通對象不含有,無法使用,可以進行改造,個人博客地址 this詞法 熟悉ES6語法的開發(fā)者,箭頭函數(shù)在涉及this綁定時的行為和普通函數(shù)的行為完全不一致。跟普通this綁定規(guī)則不一樣,它使用了當前的詞法作用域覆蓋了this本來的值。...
摘要:它們有明確的和成員函數(shù)的定義,只有的實例才能調用這個的成員函數(shù)。用和調用函數(shù)里用和來指定函數(shù)調用的,即指針的指向。同樣,對于一個后的函數(shù)使用或者,也無法改變它的執(zhí)行,原理和上面是一樣的。 函數(shù)里的this指針 要理解call,apply和bind,那得先知道JavaScript里的this指針。JavaScript里任何函數(shù)的執(zhí)行都有一個上下文(context),也就是JavaScri...
摘要:首先,我們判斷是否存在方法,然后,若不存在,向對象的原型中添加自定義的方法。指向調用它的對象。總之三個的使用區(qū)別都是用來改變函數(shù)的對象的指向的第一個參數(shù)都是要指向的對象都可以利用后續(xù)參數(shù)傳參是返回對應函數(shù),便于稍后調用,是立即調用 apply和call都是為了改變某個函數(shù)運行時的上下文而存在的(就是為了改變函數(shù)內部this的指向),F(xiàn)unction對象的方法,每個函數(shù)都能調用; 使用a...
閱讀 961·2023-04-26 02:49
閱讀 1172·2021-11-25 09:43
閱讀 2541·2021-11-18 10:02
閱讀 2919·2021-10-18 13:32
閱讀 1281·2019-08-30 13:54
閱讀 2074·2019-08-30 12:58
閱讀 3008·2019-08-29 14:06
閱讀 2154·2019-08-28 18:10