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

資訊專欄INFORMATION COLUMN

[JavaScript 隨筆] 關(guān)于 this 你必須知道這幾點

鄒強 / 877人閱讀

摘要:關(guān)于中的坑大家都踩過。那這里的和是嚴(yán)格相等的。這里介紹的是通過創(chuàng)建對象時的。提示一下,數(shù)組對象的函數(shù)本身就是有這個功能的,也就是說可以達到要求。事件有兩種記法,一個是也是類似,那么在中出現(xiàn)的表示觸發(fā)該事件的元素,也就是。

TL;DR: this 指向調(diào)用該方法的對象,只有函數(shù)執(zhí)行時,this 才有定義。

關(guān)于 JavaScript 中 this 的坑大家都踩過。像本文開頭的這句話,道理你都懂,但是……所以這里就總結(jié)了幾個 this 最常用的使用場景。

全局環(huán)境

在瀏覽器的全局環(huán)境中,this === window 。
但是,當(dāng)使用了 "use strict"; 進入嚴(yán)格模式時,this === undefined 。

如果是在 nodejs 環(huán)境中,全局對象會更復(fù)雜一些,因為它有兩種執(zhí)行方式。一個是命令行方式,即輸入

$ node

進入類似于瀏覽器的控制臺一樣的界面,可以逐行執(zhí)行代碼。那這里的 this 和 global 是嚴(yán)格相等的。但如果是

$ node program.js

這樣執(zhí)行一個文件的話,nodejs 會為每個文件創(chuàng)建一個自執(zhí)行匿名函數(shù)的塊,這里面的 this 并是全局對象 global 。但是,如果聲明變量時沒有加 var 的話,這些變量還是會加到 global 上去。

函數(shù)調(diào)用

函數(shù)中的 this 可能更常見一點吧。

function foo() {
  console.log(this.name);
}

如果直接判斷這里的 this 是全局對象的話,就太沖動了(還記得最開始這句話嗎?只有當(dāng)函數(shù)調(diào)用時才能判斷 this 真正引用的對象是什么)。

如果它作為一個全局函數(shù)【foo()】,或者閉包【return foo;】,又或者是回調(diào)函數(shù)【other(foo)】的話,那么它在執(zhí)行時就是全局對象了。

還有三個我們經(jīng)常遇到的方法可以改變 this 的引用,就是 call、apply 和 bind 。

foo.call(thisArg);

那么這里的 this 就指向了 thisArg,但當(dāng)它為 null 或者 undefined,this 會指向全局對象。

還有一種函數(shù)調(diào)用是使用 new 關(guān)鍵字。

new foo();

這里的 this 指向的是構(gòu)造出來的新對象。

那么其他情況就必然是 x.foo() 類似的調(diào)用方式了,看到這條語句的時候再去看 foo 的定義,它里面 this 引用的就是對象 x 。
數(shù)學(xué)學(xué)得好的話,可以反應(yīng)過來 x 可以表示任何對象,比如 a,a.b,或者其他更復(fù)雜的表達式。

好,來測試一下,有如下代碼

var o = {
  foo: function() { return this; }
};

function bar() {
  return o.foo;
}

console.log(bar()());

結(jié)果是什么?反正就兩個選擇,一是 this 指向全局對象,二是指向 o 。

原型

在上一篇文章 《繼承的實現(xiàn)方式及原型概述》 中其實有提到過一部分原型方面的知識,那這里就稍微深入一點。

這里介紹的是通過 new 創(chuàng)建對象時的 this 。每個函數(shù)對象(用 function 關(guān)鍵字修飾的變量)自帶 prototype 屬性,在 prototype 上定義的屬性都會繼承給 this 。這些屬性被每個實例共享,實例中會創(chuàng)建所有 prototype 上的屬性,值為這些屬性的引用。

文字一多心里難免煩煩的……

首先,這里通過 new 創(chuàng)建了兩個實例,它們有相同的 prototype 。原型中的數(shù)據(jù)是創(chuàng)建在堆上的,所以繼承下來的屬性和方法都會指向同一個引用(左邊的箭頭)。

然后,在 this 上定義的屬性和方法是創(chuàng)建在棧上的,所以這些屬性和方法會有各自獨立的內(nèi)存區(qū)域(右邊的箭頭)。

假如在 this 上定義的變量與 prototype 上沖突了,那么 prototype 中的那個變量會“隱藏”起來。

如果有 child.foo = "tom"; 那么思考一下怎樣才能讓 child.foo 重新獲得 prototype 中的 foo 值?

一種是可以直接 Parent.prototype.foo 就完事了。另外一種可以通過

delete child.foo; 
console.log(child.foo); // 重新獲得 prototype 中的 foo 值

