成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

this - 想說愛你不容易

zhaot / 418人閱讀

摘要:構(gòu)造函數(shù)也是函數(shù),所以當(dāng)你用普通調(diào)用方式調(diào)用時(shí)這個(gè)時(shí)候相當(dāng)于給對(duì)象添加了和兩個(gè)屬性。為構(gòu)造函數(shù)指定這里報(bào)錯(cuò)了,原因是我們?nèi)チ撕瘮?shù),這里的函數(shù)不是一個(gè)構(gòu)造函數(shù)當(dāng)然解決方式也是有的。

前言

javascript中的this是啥東西?為啥我們經(jīng)常被他搞得暈頭轉(zhuǎn)向不知所以?他是惡魔?是天使 ?是怪胎?讓我們一起來揭開它那神秘的面紗。

他是個(gè)啥

首先this是Javascript語言的關(guān)鍵字之一,指函數(shù)運(yùn)行時(shí)的當(dāng)前對(duì)象。那既然和函數(shù)運(yùn)行有關(guān),js中函數(shù)有哪些調(diào)用模式呢?

純粹的函數(shù)調(diào)用

對(duì)象的方法調(diào)用

構(gòu)造函數(shù)調(diào)用

apply、call調(diào)用

我擦,有木有一千只草泥馬在心里蹦騰不息,人家是要弄懂this,你這又是整的哪一出

我們慢慢來,一步步從這些調(diào)用模式中探究this這個(gè)神奇的遠(yuǎn)古神獸

純粹的函數(shù)調(diào)用

函數(shù)調(diào)用 即 functionName () 模式,這也是我們使用的最多的一種方式,其屬于全局調(diào)用,瀏覽中默認(rèn)情況下函數(shù)內(nèi)部的this指向window,當(dāng)然是在非嚴(yán)格模式下。

this.name = "qianlong";

function showName () {
  console.log(this.name);
  console.log(this === window);
}

showName() 
 
// qianlong
// true
對(duì)象的方法調(diào)用

當(dāng)一個(gè)函數(shù)作為對(duì)象的某個(gè)屬性方法被調(diào)用的時(shí)候

var obj = {
  name: "qianlong",
  showName: function () {
    console.log(this.name);
  }
};

obj.showName();
// qianlong

可以看出this指向是obj這個(gè)對(duì)象,其實(shí)本質(zhì)上講函數(shù)調(diào)用形式內(nèi)部this就是指向調(diào)用它的那個(gè)對(duì)象

上面的例子相當(dāng)于

window.showName()

這也是為什么可以讀取到全局定義的name屬性的原因。

再來

var showName = function () {
    console.log(this.name);
  },
  obj = {
    name: "qianlong",
    showName: showName
  };

  obj.showName();

這個(gè)時(shí)候輸出的是什么呢

結(jié)果是不變的,在js中,一切都是對(duì)象,而這里也只是將,obj的showName屬性指向,showNmae函數(shù)的引用地址。

繼續(xù)

當(dāng)我們把showName方法賦值給了一個(gè)變量,又會(huì)有什么事情發(fā)生呢?

var obj = {
  name: "qianlong",
  showName: function () {
    console.log(this.name);
  }
};

var tempShowName = obj.showName;

tempShowName()

// undefined

為什么不是期望的那樣輸出 qianlong呢。obj的showName方法是一個(gè)對(duì)象,當(dāng)把它賦值給了tempShowName變量,此時(shí)便和obj沒有什么關(guān)系了,而這個(gè)時(shí)候的調(diào)用和下面是等價(jià)的。

window.tempShowName()

window上此事并沒有name屬性,自然輸出是undefined。

構(gòu)造函數(shù)調(diào)用

當(dāng)使用 new 去調(diào)用一個(gè)構(gòu)造函數(shù)的時(shí)候,內(nèi)部的this,指向的是實(shí)例化出來的對(duì)象。

var Person = function (name, sex) {
  this.name = name;
  this.sex = sex;
  console.log(this);
};

var p1 = new Person("qianlong", "boy");

// Person {name: "qianlong", sex: "boy"};

