重學(xué)前端隨筆

學(xué)習(xí)材料是winter前輩的《重學(xué)前端》課程敏沉,記錄一下盲點(diǎn)诊沪。

類型

  • 為什么推薦用void 0代替undefined
    undefined不是關(guān)鍵字差导,此為js公認(rèn)的設(shè)計(jì)失誤之一被啼;void接任意表達(dá)式都是undefined帜消。為了防止undefined被無意篡改,推薦用void 0來獲取undefined值浓体。
    window上的undefined是無法修改的泡挺,局部變量可以修改。
  • string的最大長(zhǎng)度
    string并非表示其展示的字符串命浴,而是其UTF編碼娄猫,最大長(zhǎng)度為2^53 - 1。
    字符是以Unicode的方式表示的生闲,每一個(gè)Unicode的碼點(diǎn)表示一個(gè)字符媳溺,UTF是Unicode的編碼方式,規(guī)定了碼點(diǎn)在計(jì)算機(jī)中的表示方法碍讯,常見的有UTF16和UTF8悬蔽,可以理解為兩套字典。
    js是UTF16捉兴,所以表示為U+4位16進(jìn)制數(shù)屯阀。

絕大部分的常用字符都是4位16進(jìn)制數(shù)缅帘,也就是U+0000到U+FFFF,被稱為基本字符區(qū)域BMP难衰,這部分的碼點(diǎn)個(gè)數(shù)跟表現(xiàn)出來的字符串長(zhǎng)度是一致的。
還有剩余部分從U+010000到U+10FFFF的字符被稱為補(bǔ)充字符逗栽,也叫做代理盖袭,用兩個(gè)BMP碼點(diǎn)表示,形成一個(gè)代理對(duì)彼宠,表示一個(gè)補(bǔ)充字符鳄虱。

正常來說都是BMP,校驗(yàn)長(zhǎng)度也應(yīng)該是不需要考慮補(bǔ)充字符的凭峡。補(bǔ)充字符舉個(gè)栗子:'\uD83C\uDF03' ??拙已,長(zhǎng)度為2。
補(bǔ)充字符除了用代理對(duì)表示摧冀,還可以用String.fromCodePoint構(gòu)造倍踪,比如上面這個(gè)例子,使用0x1F303作為參數(shù)即可索昂;\u只表示BMP建车,對(duì)應(yīng)的字符構(gòu)造方法是String.fromCharCode。

  • 0.1 + 0.2 !== 0.3
    這個(gè)之前在筆記里有寫椒惨,與浮點(diǎn)數(shù)的計(jì)算方式有關(guān)缤至,這個(gè)二進(jìn)制算出來是個(gè)無限循環(huán)。
    正確的計(jì)算方式是Math.abs(0.1 + 0.2 - 0.3) <= Number.EPSILON康谆。
  • 為什么給對(duì)象添加的方法能用在基本類型上
    一開始沒太明白這句話的意思领斥,實(shí)際上說的是為什么可以像'abc'.charAt(0) (3.2).toFixed(2)這樣在基本類型上調(diào)用對(duì)象的方法。
    原因是基本類型的.操作符提供了裝箱操作沃暗,將基本類型轉(zhuǎn)為對(duì)象類型String月洛、Number、Boolean描睦、Symbol膊存,這些對(duì)象類型原型上的方法自然可以被調(diào)用。
  • 類型轉(zhuǎn)換
    ==運(yùn)算是設(shè)計(jì)失誤忱叭,關(guān)于隱式轉(zhuǎn)換規(guī)則隔崎,之前有寫過一篇JS 隱式轉(zhuǎn)換。當(dāng)時(shí)還不知道拆裝箱轉(zhuǎn)換韵丑。
    裝箱上面說了爵卒,就是從基本類型轉(zhuǎn)為對(duì)象類型,前三種都可以用new來得到撵彻。symbol有點(diǎn)特殊钓株,無法用new構(gòu)造实牡,使用Symbol構(gòu)造的是symbol基本類型。構(gòu)造Symbol對(duì)象類型可以用Object(Symbol('xxx'))來得到轴合。
    拆箱則是逆操作创坞,原理是對(duì)象的Symbol.toPrimitive方法,具體則是valueOf和toString受葛,兩者經(jīng)過后都未返回基本類型則拋出TypeError異常题涨。
    調(diào)用valueOf和toString的順序則是取決于上下文,比如
let o = {
    valueOf : () => {console.log("valueOf"); return {}},
    toString : () => {console.log("toString"); return {}}
}

