You Dont Know JS(上)筆記

最近項(xiàng)目产喉,一直在研究使用新的框架捂掰,新的工具,結(jié)果發(fā)現(xiàn)學(xué)習(xí)的速度還沒(méi)有輪子出現(xiàn)的速度快曾沈,就拿webpack來(lái)說(shuō)这嚣,1.0都還沒(méi)有掌握,2.0就出來(lái)了塞俱,無(wú)力感突現(xiàn)姐帚,一直在跟隨著別人的腳步在前進(jìn),都沒(méi)有自己的東西敛腌,所以內(nèi)功才是一切卧土,內(nèi)功強(qiáng)大,自己寫(xiě)一個(gè)框架像樊,也不是不可尤莺。不然你連人家的源碼都不懂,只會(huì)用又有什么用呢生棍,明天換一個(gè)框架颤霎,或者換一個(gè)公司,你又要從頭開(kāi)始涂滴,你的競(jìng)爭(zhēng)力又在何方友酱。

  • 作用域

1,LHS(賦值操作)和RHS(取值操作)查詢都會(huì)在當(dāng)前執(zhí)行作用域開(kāi)始柔纵,如果沒(méi)有找到缔杉,就會(huì)向上級(jí)作用域繼續(xù)查找目標(biāo)標(biāo)識(shí)符,這樣每次上升一級(jí)搁料,最后抵達(dá)全局作用域或详。
2系羞,不成功的RHS引用會(huì)拋出ReferenceError異常,不成功的LHS引用會(huì)導(dǎo)致自動(dòng)隱式的創(chuàng)建全局變量(非嚴(yán)格模式下)霸琴,或者拋出ReferenceError異常(嚴(yán)格模式下)
  • 詞法作用域##

詞法作用域完全由寫(xiě)代碼期間函數(shù)聲明的位置來(lái)定義

function foo(a) {
    var b = a * 2;
    function bar(c) {
        console.log( a, b, c );
    }

    bar(b * 3);
}
foo( 2 ); // 2 4 12

對(duì)于console而言椒振,會(huì)先查找最內(nèi)部的作用域,引擎在這里無(wú)法找到a,因此就會(huì)去上一層作用域中查找梧乘。作用域查找會(huì)在找到第一個(gè)匹配的標(biāo)識(shí)符時(shí)停止澎迎,所以在多層嵌套的作用域中可以定義同名的標(biāo)識(shí)符,這叫做遮蔽效應(yīng)(內(nèi)部的標(biāo)識(shí)符遮蔽了外部的標(biāo)識(shí)符)

function foo(str, a) {
    eval( str ); // 欺騙!选调,在運(yùn)行時(shí)就相當(dāng)于var b= 3,遮蔽了外部的b
    // 但是在嚴(yán)格模式下夹供,eval運(yùn)行時(shí),有自己的作用域学歧,無(wú)法修改所在的作用域
    console.log( a, b );
}
var b = 2;
foo( "var b = 3;", 1 ); // 1 3
function foo(obj) {
    with (obj) {
        a = 2;
    }
}
var o1 = {
    a: 3
};
var o2 = {
    b: 3
};
foo( o1 );
console.log( o1.a ); // 2
foo( o2 );
console.log( o2.a ); // undefined
console.log( a ); // 2 -- 不好罩引,a被泄露到全局作用域上了!
//當(dāng)我們傳遞o1給with時(shí),with所聲明的作用域是o1,而這個(gè)作用域中含有一個(gè)相符的標(biāo)識(shí)符枝笨,但是我們將o2作為作用域時(shí)袁铐,其中并沒(méi)有a標(biāo)識(shí)符,因此進(jìn)行了正常的LHS查找

使用eval和with可以欺騙詞法作用域横浑,但是會(huì)導(dǎo)致性能的下降剔桨,所以不要使用,同時(shí)因?yàn)閖s引擎會(huì)在編譯階段進(jìn)行數(shù)項(xiàng)的優(yōu)化徙融,但是對(duì)于未知的代碼時(shí)優(yōu)化不了的

  • 函數(shù)作用域和塊作用域

1洒缀,在軟件設(shè)計(jì)中,應(yīng)該最小限度的暴露必要內(nèi)容欺冀,而將其他的內(nèi)容都隱藏起來(lái)树绩,比如某個(gè)模塊或?qū)ο蟮腁PI,
2隐轩,(function(){})()和(function(){}())是一樣的東西饺饭,都叫做立即執(zhí)行函數(shù)表達(dá)式(IIFE),看個(gè)人習(xí)慣,
3,在try/catch的catch分局中會(huì)創(chuàng)建一個(gè)作用域
4,
  • 提升

1职车,js存在預(yù)編譯階段瘫俊,此時(shí)會(huì)將函數(shù)聲明和變量提升,并且函數(shù)會(huì)在變量之前悴灵,同事若是重復(fù)的聲明將會(huì)忽略
  • 閉包

