JavaScript 知識框架一

JS目錄

給 JavaScript 做一個(gè)頂層目錄盲赊,可這樣劃分:文法碟渺、語義叔扼、運(yùn)行時(shí)
再細(xì)分為:


建立知識框架

兩個(gè)目標(biāo):一是理解原理和背景,二是把不方便查閱和記憶的內(nèi)容整理好
前端知識在總體上分成基礎(chǔ)部分和實(shí)踐部分
基礎(chǔ)部分包含3大塊: JS語言狈定、CSS 及 HTML颂龙、瀏覽器的實(shí)現(xiàn)原理及API

一、類型

JS分7 種類型是:

Undefined掸冤;Null厘托;Boolean友雳;String稿湿;Number;Symbol押赊;Object
Undefined與null

Undefined 類型表示未定義饺藤,它的類型只有一個(gè)值包斑,就是 undefined。任何變量在賦值前是 Undefined 類型涕俗、值為 undefined
編程規(guī)范要求用 void 0 代替 undefined罗丰,因?yàn)椋篔S 的代碼 undefined 是一個(gè)變量,而并非是一個(gè)關(guān)鍵字再姑,這是 js 語言公認(rèn)的設(shè)計(jì)失誤之一萌抵,所以,為了避免無意中被篡改元镀,建議用 void 0 來獲取 undefined 值
Undefined 跟 Null 有一定的表意差別绍填,Null 表示的是:“定義了但是為空”。
Null與 undefined 不同栖疑,null 是 JavaScript 關(guān)鍵字讨永,所以在任何代碼中,你都可以放心用 null 關(guān)鍵字來獲取 null 值遇革。

String

String 用于表示文本數(shù)據(jù)卿闹。String 有最大長度是 2^53 - 1。
String 的意義并非“字符串”萝快,而是字符串的 UTF16 編碼
字符串的操作 charAt锻霎、charCodeAt、length 等方法針對的都是 UTF16 編碼杠巡。所以量窘,字符串的最大長度,實(shí)際上是受字符串的編碼長度影響的氢拥。
JavaScript 中的字符串是永遠(yuǎn)無法變更的蚌铜,一旦字符串構(gòu)造出來,無法用任何方式改變字符串的內(nèi)容嫩海,所以字符串具有值類型的特征冬殃。

Number

JavaScript 為了表達(dá)幾個(gè)額外的語言場景(比如不讓除以 0 出錯(cuò),而引入了無窮大的概念)

規(guī)定了幾個(gè)例外情況:
NaN叁怪,占用了 9007199254740990审葬,它不是個(gè)數(shù)字
Infinity,無窮大奕谭;
-Infinity涣觉,負(fù)無窮大。

Symbol

Symbol 是 ES6 中引入的新類型血柳,它是一切非字符串的對象 key 的集合
在 ES6 規(guī)范中官册,整個(gè)對象系統(tǒng)被用 Symbol 重塑。
我們創(chuàng)建 Symbol 的方式是使用全局的 Symbol 函數(shù)难捌。
例如: var mySymbol = Symbol("my symbol");

Object

Object 的定義是“屬性的集合”膝宁。屬性分為數(shù)據(jù)屬性和訪問器屬性鸦难,二者都是 key-value 結(jié)構(gòu),key 可以是字符串或者 Symbol 類型员淫。
我們必須認(rèn)識到 3 與 new Number(3) 是完全不同的值合蔽,它們一個(gè)是 Number 類型, 一個(gè)是對象類型介返。
因?yàn)?C++ 和 Java 的成功拴事,在這兩門語言中,每個(gè)類都是一個(gè)類型圣蝎,二者幾乎等同挤聘,以至于很多人常常會把 JavaScript 的“類”與類型混淆。
Number捅彻、String 和 Boolean组去,三個(gè)構(gòu)造器是兩用的,當(dāng)跟 new 搭配時(shí)步淹,它們產(chǎn)生對象从隆,當(dāng)直接調(diào)用時(shí),它們表示強(qiáng)制類型轉(zhuǎn)換缭裆。
Symbol 函數(shù)比較特殊键闺,直接用 new 調(diào)用它會拋出錯(cuò)誤,但它仍然是 Symbol 對象的構(gòu)造器澈驼。

