国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

JavaScript this關鍵字的深入詳解

瀏覽:92日期:2023-10-05 13:28:22
一、前言

this關鍵字是JavaScript中最復雜的機制之一。它是一個很特別的關鍵字,被自動定義在所有函數的作用域中。對于那些沒有投入時間學習this機制的JavaScript開發者來說,this的綁定一直是一件非常令人困惑的事。

JavaScript this關鍵字的深入詳解

二、了解this

學習this的第一步是明白this既不指向函數自身也不指向函數的詞法作用域,你也許被這樣的解釋誤導過,但其實它們都是錯誤的。隨著函數使用場合的不同,this的值會發生變化。但總有一條原則就是 JS中的this代表的是當前行為執行的主體 ,在JS中主要研究的都是函數中的this,但并不是說只有在函數里才有this, this實際上是在函數被調用時發生的綁定,它指向什么完全取決于函數在哪里被調用 。如何的區分this呢?

三、this到底是誰

這要分情況討論,常見有五種情況:

1、函數執行時首先看函數名前面是否有'.',有的話,'.'前面是誰,this就是誰;沒有的話this就是window

function fn(){ console.log(this);}var obj={fn:fn};fn();//this->windowobj.fn();//this->objfunction sum(){ fn();//this->window}sum();var oo={ sum:function(){ console.log(this);//this->oo fn();//this->window }};oo.sum();

2、自執行函數中的this永遠是window