o * 2
// 因?yàn)槭撬阈g(shù)運(yùn)算总滩,所以是先valueOf再toString纲堵,最后類型異常
let o = {
    valueOf : () => {console.log("valueOf"); return {}},
    toString : () => {console.log("toString"); return {}}
}

String(o)
// 字符串操作,先toString再valueOf闰渔,最后類型異常

拋出的異常都是Cannot convert object to primitive value席函,要說明一下這兩個(gè)方法的返回值,如果返回基本類型冈涧,會(huì)進(jìn)行隱式轉(zhuǎn)換茂附,返回對(duì)象類型則會(huì)再進(jìn)行拆箱轉(zhuǎn)換。當(dāng)然隱式轉(zhuǎn)換本身也包括對(duì)象類型的拆箱炕舵。
另外何之,在es6之后,還允許顯示聲明對(duì)象的Symbol.toPrimitive方法來覆蓋toString和valueOf

let o = {
    valueOf : () => {console.log("valueOf"); return {}},
    toString : () => {console.log("toString"); return {}}
}

o[Symbol.toPrimitive] = () => {console.log("toPrimitive"); return "hello"}

String(o)
// 只會(huì)調(diào)用Symbol.toPrimitive咽筋,前面兩個(gè)都沒調(diào)用溶推,打印hello
  • promise async/await
    之前在面試隨筆里寫過一些內(nèi)容,不完全正確


    面試記錄

首先await確實(shí)就是用來修飾Promise的奸攻,當(dāng)時(shí)理解并沒錯(cuò)蒜危。
另外是generator/iterator,generator/iterator并非異步代碼睹耐,只是在缺少async/await時(shí)辐赞,co利用其特性來模擬async/await;但是generator并非被設(shè)計(jì)成實(shí)現(xiàn)異步硝训,語法糖的說法只適用于co實(shí)現(xiàn)响委。

  • Completion Record類型
    此為js的標(biāo)準(zhǔn)類型,用來描述語句執(zhí)行之后的結(jié)果窖梁。它有三個(gè)字段:
  1. [[type]] 完成的類型赘风,有break、continue纵刘、return邀窃、throw和normal幾種類型;
  2. [[value]] 語句的返回值假哎,沒有則為empty;
  3. [[target]] 語句的模板,通常是一個(gè)js標(biāo)簽呀打。

type為normal的Completion Record主要有聲明類語句、表達(dá)式語句劣砍、空語句和debugger。

在try中有return語句笋轨,finally中的內(nèi)容還會(huì)執(zhí)行嗎秆剪?

會(huì)執(zhí)行,因?yàn)閒inally中的內(nèi)容必須保證執(zhí)行爵政,所以 try/catch執(zhí)行完畢,即使得到的結(jié)果是非normal型的完成記錄陶缺,也必須要執(zhí)行finally钾挟。而當(dāng)finally執(zhí)行也得到了非normal記錄,則會(huì)使finally中的記錄作為整個(gè)try結(jié)構(gòu)的結(jié)果饱岸。

至于target掺出,這個(gè)是js比較冷門的語法,帶標(biāo)簽的語句苫费。
比如聲明 defLabel: var i = 0;汤锨,大部分時(shí)候這個(gè)東西相當(dāng)于注釋,沒有任何作用百框,且不能聲明let和const闲礼;但可以跳出外層循環(huán)。

outer: while(true) {
  inner: while(true) {
      break outer;
  }
}
console.log("finished")

相當(dāng)于錨點(diǎn)铐维,指定label消費(fèi)break柬泽。(continue同理)

  • 為什么12.toString()會(huì)報(bào)錯(cuò)
    因?yàn)?2后的.會(huì)被當(dāng)成小數(shù)點(diǎn),可以12 .toString()嫁蛇,之前都是用小括號(hào)包起來的锨并。
  • 空白字符
    之前在可編輯的有序列表中提到過“隱式空白字符”,HTML代碼表示為&#8203;睬棚,其正式名稱叫做零寬字符<BOM>第煮,與其類似的還有零寬連接符<ZWJ>和零寬非連接符<ZWNJ>,用Unicode表示依次為\uFEFF \u200D \u200C抑党。
  • 不寫行尾分號(hào)可能引起的問題
    先說原理:自動(dòng)補(bǔ)分號(hào)的條件有一條是“此處有換行符包警,但語法規(guī)定此處不能有換行符”,但js中有no LineTerminator here 規(guī)則新荤,即不能插入換行揽趾。
    記幾條比較少見的:
  1. 后自增/自減前
  2. async、yield
  3. 箭頭函數(shù)的箭頭前