1,無(wú)論通過(guò)何種手段將內(nèi)部函數(shù)傳遞到所在的詞法作用域以外扛芽,他都會(huì)持有對(duì)原始定義作用域的引用,無(wú)論在何處執(zhí)行這個(gè)函數(shù)都會(huì)使用閉包积瞒,內(nèi)部的變量都不會(huì)銷(xiāo)毀川尖,因?yàn)殚]包需要使用,最常見(jiàn)的就是回調(diào)函數(shù)茫孔,和setTimeout,
2,延遲函數(shù)的回調(diào)會(huì)在循環(huán)結(jié)束后才執(zhí)行空厌,會(huì)先把當(dāng)前的同步執(zhí)行完庐船,
3银酬,現(xiàn)在大多數(shù)的模塊依賴加載/管理器的本質(zhì)上都是將這種模塊定義封裝進(jìn)一個(gè)友好的API中嘲更,一下是核心的原理
var MyModules = (function Manager(){
  var modules = []
  // name: 模塊名稱
  // deps:模塊依賴
  // impl: 模塊實(shí)體
  function define(name,deps,impl){
    // 得到所有依賴,當(dāng)前依賴的東西必須在之前已經(jīng)定義好的
    for(var i=0;i<deps.length;i++){
      deps[i] = modules[deps[i]]
    }
    // 定義模塊揩瞪,將所有依賴傳入當(dāng)前的模塊實(shí)體中赋朦,這樣模塊便可以使用依賴
    // apply會(huì)直接執(zhí)行函數(shù),然后得到模塊暴露出來(lái)的API
    modules[name] = impl.apply(impl,deps)
  }
  
  function get(name){
    return modules[name]
  }
  
  // 暴露API
  return {
    define: define,
    get: get
  }
})()
4李破,模塊文件中的內(nèi)容會(huì)被當(dāng)做好像包含在作用域閉包中一樣來(lái)處理宠哄。
  • this

使用new來(lái)調(diào)用函數(shù),會(huì)自動(dòng)執(zhí)行下面的操作
1,創(chuàng)建一個(gè)全新的對(duì)象
2,這個(gè)對(duì)象會(huì)被執(zhí)行[[Prototype]]連接
3,這個(gè)新對(duì)象會(huì)綁定到函數(shù)調(diào)用的this
4,如果函數(shù)內(nèi)部沒(méi)有返回嗤攻,那么自動(dòng)返回這個(gè)新對(duì)象
1毛嫉,字符串,數(shù)值妇菱,布爾字面量在需要的時(shí)候會(huì)自動(dòng)轉(zhuǎn)換為對(duì)應(yīng)的對(duì)象
2承粤,object.assign使用=復(fù)制,所以引用的東西復(fù)制過(guò)來(lái)還是引用
3闯团,var myobject  = Object.create(anotherobject)//以這個(gè)對(duì)象為原型創(chuàng)建一個(gè)對(duì)象
var obj = Object.create(null)得到的對(duì)象沒(méi)有_proto_,存儲(chǔ)數(shù)據(jù)最好了辛臊。
  • 原型,委托

這里的原型概念確實(shí)拓展了以前的理解
常見(jiàn)的類(lèi)的實(shí)現(xiàn)

function Foo(who){
    this.me = who
}
Foo.prototype.identify = function(){
    return 'I am '+ this.me
}
function Bar(who){
    Foo.call(this,who)
}
// 慚愧房交,以前直接=彻舰,因?yàn)槭且茫圆缓线壿?Bar.prototype = Object.create(Foo.prototype)
Bar.prototype.speak = function(){
    alert('Hello,'+ this.identify()+'.')
}
var b1 = new Bar('b1')
var b2 = new Bar('b2')
b1.speak()
b2.speak()

這種實(shí)現(xiàn)情況下候味,他的關(guān)系圖如下(良心出品):

傳統(tǒng)實(shí)現(xiàn)關(guān)系圖.png

1刃唤,因?yàn)閎ar的原型對(duì)象中沒(méi)有constructor所以去原型鏈中找到了Foo,b1,b2也是一樣
2白群,F(xiàn)oo,Bar都是Function 的一個(gè)實(shí)例(函數(shù)也是一個(gè)對(duì)象)尚胞,包括function Object()也是,所以他們的constructor都指向Function 對(duì)象川抡,而proto都指向Function.prototype,

使用委托風(fēng)格實(shí)現(xiàn)的代碼:

Foo = {
  init: function(who){
    this.me = who
  },
  identify: function(){
    return 'I am '+this.me
  }
}

Bar = Object.create(Foo)

Bar.speak = function(){
  alert('Hello,'+this.identify()+'.')
}

var b1 = Object.create(Bar)
b1.init('b1')

var b2 = Object.create(Bar)
b2.init('b2')

b1.speak()
b2.speak()

關(guān)系圖如下:


