最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript this關(guān)鍵字的深入詳解

 更新時間:2021年01月14日 15:07:37   作者:JAVA_樸先生  
這篇文章主要給大家介紹了關(guān)于JavaScript this關(guān)鍵字的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

一、前言

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

二、了解this

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

三、this到底是誰

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

1、函數(shù)執(zhí)行時首先看函數(shù)名前面是否有".",有的話,"."前面是誰,this就是誰;沒有的話this就是window

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

2、自執(zhí)行函數(shù)中的this永遠(yuǎn)是window

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

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

DOM零級事件綁定

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

DOM二級事件綁定

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

在IE6~8下使用attachEvent,默認(rèn)的this就是指的window對象

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

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

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

4、在構(gòu)造函數(shù)模式中,類中(函數(shù)體中)出現(xiàn)的this.xxx=xxx中的this是當(dāng)前類的一個實(shí)例

function CreateJsPerson(name,age){
//瀏覽器默認(rèn)創(chuàng)建的對象就是我們的實(shí)例p1->this
this.name=name;//->p1.name=name
this.age=age;
this.writeJs=function(){
console.log("my name is"+this.name +",i can write Js");
 };
//瀏覽器再把創(chuàng)建的實(shí)例默認(rèn)的進(jìn)行返回
}
var p1=new CreateJsPerson("尹華芝",48);

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

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

5.call、apply和bind

我們先來看一個問題,想在下面的例子中this綁定obj,怎么實(shí)現(xiàn)?

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

如果直接綁定obj.fn(),程序就會報(bào)錯。這里我們應(yīng)該用fn.call(obj)就可以實(shí)現(xiàn)this綁定obj,接下來我們詳細(xì)介紹下call方法:

call方法的作用:

①首先我們讓原型上的call方法執(zhí)行,在執(zhí)行call方法的時候,我們讓fn方法中的this變?yōu)榈谝粋€參數(shù)值obj;然后再把fn這個函數(shù)執(zhí)行。

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

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

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

執(zhí)行,而且在嚴(yán)格模式下和非嚴(yán)格模式下對于第一個參數(shù)是null/undefined這種情況的規(guī)

律也是一樣的。**

兩者唯一的區(qū)別:call在給fn傳遞參數(shù)的時候,是一個個的傳遞值的,而apply不是一個個傳,而是把要給fn傳遞的參數(shù)值統(tǒng)一的放在一個數(shù)組中進(jìn)行操作。但是也相當(dāng)子一個個的給fn的形參賦值。 總結(jié)一句話:call第二個參數(shù)開始接受一個參數(shù)列表,apply第二個參數(shù)開始接受一個參數(shù)數(shù)組

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

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

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

bind體現(xiàn)了預(yù)處理思想:事先把fn的this改變?yōu)槲覀兿胍慕Y(jié)果,并且把對應(yīng)的參數(shù)值也準(zhǔn)備好,以后要用到了,直接的執(zhí)行即可。

call和apply直接執(zhí)行函數(shù),而bind需要再一次調(diào)用。

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

上述代碼沒有執(zhí)行,bind返回改變了上下文的一個函數(shù),我們必須要手動去調(diào)用:

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

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

四、箭頭函數(shù)this指向

箭頭函數(shù)正如名稱所示那樣使用一個“箭頭”(=>)來定義函數(shù)的新語法,但它優(yōu)于傳統(tǒng)的函數(shù),主要體現(xiàn)兩點(diǎn): 更簡短的函數(shù)并且不綁定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();
 }
};

現(xiàn)在,箭頭函數(shù)完全修復(fù)了this的指向, 箭頭函數(shù)沒有自己的this,箭頭函數(shù)的this不是調(diào)用的時候決定的,而是在定義的時候處在的對象就是它的this 。

換句話說, 箭頭函數(shù)的this看外層的是否有函數(shù),如果有,外層函數(shù)的this就是內(nèi)部箭頭函數(shù)的this,如果沒有,則this是window 。

<button id="btn1">測試箭頭函數(shù)this_1</button>
 <button id="btn2">測試箭頭函數(shù)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>

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

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

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

<button id="btn1">測試箭頭函數(shù)this_1</button>
 <button id="btn2">測試箭頭函數(shù)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>