JavaScript 中的“類”僅僅是運(yùn)行時(shí)對象的一個(gè)私有屬性辛燥,而 JavaScript 中是無法自定義類型的。
JS 語言設(shè)計(jì)上試圖模糊對象和基本類型之間的關(guān)系缝其,可以把對象的方法在基本類型上使用
比如: console.log("abc".charAt(0)); //a
其原理是挎塌,. 點(diǎn)運(yùn)算符提供了裝箱操作,它會根據(jù)基礎(chǔ)類型構(gòu)造一個(gè)臨時(shí)對象内边,能在基礎(chǔ)類型上調(diào)用對應(yīng)對象的方法

二榴都、裝箱、拆箱

前文提到漠其,全局的 Symbol 函數(shù)無法使用 new 來調(diào)用嘴高,但我們?nèi)钥梢岳醚b箱機(jī)制來得到一個(gè) Symbol 對象,我們可以利用一個(gè)函數(shù)的 call 方法來強(qiáng)迫產(chǎn)生裝箱和屎。

var symbolObject = (function(){ return this; }).call(Symbol("a"));

使用內(nèi)置的 Object 函數(shù)拴驮,我們可以在 JS 中顯式調(diào)用裝箱能力

var symbolObject = Object(Symbol("a")); 
console.log(typeof symbolObject); //object

拆箱轉(zhuǎn)換
拆箱轉(zhuǎn)換,它是對象類型到基本類型的轉(zhuǎn)換柴信。
會嘗試調(diào)用 valueOf 和 toString 來獲得拆箱后的基本類型套啤。如果 valueOf 和 toString 都不存在,或者沒有返回基本類型颠印,則會產(chǎn)生類型錯(cuò)誤 TypeError纲岭。
在 ES6 之后,還允許對象通過顯式指定 Symbol.toPrimitive 來覆蓋原有的行為(用這方法就不會執(zhí)行valueOf和toString方法)


三线罕、對象屬性:

對象屬性分為:數(shù)據(jù)屬性止潮、訪問器屬性
數(shù)據(jù)屬性:它比較接近于其它語言的屬性概念,具有四個(gè)特征

value:就是屬性的值钞楼。
writable:決定屬性能否被賦值喇闸。
enumerable:決定 for in 能否枚舉該屬性。
configurable:決定該屬性能否被刪除或者改變特征值询件。

在大多數(shù)情況下燃乍,我們只關(guān)心數(shù)據(jù)屬性的值即可

訪問器屬性:
屬性在讀和寫時(shí)執(zhí)行,它允許使用者在寫和讀屬性時(shí)宛琅,得到完全不同的值刻蟹,可視為一種函數(shù)的語法糖

getter:函數(shù)或 undefined,在取屬性值時(shí)被調(diào)用嘿辟。
setter:函數(shù)或 undefined舆瘪,在設(shè)置屬性值時(shí)被調(diào)用。
enumerable:決定 for in 能否枚舉該屬性红伦。
configurable:決定該屬性能否被刪除或者改變特征值英古。
對象分類

1、宿主對象(host Objects):由 JavaScript 宿主環(huán)境提供的對象昙读,它們的行為完全由宿主環(huán)境決定召调。
2、內(nèi)置對象(Built-in Objects):由 JavaScript 語言提供的對象蛮浑。

  • 2.1唠叛、固有對象(Intrinsic Objects ):由標(biāo)準(zhǔn)規(guī)定,隨著 JavaScript 運(yùn)行時(shí)創(chuàng)建而自動創(chuàng)建的對象實(shí)例沮稚。
  • 2.2玻墅、原生對象(Native Objects):可以由用戶通過 Array、RegExp 等內(nèi)置構(gòu)造器或者特殊語法創(chuàng)建的對象壮虫。
  • 2.3澳厢、普通對象(Ordinary Objects):由{}語法、Object 構(gòu)造器或者 class 關(guān)鍵字定義類創(chuàng)建的對象囚似,它能夠被原型繼承剩拢。

宿主對象,分為固有宿主的和用戶可創(chuàng)建的宿主兩種
固有宿主如:window
用戶創(chuàng)建宿主如: document.createElement 就可以創(chuàng)建一些 DOM 對象

固有對象饶唤,在任何 JavaScript 代碼執(zhí)行前就已經(jīng)被創(chuàng)建出來了徐伐,它們通常扮演者類似基礎(chǔ)庫的角色

三個(gè)值:Infinity、NaN募狂、undefined
九個(gè)函數(shù):eval办素、isFinite角雷、isNaN、parseFloat性穿、parselnt勺三、decodeURl、decodeURIComponent需曾、encodeURI吗坚、encodeURlComponent
構(gòu)造器:Array、Date呆万、RegExp商源、Promise、Proxy谋减、Map牡彻、WeakMap、Set出爹、WeakSet讨便、Function、Boolean以政、String霸褒、Number、Symbol盈蛮、Object废菱、Error、EvalError....
四個(gè)用于當(dāng)作命名空間的對象:Atomics抖誉、JSON殊轴、Math、Reflect