委托實(shí)現(xiàn)關(guān)系圖.png

實(shí)現(xiàn)方式比較簡(jiǎn)單辐真,就是一路的使用原型鏈去委托,找不到的話崖堤,就去上一級(jí)尋找侍咱。
還是習(xí)慣于使用傳統(tǒng)的方式,但是委托的方式還是很大拓展的思維

  • 嚴(yán)格模式的限制

變量必須聲明后再使用
函數(shù)的參數(shù)不能有同名屬性密幔,否則報(bào)錯(cuò)
不能使用with語(yǔ)句
不能對(duì)只讀屬性賦值楔脯,否則報(bào)錯(cuò)
不能使用前綴0表示八進(jìn)制數(shù),否則報(bào)錯(cuò)
不能刪除不可刪除的屬性胯甩,否則報(bào)錯(cuò)
不能刪除變量delete prop昧廷,會(huì)報(bào)錯(cuò)堪嫂,只能刪除屬性delete global[prop]
eval不會(huì)在它的外層作用域引入變量
eval和arguments不能被重新賦值
arguments不會(huì)自動(dòng)反映函數(shù)參數(shù)的變化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局對(duì)象
不能使用fn.caller和fn.arguments獲取函數(shù)調(diào)用的堆棧
增加了保留字(比如protected、static和interface)
  • es6模塊

1,代碼是在模塊作用域之中運(yùn)行木柬,而不是在全局作用域運(yùn)行皆串。模塊內(nèi)部的頂層變量,外部不可見(jiàn)眉枕。
2,模塊腳本自動(dòng)采用嚴(yán)格模式恶复,不管有沒(méi)有聲明use strict。
3,模塊之中速挑,可以使用import命令加載其他模塊(.js后綴不可省略谤牡,需要提供絕對(duì) URL 或相對(duì) URL),也可以使用export命令輸出對(duì)外接口姥宝。
4,模塊之中翅萤,頂層的this關(guān)鍵字返回undefined,而不是指向window腊满。也就是說(shuō)套么,在模塊頂層使用this關(guān)鍵字,是無(wú)意義的糜烹。
5,同一個(gè)模塊如果加載多次违诗,將只執(zhí)行一次。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疮蹦,一起剝皮案震驚了整個(gè)濱河市诸迟,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌愕乎,老刑警劉巖阵苇,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異感论,居然都是意外死亡绅项,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén)比肄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)快耿,“玉大人,你說(shuō)我怎么就攤上這事芳绩∠坪ィ” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵妥色,是天一觀的道長(zhǎng)搪花。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么撮竿? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任吮便,我火速辦了婚禮,結(jié)果婚禮上幢踏,老公的妹妹穿的比我還像新娘髓需。我一直安慰自己,他們只是感情好惑折,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布授账。 她就那樣靜靜地躺著,像睡著了一般惨驶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上敛助,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天粗卜,我揣著相機(jī)與錄音,去河邊找鬼纳击。 笑死续扔,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的焕数。 我是一名探鬼主播纱昧,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼堡赔!你這毒婦竟也來(lái)了识脆?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤善已,失蹤者是張志新(化名)和其女友劉穎灼捂,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體换团,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡悉稠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了艘包。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片的猛。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖想虎,靈堂內(nèi)的尸體忽然破棺而出卦尊,到底是詐尸還是另有隱情,我是刑警寧澤磷醋,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布猫牡,位于F島的核電站,受9級(jí)特大地震影響邓线,放射性物質(zhì)發(fā)生泄漏淌友。R本人自食惡果不足惜煌恢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望震庭。 院中可真熱鬧瑰抵,春花似錦、人聲如沸器联。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拨拓。三九已至肴颊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間渣磷,已是汗流浹背婿着。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留醋界,地道東北人竟宋。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像形纺,于是被迫代替她去往敵國(guó)和親丘侠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理逐样,服務(wù)發(fā)現(xiàn)蜗字,斷路器,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持官研,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券秽澳,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 3,652評(píng)論 2 27
  • 第一章 編譯原理 js是一門(mén)編譯語(yǔ)言 傳統(tǒng)編譯語(yǔ)言流程: 分詞/詞法分析:把字符串分解成有意義的代碼塊 解析/語(yǔ)法...
    冥冥2017閱讀 582評(píng)論 0 0
  • 前言 人生苦多戏羽,快來(lái) Kotlin 担神,快速學(xué)習(xí)Kotlin! 什么是Kotlin始花? Kotlin 是種靜態(tài)類(lèi)型編程...
    任半生囂狂閱讀 26,146評(píng)論 9 118
  • 241妄讯、我希望所有的單身,都是一種勇者的自信與誠(chéng)實(shí)酷宵,所有的婚姻亥贸,都是一種強(qiáng)者的風(fēng)花與雪月。 242浇垦、女人一生中的精...
    夏煙閱讀 338評(píng)論 1 3