上例中,雖然存在兩個箭頭函數(shù),其實(shí)this取決于最外層的箭頭函數(shù),由于obj是個對象而非函數(shù),所以this指向?yàn)閃indow對象

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

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

擴(kuò)展閱讀

箭頭函數(shù)-廖雪峰

JS中的箭頭函數(shù)與this

this、apply、call、bind

總結(jié)

到此這篇關(guān)于JavaScript this關(guān)鍵字深入詳解的文章就介紹到這了,更多相關(guān)JavaScript this關(guān)鍵字內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript 面向?qū)ο笈c原型

    JavaScript 面向?qū)ο笈c原型

    這篇文章主要介紹了JavaScript 面向?qū)ο笈c原型,需要的朋友可以參考下
    2015-04-04
  • Fetch超時設(shè)置與終止請求詳解

    Fetch超時設(shè)置與終止請求詳解

    這篇文章主要給大家介紹了關(guān)于Fetch超時設(shè)置與終止請求的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Fetch具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • IE瀏覽器兼容Firefox的JS腳本的代碼

    IE瀏覽器兼容Firefox的JS腳本的代碼

    對于經(jīng)常用js的朋友,有時候一段腳本并不是兩個瀏覽器都兼容的,下面一些對ie和firefox都兼容的一些代碼,大家可以學(xué)習(xí)下。
    2008-10-10
  • 一文讓您了解document.forms和document.formName的兼容性分析

    一文讓您了解document.forms和document.formName的兼容性分析

    今天在代碼中不小心寫了兩個name相同的form表單,然后通過document.forms[formName]形式獲取到的只有第一個表單,然后深入學(xué)習(xí)了下document.forms[formName]和document.formName的區(qū)別和兼容性
    2025-03-03
  • 如何利用Typescript封裝本地存儲

    如何利用Typescript封裝本地存儲

    這篇文章主要給大家介紹了關(guān)于如何利用Typescript封裝本地存儲的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2022-01-01
  • js表格排序?qū)嵗治觯ㄖС謎nt,float,date,string四種數(shù)據(jù)類型)

    js表格排序?qū)嵗治觯ㄖС謎nt,float,date,string四種數(shù)據(jù)類型)

    這篇文章主要介紹了js表格排序?qū)嵗治觯ㄖС謎nt,float,date,string四種數(shù)據(jù)類型),涉及javascript常用的升序、降序及數(shù)據(jù)類型轉(zhuǎn)換等相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • 微信小程序常用表單組件的使用詳解

    微信小程序常用表單組件的使用詳解

    本文主要為大家介紹了微信小程序中常用的幾個表單組件的使用方法,例如:button、CheckBox、input、form等,感興趣的可以了解一下
    2022-03-03
  • JS傳遞對象數(shù)組為參數(shù)給后端,后端獲取的實(shí)例代碼

    JS傳遞對象數(shù)組為參數(shù)給后端,后端獲取的實(shí)例代碼

    下面小編就為大家?guī)硪黄狫S傳遞對象數(shù)組為參數(shù)給后端,后端獲取的實(shí)例代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • JS焦點(diǎn)圖,JS 多個頁面放多個焦點(diǎn)圖的實(shí)例

    JS焦點(diǎn)圖,JS 多個頁面放多個焦點(diǎn)圖的實(shí)例

    下面小編就為大家?guī)硪黄狫S焦點(diǎn)圖,JS 多個頁面放多個焦點(diǎn)圖的實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-12-12
  • 服務(wù)器端的JavaScript腳本 Node.js 使用入門

    服務(wù)器端的JavaScript腳本 Node.js 使用入門

    觸爪伸向傳說中的Server-Side Javascrpt。后端JS最出名無疑是Ryan Dahl的node.js,另一個是aptana IDE提供商搞出的jaxer,這里討論node.js的使用
    2012-03-03

最新評論

内江市| 中江县| 凌源市| 南投市| 大姚县| 贵定县| 台山市| 正镶白旗| 博乐市| 晴隆县| 临安市| 禄劝| 枝江市| 河东区| 巢湖市| 凯里市| 喀什市| 资中县| 扎囊县| 宽甸| 和林格尔县| 安多县| 海晏县| 承德县| 余江县| 漳平市| 邵东县| 临海市| 左权县| 桦川县| 聂荣县| 宁津县| 随州市| 象山县| 迁西县| 大同县| 百色市| 福州市| 邯郸市| 台江县| 论坛|