構(gòu)造函數(shù)也是函數(shù),所以當(dāng)你用普通調(diào)用方式調(diào)用時(shí)

var Person = function (name, sex) {
  this.name = name;
  this.sex = sex;
  console.log(this);
};

Person("qianlong", "boy");

// 這個(gè)時(shí)候相當(dāng)于給window對(duì)象添加了name和sex兩個(gè)屬性。

window.name // "qianlong"
window.sex // "boy"
apply、call調(diào)用

使用call和apply方式去調(diào)用一個(gè)函數(shù)的時(shí)候,內(nèi)部的this指向的是傳進(jìn)來的第一個(gè)參數(shù),當(dāng)?shù)谝粋€(gè)參數(shù)是undefined或者null的時(shí)候,依舊指向window

關(guān)于call和apply歡迎查看另一篇文章

js中call、apply、bind那些事

var showName = function () {
      console.log(this);
    };

showName() // window
showName.call(undefined) // window
showName.call(null) // window
showName.call({name: "qianlong"}) // {name: "qianlong"}

箭頭函數(shù)

在 ES6 的新規(guī)范中,加入了箭頭函數(shù),它和普通函數(shù)最不一樣的一點(diǎn)就是 this 的指向,普通函數(shù)中的this,是運(yùn)行時(shí)候決定的,而箭頭函數(shù)卻是定義時(shí)候就決定了。

var obj = {
  name: "qianlong",
  showName: function () {
    console.log(this.name);
  },
  showNameLater: function () {
    setTimeout(() => {
      console.log(this.name);
    }, 1000)
  }        
};

obj.showNameLater();

// qianlong
var obj = {
  name: "qianlong",
  showName: () => {
    console.log(this.name);
  }
};

obj.showName();
// undefined
一些坑

1. setTimeout

var obj = {
  name: "qianlong",
  showName: function () {
    console.log(this.name);
  },
  showNameLater: function () { 
    setTimeout(this.showName, 1000);
  }
};

obj.showNameLater();

// undefined

這里在執(zhí)行setTimeout這個(gè)函數(shù)的時(shí)候傳了obj的showName函數(shù)作為第一個(gè)參數(shù),其效果與

var showName = obj.showName

是相同的。而setTimeout內(nèi)部其實(shí)也是執(zhí)行了傳進(jìn)去這個(gè)函數(shù)而已,即。

showName();

還記得這種調(diào)用方式和window.showName()是類似的效果嗎?這個(gè)時(shí)候輸入為undefined也就好理解了。

那么怎么解決這個(gè)問題呢,畢竟我們期望的效果是輸出qianlong。

var obj = {
  name: "qianlong",
  showName: function () {
    console.log(this.name);
  },
  showNameLater: function () { 
    var self = this;
    setTimeout(function () {
      self.showName();
    }, 1000);
  }
};

obj.showNameLater();

或者

var obj = {
  name: "qianlong",
  showName: function () {
    console.log(this.name);
  },
  showNameLater: function () { 
    setTimeout(this.showName.bind(this), 1000);
  }
};

obj.showNameLater();

2. setTimeout

尼瑪坑爹啊,居然還是因?yàn)槟恪?/p>

"use strict";

function show() {
  console.log(this);
}

show(); // undefined 

setTimeout(show, 1); // window

在嚴(yán)格模式下面,函數(shù)調(diào)用的時(shí)候沒有指定this的情況下,內(nèi)部this的表現(xiàn)為undefined,但是setTimeout卻不同,其內(nèi)部默認(rèn)還是指向window。

3. 為構(gòu)造函數(shù)指定this

var Person = function (name, sex) {
  this.name = name;
  this.sex = sex;
};

var p1 = new Person.call({});

// Uncaught TypeError: Person.call is not a constructor

這里報(bào)錯(cuò)了,原因是我們?nèi)?new 了 Person.call 函數(shù) ,這里的函數(shù)不是一個(gè)構(gòu)造函數(shù);

當(dāng)然解決方式也是有的。

var Person = function (name, sex) {
  this.name = name;
  this.sex = sex;
};

var p1 = new (Person.bind({}))("qianlong", "sex");

// Person {name: "qianlong", sex: "sex"}