回到問題苛骨,不寫分號(hào)可能引起的幾種情況:

(function(a){
    console.log(a);
})()/*這里沒有被自動(dòng)插入分號(hào)*/
(function(a){
    console.log(a);
})()

比較好理解篱瞎,第二個(gè)自執(zhí)行當(dāng)成了上面的鏈?zhǔn)秸{(diào)用參數(shù)苟呐。

var a = [[]]/*這里沒有被自動(dòng)插入分號(hào)*/
[3, 2, 1, 0].forEach(e => console.log(e))

說明一下,這里能連上而且不會(huì)報(bào)錯(cuò)俐筋。
會(huì)看做是數(shù)組用中括號(hào)取值牵素,3,2,1,0當(dāng)做表達(dá)式,返回0澄者,結(jié)果就是[].forEach笆呆,不會(huì)報(bào)錯(cuò)。

var x = 1, g = {test:()=>0}, b = 1/*這里沒有被自動(dòng)插入分號(hào)*/
/(a)/g.test("abc")
console.log(RegExp.$1)

正則的/當(dāng)成了除號(hào)粱挡。

var f = function(){
  return "";
}
var g = f/*這里沒有被自動(dòng)插入分號(hào)*/
`Template`.match(/(a)/);
console.log(RegExp.$1)

模板字符串特性赠幕,可以跟在函數(shù)后面當(dāng)成參數(shù)。
這些都是不滿足no LineTerminator here 規(guī)則的询筏,所以不會(huì)在行尾加分號(hào)榕堰。

  • 預(yù)處理
    var變量提升的原理,有段反常識(shí)的代碼
var a = 1;
function foo() {
    var o= {a:3}
    with(o) {
        var a = 2;
    }
    console.log(o.a);
    console.log(a);
}
foo();

foo內(nèi)嫌套,a聲明提到首行逆屡,with(o)修改a時(shí)不影響外部a的賦值,所以o.a為2踱讨,a為undefined魏蔗。

  • 指令序言(Directive Prologs)
    js中規(guī)定的唯一指令序言是"use strict";
  • 乘方表達(dá)式
    -2 ** 2會(huì)報(bào)錯(cuò),一元表達(dá)式不能放入乘方表達(dá)式痹筛;乘方表達(dá)式是右結(jié)合的莺治。
  • 為什么沒有“父選擇器”
    因?yàn)闉g覽器構(gòu)建DOM樹的順序是父-子,當(dāng)解析到一個(gè)dom時(shí)就應(yīng)該完全得到其樣式信息味混,而不是還要依賴未被構(gòu)建的子節(jié)點(diǎn)來判斷是否選中产雹,所以不會(huì)出現(xiàn)“父選擇器”。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末翁锡,一起剝皮案震驚了整個(gè)濱河市蔓挖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌馆衔,老刑警劉巖瘟判,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異角溃,居然都是意外死亡拷获,警方通過查閱死者的電腦和手機(jī)减细,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人茧妒,你說我怎么就攤上這事∽蠖” “怎么了桐筏?”我有些...
    開封第一講書人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵拇砰,是天一觀的道長(zhǎng)梅忌。 經(jīng)常有香客問我除破,道長(zhǎng)牧氮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任瑰枫,我火速辦了婚禮蹋笼,結(jié)果婚禮上躁垛,老公的妹妹穿的比我還像新娘圾笨。我一直安慰自己,他們只是感情好擂达,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著悲敷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪后德。 梳的紋絲不亂的頭發(fā)上抄腔,一...
    開封第一講書人閱讀 51,231評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音赫蛇,去河邊找鬼。 笑死落蝙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的筏勒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼起意,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼病瞳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起套菜,我...
    開封第一講書人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤亲善,失蹤者是張志新(化名)和其女友劉穎逗柴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體戏溺,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年耕拷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了托享。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡赃绊,死狀恐怖羡榴,靈堂內(nèi)的尸體忽然破棺而出碧查,到底是詐尸還是另有隱情炕矮,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布档痪,位于F島的核電站邢滑,受9級(jí)特大地震影響愿汰,放射性物質(zhì)發(fā)生泄漏乐纸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一汽绢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧跌宛,春花似錦、人聲如沸疆拘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隆圆。三九已至,卻和暖如春棱烂,著一層夾襖步出監(jiān)牢的瞬間阶女,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工秃踩, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留业筏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓消别,卻偏偏與公主長(zhǎng)得像台谢,于是被迫代替她去往敵國(guó)和親寻狂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子朋沮,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

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