前者的缺點在于,假設(shè) foo 是個函數(shù)的話,那么 Parent.prototype.foo() 時,其中的 this 指向的是 Parent.prototype,而不是 child 實例。

很多道理都很簡單,那么再來考一下……

var slice = ___?

slice({"0": "a", "1": "b", "length": 2}) => ["a", "b"]

簡單來說就是用一個表達式定義一個變量(函數(shù)),它可以將類數(shù)組對象(比如說 arguments)轉(zhuǎn)化成數(shù)組。提示一下,數(shù)組對象的 slice 函數(shù)本身就是有這個功能的,也就是說 Array.prototype.slice.call(arguments) 可以達到要求。

DOM 事件

聽說長篇大論不會受歡迎,但是我仔細想想還是得把這部分寫下來。

事件有兩種記法,一個是

el.addEventListener("event", handler);

attachEvent 也是類似,那么在 handler 中出現(xiàn)的 this 表示觸發(fā)該事件的元素,也就是 el 。

另一種是

el.onevent = handler;

同樣,handler 中的 this 還是 el 。

最后一個題……

var o = {
  foo: function() { return this; }
}

document.onload = o.foo;

請問,當(dāng) load 事件觸發(fā)時,這里的 this 是什么?三個選擇:o, window, document.

小結(jié)

從這里開始是“廣告”時間了……

其實 this 的討論可以展開很多,可能上面記的內(nèi)容中有很多欠缺的地方,這個希望大家可以指正。

那我們的知識庫總是會隨著學(xué)習(xí)和努力慢慢擴大的,個人能力是一方面,花的精力是另一方面。只要肯靜下心去琢磨,很多“網(wǎng)上各種人說這個難那個難”的知識(比如說閉包、原型,或者和知識面廣度有關(guān)的,比如說數(shù)組中 slice 的高級用法等),花點時間總會搞懂的。

所以學(xué)習(xí)沒有捷徑,也沒有培訓(xùn)班,有心就可以了。

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

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

相關(guān)文章

  • 繼承的實現(xiàn)方式及原型概述 | JavaScript 隨筆

    摘要:每一個對象直接量都是的子類,即構(gòu)造函數(shù)中的構(gòu)造函數(shù)與普通函數(shù)并沒有什么兩樣,只不過在調(diào)用時,前面加上了關(guān)鍵字,就當(dāng)成是構(gòu)造函數(shù)了。由于沒有傳入變量,在調(diào)用的構(gòu)造函數(shù)時,會出錯這個問題可以通過一個空對象來解決改自。 showImg(https://segmentfault.com/img/bVmNZj); 對于 OO 語言,有一句話叫Everything is object,雖然 Ja...

    chenjiang3 評論0 收藏0
  • [JavaScript 隨筆] 理解嚴(yán)格相等、非嚴(yán)格相等和隱式類型轉(zhuǎn)換

    摘要:顯然,相等判斷是基于數(shù)字比較的,而條件判斷是基于布爾值。嚴(yán)格相等嚴(yán)格相等的邏輯相對簡單粗暴,如果類型不同,就不考慮隱式轉(zhuǎn)換了,直接為假。 JavaScript 中大概有這幾種 類型: undefined null string boolean number object function 之所以在 類型 上加了雙引號,是因為嚴(yán)格來說,null 的類型是 object。但本文討論的主...

    rickchen 評論0 收藏0
  • 一個JAVA WEB偽全棧的VUE入坑隨筆:從登錄開始(VUEX)

    摘要:此文章用于記錄本人學(xué)習(xí)歷程,有共同愛好者可加好友一起分享。從上周天,由于本周有公司籃球比賽,所以耽誤兩天晚上,耗時三個晚上勉強做了一個登錄功能。這里的用戶信息和登錄狀態(tài)都是直接取的中的用戶信息進行屬性值初始化。 此文章用于記錄本人VUE學(xué)習(xí)歷程,有共同愛好者可加好友一起分享。從上周天,由于本周有公司籃球比賽,所以耽誤兩天晚上,耗時三個晚上勉強做了一個登錄功能。中間的曲折只有自己知道,有...

    Zack 評論0 收藏0
  • [譯]JSX:硬幣的另一面

    摘要:它不過是硬幣的另一面。因此,既然我們能夠接受與通過這種方式混合在一塊兒,那么是時候讓介入并向我們展示硬幣的另一面了第三階段的并不是一個激進的改變,是因為我們這個行業(yè)從一開始就注定和應(yīng)該是在一起的。 React框架剛剛發(fā)布的時候,JSX顛覆了很多人的想法。習(xí)慣了HTML標(biāo)簽與JavaScript代碼分離的前端工程師們,看到JSX大概都會不禁吐槽:這些奇怪的標(biāo)簽出現(xiàn)在JavaScript里...

    mudiyouyou 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<