4. 為箭頭函數(shù)指定this

var show = (str) => {
  console.log(str);
  console.log(this);
};

show("qianlong");
// qianlong
// window

show.call({name: "qianlong"}, "qianlong");
// qianlong
// window

可以看到使用call來手動(dòng)改變箭頭函數(shù)中的this的時(shí)候,無法成功。 箭頭函數(shù)中的 this 在定義它的時(shí)候已經(jīng)決定了(執(zhí)行定義它的作用域中的 this),與如何調(diào)用以及在哪里調(diào)用它無關(guān),包括 (call, apply, bind) 等操作都無法改變它的 this。

結(jié)語

文章可能有些疏漏與錯(cuò)誤之處,歡迎各位指正。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/86732.html

相關(guān)文章

  • 瀏覽器緩存,想說愛你容易

    摘要:瀏覽器緩存的分類瀏覽器緩存主要有兩類緩存協(xié)商和徹底緩存,也有稱之為協(xié)商緩存和強(qiáng)緩存。只能被終端用戶的瀏覽器緩存,不允許等中繼緩存服務(wù)器對(duì)其緩存。 今天小微開店寶在測(cè)試環(huán)境發(fā)布更新的時(shí)候,同事問:為什么我需要手動(dòng)清理瀏覽器緩存才能看到變更?難道系統(tǒng)上線后也需要客戶自己清理瀏覽器緩存嗎!看來,這個(gè)坑需要我來填了。 什么是瀏覽器緩存 瀏覽器緩存(Brower Caching)是瀏覽器在本地磁...

    Imfan 評(píng)論0 收藏0
  • 無需Flash錄視頻——HTML5中級(jí)進(jìn)階

    摘要:比如就會(huì)報(bào)出警告,并執(zhí)行出錯(cuò)。視頻的寬高,并不會(huì)因?yàn)樘顚懙臄?shù)值比例不合法而失真。通過綁定事件,來獲取視頻片段數(shù)據(jù),并在內(nèi)存中累積。執(zhí)行之后會(huì)停止觸發(fā)事件。錄制結(jié)束后,把累計(jì)的片段數(shù)據(jù)保存為對(duì)象,并從瀏覽器下載存為視頻文件。 前言 HTML5的權(quán)限越來越大了,瀏覽器可以直接調(diào)用攝像頭、麥克風(fēng)了,好激動(dòng)啊。我們要用純潔的HTML代碼造出自己的天地。 視頻采集 本篇介紹的栗子 都是在chro...

    Cruise_Chan 評(píng)論0 收藏0
  • 2016年前端盤點(diǎn)合集

    摘要:年已經(jīng)過去,這一年前端領(lǐng)域發(fā)生了什么有哪些技術(shù)和項(xiàng)目引人注目工程師們觀點(diǎn)和看法又有怎樣的變化在此,整理了一些對(duì)過去的年盤點(diǎn)的資料,一是希望能借此提高自己的姿勢(shì)水平,二是希望能為年的學(xué)習(xí)有所指導(dǎo)。 2016年已經(jīng)過去,這一年前端領(lǐng)域發(fā)生了什么?有哪些技術(shù)和項(xiàng)目引人注目?工程師們觀點(diǎn)和看法又有怎樣的變化?在此,整理了一些對(duì)過去的2016年盤點(diǎn)的資料,一是希望能借此提高自己的姿勢(shì)水平,二是希...

    aisuhua 評(píng)論0 收藏0
  • JavaScript深入淺出

    摘要:理解的函數(shù)基礎(chǔ)要搞好深入淺出原型使用原型模型,雖然這經(jīng)常被當(dāng)作缺點(diǎn)提及,但是只要善于運(yùn)用,其實(shí)基于原型的繼承模型比傳統(tǒng)的類繼承還要強(qiáng)大。中文指南基本操作指南二繼續(xù)熟悉的幾對(duì)方法,包括,,。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。 怎樣使用 this 因?yàn)楸救藢儆趥吻岸?,因此文中只看懂?8 成左右,希望能夠給大家?guī)韼椭?...(據(jù)說是阿里的前端妹子寫的) this 的值到底...

    blair 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

zhaot

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<