原生對象袒炉,分成以下類:

JavaScript 用對象模擬函數(shù)的設(shè)計(jì)代替了一般編程語言中的函數(shù)旁理,它們可以像其它語言的函數(shù)一樣被調(diào)用、傳參我磁。
任何對象只需要實(shí)現(xiàn)[[call]]孽文,它就是一個(gè)函數(shù)對象,可以去作為函數(shù)被調(diào)用夺艰。而如果它能實(shí)現(xiàn)[[construct]]芋哭,它就是一個(gè)構(gòu)造器對象,可以作為構(gòu)造器被調(diào)用郁副。
用戶用 function 關(guān)鍵字創(chuàng)建的函數(shù)必定同時(shí)是函數(shù)和構(gòu)造器减牺,但它們表現(xiàn)出來的行為效果卻并不相同。


JS 的執(zhí)行

Promise:是 JavaScript 語言提供的一種標(biāo)準(zhǔn)化的異步管理方式,它的總體思想是拔疚,需要進(jìn)行 io肥隆、等待或者其它異步操作的函數(shù),不返回真實(shí)結(jié)果稚失,而返回一個(gè)“承諾”栋艳,函數(shù)的調(diào)用方可以在合適的時(shí)機(jī),選擇等待這個(gè)承諾兌現(xiàn)(通過 Promise 的 then 方法的回調(diào))

var r = new Promise(function(resolve, reject){ 
    console.log("a"); 
    resolve() 
}); 
setTimeout(()=>console.log("d"), 0)  //0秒的setTimeout
r.then(() => console.log("c"));  
console.log("b")

打印順序是abcd墩虹,不論代碼順序如何,d 必定發(fā)生在 c 之后憨琳,哪怕Promise返回需要3秒诫钓,也仍然是先c后d。
因?yàn)?Promise 產(chǎn)生的是 JavaScript 引擎內(nèi)部的微任務(wù)篙螟,而 setTimeout 是瀏覽器 API菌湃,它產(chǎn)生宏任務(wù)。

generator/iterator 也常常被跟異步一起來講遍略,但它們并非異步代碼惧所,只是在缺少 async/await 的時(shí)候,一些框架使用這樣的特性來模擬 async/await绪杏。但是 generator 并非被設(shè)計(jì)成實(shí)現(xiàn)異步下愈,所以有了 async/await 之后,generator/iterator 就不應(yīng)用來模擬異步的方法蕾久,只用于迭代器势似。

通常把宿主發(fā)起的任務(wù)稱為宏觀任務(wù),JS引擎發(fā)起的任務(wù)稱為微觀任務(wù)
Promise 產(chǎn)生異步代碼僧著,JS保證這些異步代碼在一個(gè)宏觀任務(wù)中完成 (每個(gè)宏觀任務(wù)包含1個(gè)微觀任務(wù)隊(duì)列)
異步執(zhí)行的順序:
1履因、首先我們分析有多少個(gè)宏任務(wù);
2盹愚、在每個(gè)宏任務(wù)中栅迄,分析有多少個(gè)微任務(wù);
3皆怕、根據(jù)調(diào)用次序毅舆,確定宏任務(wù)中的微任務(wù)執(zhí)行次序;
4愈腾、根據(jù)宏任務(wù)的觸發(fā)規(guī)則和調(diào)用次序朗兵,確定宏任務(wù)的執(zhí)行次序;
5顶滩、確定整個(gè)順序


在只有 var余掖,沒有 let 的舊 JavaScript 時(shí)代,誕生了一個(gè)技巧,叫做:立即執(zhí)行的函數(shù)表達(dá)式(IIFE)盐欺,通過創(chuàng)建一個(gè)函數(shù)赁豆,并且立即執(zhí)行,來構(gòu)造一個(gè)新的域冗美,從而控制 var 的范圍魔种。

(function(){ 
  var a;
}());
或者
(function(){ 
  var a; 
})();
推薦用法:
void function(){
 var a; 
}();

有了let,就不需要用這種立即執(zhí)行函數(shù)了

執(zhí)行上下文

一旦上下文被切換粉洼,整個(gè)語句的效果可能都會發(fā)生改變节预。所以切換上下文的時(shí)機(jī)就顯得非常重要。切換上下文最主要的場景是函數(shù)調(diào)用属韧。

