摘要:關(guān)于中的坑大家都踩過。那這里的和是嚴(yán)格相等的。這里介紹的是通過創(chuàng)建對(duì)象時(shí)的。提示一下,數(shù)組對(duì)象的函數(shù)本身就是有這個(gè)功能的,也就是說可以達(dá)到要求。事件有兩種記法,一個(gè)是也是類似,那么在中出現(xiàn)的表示觸發(fā)該事件的元素,也就是。
TL;DR: this 指向調(diào)用該方法的對(duì)象,只有函數(shù)執(zhí)行時(shí),this 才有定義。
關(guān)于 JavaScript 中 this 的坑大家都踩過。像本文開頭的這句話,道理你都懂,但是……所以這里就總結(jié)了幾個(gè) this 最常用的使用場(chǎng)景。
全局環(huán)境在瀏覽器的全局環(huán)境中,this === window 。
但是,當(dāng)使用了 "use strict"; 進(jìn)入嚴(yán)格模式時(shí),this === undefined 。
如果是在 nodejs 環(huán)境中,全局對(duì)象會(huì)更復(fù)雜一些,因?yàn)樗袃煞N執(zhí)行方式。一個(gè)是命令行方式,即輸入
$ node
進(jìn)入類似于瀏覽器的控制臺(tái)一樣的界面,可以逐行執(zhí)行代碼。那這里的 this 和 global 是嚴(yán)格相等的。但如果是
$ node program.js
這樣執(zhí)行一個(gè)文件的話,nodejs 會(huì)為每個(gè)文件創(chuàng)建一個(gè)自執(zhí)行匿名函數(shù)的塊,這里面的 this 并不是全局對(duì)象 global 。但是,如果聲明變量時(shí)沒有加 var 的話,這些變量還是會(huì)加到 global 上去。
函數(shù)調(diào)用函數(shù)中的 this 可能更常見一點(diǎn)吧。
function foo() { console.log(this.name); }
如果直接判斷這里的 this 是全局對(duì)象的話,就太沖動(dòng)了(還記得最開始這句話嗎?只有當(dāng)函數(shù)調(diào)用時(shí)才能判斷 this 真正引用的對(duì)象是什么)。
如果它作為一個(gè)全局函數(shù)【foo()】,或者閉包【return foo;】,又或者是回調(diào)函數(shù)【other(foo)】的話,那么它在執(zhí)行時(shí)就是全局對(duì)象了。
還有三個(gè)我們經(jīng)常遇到的方法可以改變 this 的引用,就是 call、apply 和 bind 。
foo.call(thisArg);
那么這里的 this 就指向了 thisArg,但當(dāng)它為 null 或者 undefined,this 會(huì)指向全局對(duì)象。
還有一種函數(shù)調(diào)用是使用 new 關(guān)鍵字。
new foo();
這里的 this 指向的是構(gòu)造出來的新對(duì)象。
那么其他情況就必然是 x.foo() 類似的調(diào)用方式了,看到這條語句的時(shí)候再去看 foo 的定義,它里面 this 引用的就是對(duì)象 x 。
數(shù)學(xué)學(xué)得好的話,可以反應(yīng)過來 x 可以表示任何對(duì)象,比如 a,a.b,或者其他更復(fù)雜的表達(dá)式。
好,來測(cè)試一下,有如下代碼
var o = { foo: function() { return this; } }; function bar() { return o.foo; } console.log(bar()());
結(jié)果是什么?反正就兩個(gè)選擇,一是 this 指向全局對(duì)象,二是指向 o 。
原型在上一篇文章 《繼承的實(shí)現(xiàn)方式及原型概述》 中其實(shí)有提到過一部分原型方面的知識(shí),那這里就稍微深入一點(diǎn)。
這里介紹的是通過 new 創(chuàng)建對(duì)象時(shí)的 this 。每個(gè)函數(shù)對(duì)象(用 function 關(guān)鍵字修飾的變量)自帶 prototype 屬性,在 prototype 上定義的屬性都會(huì)繼承給 this 。這些屬性被每個(gè)實(shí)例共享,實(shí)例中會(huì)創(chuàng)建所有 prototype 上的屬性,值為這些屬性的引用。
文字一多心里難免煩煩的……
首先,這里通過 new 創(chuàng)建了兩個(gè)實(shí)例,它們有相同的 prototype 。原型中的數(shù)據(jù)是創(chuàng)建在堆上的,所以繼承下來的屬性和方法都會(huì)指向同一個(gè)引用(左邊的箭頭)。
然后,在 this 上定義的屬性和方法是創(chuàng)建在棧上的,所以這些屬性和方法會(huì)有各自獨(dú)立的內(nèi)存區(qū)域(右邊的箭頭)。
假如在 this 上定義的變量與 prototype 上沖突了,那么 prototype 中的那個(gè)變量會(huì)“隱藏”起來。
如果有 child.foo = "tom"; 那么思考一下怎樣才能讓 child.foo 重新獲得 prototype 中的 foo 值?
一種是可以直接 Parent.prototype.foo 就完事了。另外一種可以通過
delete child.foo; console.log(child.foo); // 重新獲得 prototype 中的 foo 值
前者的缺點(diǎn)在于,假設(shè) foo 是個(gè)函數(shù)的話,那么 Parent.prototype.foo() 時(shí),其中的 this 指向的是 Parent.prototype,而不是 child 實(shí)例。
很多道理都很簡單,那么再來考一下……
var slice = ___? slice({"0": "a", "1": "b", "length": 2}) => ["a", "b"]
簡單來說就是用一個(gè)表達(dá)式定義一個(gè)變量(函數(shù)),它可以將類數(shù)組對(duì)象(比如說 arguments)轉(zhuǎn)化成數(shù)組。提示一下,數(shù)組對(duì)象的 slice 函數(shù)本身就是有這個(gè)功能的,也就是說 Array.prototype.slice.call(arguments) 可以達(dá)到要求。
DOM 事件聽說長篇大論不會(huì)受歡迎,但是我仔細(xì)想想還是得把這部分寫下來。
事件有兩種記法,一個(gè)是
el.addEventListener("event", handler);
attachEvent 也是類似,那么在 handler 中出現(xiàn)的 this 表示觸發(fā)該事件的元素,也就是 el 。
另一種是
el.onevent = handler;
同樣,handler 中的 this 還是 el 。
最后一個(gè)題……
var o = { foo: function() { return this; } } document.onload = o.foo;
請(qǐng)問,當(dāng) load 事件觸發(fā)時(shí),這里的 this 是什么?三個(gè)選擇:o, window, document.
小結(jié)從這里開始是“廣告”時(shí)間了……
其實(shí) this 的討論可以展開很多,可能上面記的內(nèi)容中有很多欠缺的地方,這個(gè)希望大家可以指正。
那我們的知識(shí)庫總是會(huì)隨著學(xué)習(xí)和努力慢慢擴(kuò)大的,個(gè)人能力是一方面,花的精力是另一方面。只要肯靜下心去琢磨,很多“網(wǎng)上各種人說這個(gè)難那個(gè)難”的知識(shí)(比如說閉包、原型,或者和知識(shí)面廣度有關(guān)的,比如說數(shù)組中 slice 的高級(jí)用法等),花點(diǎn)時(shí)間總會(huì)搞懂的。
所以學(xué)習(xí)沒有捷徑,也沒有培訓(xùn)班,有心就可以了。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/85839.html
摘要:每一個(gè)對(duì)象直接量都是的子類,即構(gòu)造函數(shù)中的構(gòu)造函數(shù)與普通函數(shù)并沒有什么兩樣,只不過在調(diào)用時(shí),前面加上了關(guān)鍵字,就當(dāng)成是構(gòu)造函數(shù)了。由于沒有傳入變量,在調(diào)用的構(gòu)造函數(shù)時(shí),會(huì)出錯(cuò)這個(gè)問題可以通過一個(gè)空對(duì)象來解決改自。 showImg(https://segmentfault.com/img/bVmNZj); 對(duì)于 OO 語言,有一句話叫Everything is object,雖然 Ja...
摘要:顯然,相等判斷是基于數(shù)字比較的,而條件判斷是基于布爾值。嚴(yán)格相等嚴(yán)格相等的邏輯相對(duì)簡單粗暴,如果類型不同,就不考慮隱式轉(zhuǎn)換了,直接為假。 JavaScript 中大概有這幾種 類型: undefined null string boolean number object function 之所以在 類型 上加了雙引號(hào),是因?yàn)閲?yán)格來說,null 的類型是 object。但本文討論的主...
摘要:此文章用于記錄本人學(xué)習(xí)歷程,有共同愛好者可加好友一起分享。從上周天,由于本周有公司籃球比賽,所以耽誤兩天晚上,耗時(shí)三個(gè)晚上勉強(qiáng)做了一個(gè)登錄功能。這里的用戶信息和登錄狀態(tài)都是直接取的中的用戶信息進(jìn)行屬性值初始化。 此文章用于記錄本人VUE學(xué)習(xí)歷程,有共同愛好者可加好友一起分享。從上周天,由于本周有公司籃球比賽,所以耽誤兩天晚上,耗時(shí)三個(gè)晚上勉強(qiáng)做了一個(gè)登錄功能。中間的曲折只有自己知道,有...
摘要:它不過是硬幣的另一面。因此,既然我們能夠接受與通過這種方式混合在一塊兒,那么是時(shí)候讓介入并向我們展示硬幣的另一面了第三階段的并不是一個(gè)激進(jìn)的改變,是因?yàn)槲覀冞@個(gè)行業(yè)從一開始就注定和應(yīng)該是在一起的。 React框架剛剛發(fā)布的時(shí)候,JSX顛覆了很多人的想法。習(xí)慣了HTML標(biāo)簽與JavaScript代碼分離的前端工程師們,看到JSX大概都會(huì)不禁吐槽:這些奇怪的標(biāo)簽出現(xiàn)在JavaScript里...
摘要:系列種優(yōu)化頁面加載速度的方法隨筆分類中個(gè)最重要的技術(shù)點(diǎn)常用整理網(wǎng)頁性能管理詳解離線緩存簡介系列編寫高性能有趣的原生數(shù)組函數(shù)數(shù)據(jù)訪問性能優(yōu)化方案實(shí)現(xiàn)的大排序算法一怪對(duì)象常用方法函數(shù)收集數(shù)組的操作面向?qū)ο蠛驮屠^承中關(guān)鍵詞的優(yōu)雅解釋淺談系列 H5系列 10種優(yōu)化頁面加載速度的方法 隨筆分類 - HTML5 HTML5中40個(gè)最重要的技術(shù)點(diǎn) 常用meta整理 網(wǎng)頁性能管理詳解 HTML5 ...
閱讀 1074·2021-11-19 09:40
閱讀 2213·2021-11-15 18:00
閱讀 1267·2021-10-18 13:34
閱讀 2248·2021-09-02 15:40
閱讀 1533·2019-08-30 14:01
閱讀 1113·2019-08-30 11:11
閱讀 2482·2019-08-29 15:26
閱讀 722·2019-08-29 14:15