(function(){ //this->window })(); ~function(){ //this->window }();

3、給元素的某一個事件綁定方法,當事件觸發的時候,執行對應的方法,方法中的this是當前的元素,除了IE6~8下使用attachEvent(IE一個著名的bug)

DOM零級事件綁定

oDiv.onclick=function(){ //this->oDiv };

DOM二級事件綁定

oDiv.addEventListener('click',function(){ //this->oDiv },false);

在IE6~8下使用attachEvent,默認的this就是指的window對象

oDiv.attachEvent('click',function(){ //this->window });

我們大多數時候,遇到事件綁定,如下面例子這種,對于IE6~8下使用attachEvent不必太較真

function fn(){ console.log(this);}document.getElementById('div1').onclick=fn;//fn中的this就是#divldocument.getElementById('div1').onclick=function(){console.log(this);//this->#div1fn();//this->window};

4、在構造函數模式中,類中(函數體中)出現的this.xxx=xxx中的this是當前類的一個實例

function CreateJsPerson(name,age){//瀏覽器默認創建的對象就是我們的實例p1->thisthis.name=name;//->p1.name=namethis.age=age;this.writeJs=function(){console.log('my name is'+this.name +',i can write Js'); };//瀏覽器再把創建的實例默認的進行返回}var p1=new CreateJsPerson('尹華芝',48);

必須要注意一點: 類中某一個屬性值(方法),方法中的this需要看方法執行的時候,前面是否有'.',才能知道this是誰 。大家不妨看下接下來的這個例子,就可明白是啥意思。

function Fn(){this.x=100;//this->f1this.getX=function(){console.log(this.x);//this->需要看getX執行的時候才知道 }}var f1=new Fn;f1.getX();//->方法中的this是f1,所以f1.x=100var ss=f1.getX;ss();//->方法中的this是window ->undefined

5.call、apply和bind

我們先來看一個問題,想在下面的例子中this綁定obj,怎么實現?

var obj={name:'浪里行舟'};function fn(){console.log(this);//this=>window}fn();obj.fn();//->Uncaught TypeError:obj.fn is not a function

如果直接綁定obj.fn(),程序就會報錯。這里我們應該用fn.call(obj)就可以實現this綁定obj,接下來我們詳細介紹下call方法:

call方法的作用:

①首先我們讓原型上的call方法執行,在執行call方法的時候,我們讓fn方法中的this變為第一個參數值obj;然后再把fn這個函數執行。

②call還可以傳值,在嚴格模式下和非嚴格模式下,得到值不一樣。

//在非嚴格模式下var obj={name:'浪里行舟 '};function fn(num1,num2){console.log(num1+num2);console.log(this);}fn.call(100,200);//this->100 num1=200 num2=undefinedfn.call(obj,100,200);//this->obj num1=100 num2=200fn.call();//this->windowfn.call(null);//this->windowfn.call(undefined);//this->window

//嚴格模式下 fn.call();//在嚴格模式下this->undefinedfn.call(null);// 在嚴格模式 下this->nullfn.call(undefined);//在嚴格模式下this->undefined

**apply和call方法的作用是一模一樣的,都是用來改變方法的this關鍵字并且把方法

執行,而且在嚴格模式下和非嚴格模式下對于第一個參數是null/undefined這種情況的規

律也是一樣的。**

兩者唯一的區別:call在給fn傳遞參數的時候,是一個個的傳遞值的,而apply不是一個個傳,而是把要給fn傳遞的參數值統一的放在一個數組中進行操作。但是也相當子一個個的給fn的形參賦值。 總結一句話:call第二個參數開始接受一個參數列表,apply第二個參數開始接受一個參數數組

fn.call(obj,100,200);fn.apply(obj,[100,200]);

bind:這個方法在IE6~8下不兼容,和call/apply類似都是用來改變this關鍵字的 ,但是和這兩者有明顯區別:fn.call(obj,1,2);//->改變this和執行fn函數是一起都完成了

fn.bind(obj,1,2);//->只是改變了fn中的this為obj,并且給fn傳遞了兩個參數值1、2, 但是此時并沒有把fn這個函數執行var tempFn=fn.bind(obj,1,2);tempFn(); //這樣才把fn這個函數執行

bind體現了預處理思想:事先把fn的this改變為我們想要的結果,并且把對應的參數值也準備好,以后要用到了,直接的執行即可。

call和apply直接執行函數,而bind需要再一次調用。

var a ={ name : 'Cherry', fn : function (a,b) { console.log( a + b) } } var b = a.fn; b.bind(a,1,2)

JavaScript this關鍵字的深入詳解

上述代碼沒有執行,bind返回改變了上下文的一個函數,我們必須要手動去調用:

b.bind(a,1,2)() //3

必須要聲明一點:遇到第五種情況(call apply和bind),前面四種全部讓步。

四、箭頭函數this指向

箭頭函數正如名稱所示那樣使用一個“箭頭”(=>)來定義函數的新語法,但它優于傳統的函數,主要體現兩點: 更簡短的函數并且不綁定this 。

var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = function () { return new Date().getFullYear() - this.birth; // this指向window或undefined }; return fn(); }};

現在,箭頭函數完全修復了this的指向, 箭頭函數沒有自己的this,箭頭函數的this不是調用的時候決定的,而是在定義的時候處在的對象就是它的this 。

換句話說, 箭頭函數的this看外層的是否有函數,如果有,外層函數的this就是內部箭頭函數的this,如果沒有,則this是window 。

<button id='btn1'>測試箭頭函數this_1</button> <button id='btn2'>測試箭頭函數this_2</button> <script type='text/javascript'> let btn1 = document.getElementById(’btn1’); let obj = { name: ’kobe’, age: 39, getName: function () { btn1.onclick = () => { console.log(this);//obj }; } }; obj.getName(); </script>

JavaScript this關鍵字的深入詳解

上例中,由于箭頭函數不會創建自己的this,它只會從自己的作用域鏈的上一層繼承this。其實可以簡化為如下代碼:

let btn1 = document.getElementById(’btn1’); let obj = { name: ’kobe’, age: 39, getName: function () { console.log(this) } }; obj.getName();

那假如上一層并不存在函數,this指向又是誰?

<button id='btn1'>測試箭頭函數this_1</button> <button id='btn2'>測試箭頭函數this_2</button> <script type='text/javascript'> let btn2 = document.getElementById(’btn2’); let obj = { name: ’kobe’, age: 39, getName: () => { btn2.onclick = () => { console.log(this);//window }; } }; obj.getName(); </script>

JavaScript this關鍵字的深入詳解

上例中,雖然存在兩個箭頭函數,其實this取決于最外層的箭頭函數,由于obj是個對象而非函數,所以this指向為Window對象

由于this在箭頭函數中已經按照詞法作用域綁定了,所以, 用call()或者apply()調用箭頭函數時,無法對this進行綁定,即傳入的第一個參數被忽略 :

var obj = { birth: 1990, getAge: function (year) { var b = this.birth; // 1990 var fn = (y) => y - this.birth; // this.birth仍是1990 return fn.call({birth:2000}, year); }};obj.getAge(2018); // 28擴展閱讀

箭頭函數-廖雪峰

JS中的箭頭函數與this

this、apply、call、bind

總結

到此這篇關于JavaScript this關鍵字深入詳解的文章就介紹到這了,更多相關JavaScript this關鍵字內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: JavaScript
相關文章:
主站蜘蛛池模板: 欧美极品在线视频 | 美国一级毛片∞ | 在线男人天堂 | 国产在线一区在线视频 | 日韩一级不卡 | 日本高清不卡中文字幕 | 国产精品国产三级国产an不卡 | 91久久亚洲精品一区二区 | 欧美在线观看高清一二三区 | 亚洲欧美自拍偷拍 | 青青草国产免费一区二区 | 日本亚州在线播放精品 | 欧美性高清视频免费看www | 国产欧美日韩一区二区三区 | 一区高清 | 国产成人精品magnet | 一级a爰片久久毛片 | 久久精品视频观看 | 性久久久久久久久久 | 五月久久噜噜噜色影 | 日本三级久久 | 日韩精品亚洲专区在线观看 | 亚洲天堂视频一区 | 国产精品欧美视频另类专区 | 日本免费人成黄页网观看视频 | 玖玖玖视频在线观看视频6 玖玖影院在线观看 | 亚洲欧美视频在线播放 | 一级毛片真人免费播放视频 | 国产精品所毛片视频 | 美女曰皮| 中文字幕综合 | 亚洲va久久久噜噜噜久久狠狠 | 国产乱子伦露脸对白在线小说 | 久久99精品久久久久久三级 | 国产成人18黄网站免费 | 欧美整片在线 | 中文字幕一区在线播放 | 国产精品99久久免费观看 | 欧美国产精品不卡在线观看 | 波多野结衣视频在线 | 久久亚洲视频 |