1安拟、看個(gè)簡單的切換上下文代碼:

//a.js
var a = 1;
function foo(){ 
  console.log(a); 
  console.log(b);  
}

//b.js
引入a.js
var b = 2;
foo();    //這里就是切換上下文
foo打印a 為1,打印b 報(bào)錯(cuò)

看以下的這段 JS代碼:

var b = {}
let c = 1
this.a = 2; 
//1宵喂、var 把 b 聲明到哪里糠赦;
//2、b 表示哪個(gè)變量锅棕;
//3拙泽、b 的原型是哪個(gè)對象慷垮;
//4钾恢、let 把 c 聲明到哪里耸棒;
//5攻旦、this 指向哪個(gè)對象

2啃擦、回答上面的問題忱叭,先從理解this關(guān)鍵字開始
this 是執(zhí)行上下文中很重要的一個(gè)組成部分澄阳。同一個(gè)函數(shù)調(diào)用方式不同斗遏,得到的 this 值也不同
this 跟面向?qū)ο蠛翢o關(guān)聯(lián)脆炎,它是與函數(shù)調(diào)用時(shí)使用的表達(dá)式相關(guān)

普通函數(shù)的 this 值由 ‘ 調(diào)用它所使用的引用 ’ 決定梅猿,下面示例

function showThis(){
  console.log(this);
}
var o = { 
  x:2,
  showThis: showThis
}
showThis(); // global
o.showThis(); // Reference 類型 o   //{ x: 2, showThis: [Function: showThis] } 

注意:上面獲取函數(shù)的表達(dá)式,它返回的并非函數(shù)本身秒裕,而是一個(gè) Reference 類型
Reference 類型由兩部分組成:一個(gè)對象和一個(gè)屬性值
上面代碼中 o.showThis 產(chǎn)生的 Reference 類型袱蚓,即由對象 o 和屬性“showThis”構(gòu)成

3、JavaScript 用一個(gè)棧來管理執(zhí)行上下文几蜻,這個(gè)棧中的每一項(xiàng)又包含一個(gè)鏈表喇潘。如下圖所示:



當(dāng)函數(shù)調(diào)用時(shí),會入棧一個(gè)新的執(zhí)行上下文梭稚,函數(shù)調(diào)用結(jié)束時(shí)颖低,執(zhí)行上下文被出棧。
而 this 則是一個(gè)更為復(fù)雜的機(jī)制

4弧烤、操作 this 的內(nèi)置函數(shù)
Function.prototype.call 和 Function.prototype.apply 可以指定函數(shù)調(diào)用時(shí)傳入的 this 值

function foo(a, b, c) {
  console.log(this)
  console.log(a, b, c)
}
foo(1, 2, 3) //this為 global
foo.call({}, 1, 2, 3) //this為{}
foo.apply({}, [1, 2, 3]) //this為{}
call 和 apply 作用是一樣的忱屑,只是傳參方式有區(qū)別

來源: winter 老師的 重學(xué)前端

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子莺戒,更是在濱河造成了極大的恐慌伴嗡,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件从铲,死亡現(xiàn)場離奇詭異瘪校,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)名段,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進(jìn)店門阱扬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伸辟,你說我怎么就攤上這事麻惶。” “怎么了自娩?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵用踩,是天一觀的道長渠退。 經(jīng)常有香客問我忙迁,道長,這世上最難降的妖魔是什么碎乃? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任姊扔,我火速辦了婚禮,結(jié)果婚禮上梅誓,老公的妹妹穿的比我還像新娘恰梢。我一直安慰自己,他們只是感情好梗掰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布嵌言。 她就那樣靜靜地躺著,像睡著了一般及穗。 火紅的嫁衣襯著肌膚如雪摧茴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天埂陆,我揣著相機(jī)與錄音苛白,去河邊找鬼。 笑死焚虱,一個(gè)胖子當(dāng)著我的面吹牛购裙,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播鹃栽,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼躏率,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起禾锤,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤私股,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后恩掷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體倡鲸,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年黄娘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了峭状。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,977評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡逼争,死狀恐怖优床,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情誓焦,我是刑警寧澤胆敞,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站杂伟,受9級特大地震影響移层,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜赫粥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一观话、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧越平,春花似錦频蛔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至挣跋,卻和暖如春三圆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浆劲。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工嫌术, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牌借。 一個(gè)月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓度气,卻偏偏與公主長得像,于是被迫代替她去往敵國和親膨报。 傳聞我的和親對象是個(gè)殘疾皇子磷籍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容