摘要:于是我就先把這本薄的經(jīng)典書(shū)語(yǔ)言精粹修訂版豆瓣讀書(shū)本書(shū)簡(jiǎn)介總共章,除去附錄,才頁(yè),讀完并記錄了一些筆記。讀書(shū)筆記還可以分享給別人看。編程語(yǔ)言第版定義了的標(biāo)準(zhǔn)。程序檢查時(shí)丟棄值為函數(shù)的屬性。
之前看到這篇文章,前端網(wǎng)老姚淺談:怎么學(xué)JavaScript?,說(shuō)到怎么學(xué)習(xí)JavaScript,那就是看書(shū)、分析源碼。
10本書(shū)讀2遍的好處,應(yīng)該大于一本書(shū)讀20遍。
看書(shū)主動(dòng)學(xué)習(xí),看視頻是被動(dòng)學(xué)習(xí)。
看書(shū)和分析源碼的時(shí)機(jī)。但已經(jīng)工作一年半載時(shí),正是提高的好時(shí)候,此時(shí)可以去看書(shū)了。全面系統(tǒng)的梳理知識(shí)點(diǎn),掃清自己的盲區(qū)。如果只是靠項(xiàng)目經(jīng)驗(yàn)是不夠的,通過(guò)項(xiàng)目來(lái)學(xué)習(xí),那>肯定是必須的,工作本身就是一個(gè)學(xué)習(xí)的過(guò)程。
怎么把一本書(shū)看完呢?很簡(jiǎn)單,敲。文字加代碼都敲。
比較認(rèn)同老姚的說(shuō)法。去年畢業(yè)到現(xiàn)在,我也算是工作一年了,是時(shí)候看書(shū)查缺補(bǔ)漏了。
于是我就先把這本薄的經(jīng)典書(shū)《JavaScript語(yǔ)言精粹 修訂版》豆瓣讀書(shū)本書(shū)簡(jiǎn)介(總共10章,除去附錄,才100頁(yè)),讀完并記錄了一些筆記。基本算是摘抄書(shū)本的,自己聯(lián)想到了一些知識(shí)和資料也擴(kuò)展了一下。總體寫(xiě)下來(lái)近一萬(wàn)字。讀書(shū)筆記還可以分享給別人看。回顧時(shí),書(shū)不在身邊還可以看看自己的筆記。想想這類經(jīng)典書(shū)記一遍動(dòng)手敲一遍也是很值得的。不過(guò)這讀書(shū)筆記中可能會(huì)有一些錯(cuò)別字,閱讀時(shí)如果發(fā)現(xiàn)歡迎指正。
第1章 精華大多數(shù)語(yǔ)言都有精華和糟粕。JavaScript令人詭異的事情是,在對(duì)這門語(yǔ)言沒(méi)有的太多了解,甚至對(duì)編程都沒(méi)有太多了解的情況下,你也能用它來(lái)完成工作。
看到這里不禁想起:
張?chǎng)涡翊笈T凇段覍?duì)知乎前端相關(guān)問(wèn)題的十問(wèn)十答》
非計(jì)算機(jī)專業(yè)背景學(xué)習(xí)JS要點(diǎn)有這一條:
所有繼承和原型相關(guān)內(nèi)容跳過(guò),注意,是跳過(guò),不要看!沒(méi)有這些JS一樣可以活得很好,你的日常工作一樣玩得飛起,當(dāng)然,你沒(méi)忍住看了相關(guān)知識(shí)也沒(méi)關(guān)系,因?yàn)槟銜?huì)發(fā)現(xiàn)自己看不懂的;
JavaScript的函數(shù)是(主要)基于詞法作用域的頂級(jí)對(duì)象。
譯注:JavaScript中的函數(shù)是根據(jù)詞法來(lái)劃分作用域的,而不是動(dòng)態(tài)劃分作用域的。具體內(nèi)容參見(jiàn)《JavaScript權(quán)威指南》中譯第5版相關(guān)章節(jié)“8.8.1 詞法作用域”。
JavaScript有非常強(qiáng)大的對(duì)象字面量表示法。這種表示法是JSON的靈感來(lái)源。
原型繼承是JavaScript中一個(gè)有爭(zhēng)議的特性。
《ECMAScript編程語(yǔ)言》第3版定義了JavaScript的標(biāo)準(zhǔn)。
ES3標(biāo)準(zhǔn)
擴(kuò)展:顏海鏡大牛整理的ES3中文版
顏海鏡大牛整理的ES5中文版
W3c ES5中文版
阮一峰大牛的書(shū)籍《ES6標(biāo)準(zhǔn)入門2》
更多內(nèi)容可參見(jiàn)這篇文章:ECMAScript 2018 標(biāo)準(zhǔn)導(dǎo)讀
一個(gè)簡(jiǎn)單的例子:
Function.prototype.method = function(name, func) { this.prototype[name] = func; return this; }
書(shū)中貫徹始終都會(huì)用到這個(gè)method方案,作者將會(huì)在第4章解釋它。
第2章 語(yǔ)法本章主要用鐵路圖(語(yǔ)法圖)表示語(yǔ)法。
主要有:空白、標(biāo)識(shí)符、數(shù)字、字符串、語(yǔ)句、表達(dá)式、字面量、函數(shù)。
typeof 運(yùn)算符產(chǎn)生的值有"number", "string","boolean","undefined","function","object"。如果運(yùn)算數(shù)是一個(gè)數(shù)組或者是null,那么結(jié)果是"object",這其實(shí)是不對(duì)的。
JavaScript簡(jiǎn)單數(shù)據(jù)類型包括數(shù)字、字符串、布爾值,null值和undefined值。其他所有值都是對(duì)象。
數(shù)組、字符串和布爾值“貌似”對(duì)象,因?yàn)樗鼈儞碛蟹椒ǎòb對(duì)象),但它們是不可變的。
對(duì)象是屬性的容器,其中每個(gè)屬性都擁有名字和值。屬性名可以是包括空字符串在內(nèi)的所有字符串,屬性值可以是除了undefined值之外的任何值。
JavaScript包含一種原型鏈的特性,允許對(duì)象繼承到另一個(gè)對(duì)象的屬性。正確地使用它能減少對(duì)象初始化時(shí)的消耗的時(shí)間和內(nèi)存。
檢索
.,[]兩種檢索方式,推薦點(diǎn).表示法。
嘗試重undefined的成員屬性中取值將會(huì)導(dǎo)致TypeError異常,這時(shí)可以通過(guò)&&來(lái)避免錯(cuò)誤。
更新
如果屬性名已經(jīng)存在對(duì)象里。那么屬性的值會(huì)被替換。如果之前沒(méi)有擁有那個(gè)屬性名,那么該屬性將被擴(kuò)充到對(duì)象中。
引用
對(duì)象通過(guò)引用來(lái)傳遞。它們永遠(yuǎn)不會(huì)被復(fù)制。
原型
所有通過(guò)對(duì)象字面量創(chuàng)建的對(duì)象都鏈接到Object.prototype。
創(chuàng)建新對(duì)象時(shí),可以選擇某個(gè)對(duì)象作為它的原型。
if (typeof Object.create !== "function") { Object.create = function(o) { var F = function () {}; F.prototype = o; return new F(); }; }
原型連接只有在檢索值的時(shí)候才被用到。如果嘗試去獲取對(duì)象的某個(gè)屬性值,但對(duì)象沒(méi)有此屬性名,那么JavaScript會(huì)試著從原型對(duì)象中獲取屬性值。如果那個(gè)原型對(duì)象也沒(méi)有該屬性,那么再?gòu)乃脑椭袑ふ遥来祟愅疲钡皆撨^(guò)程最后達(dá)到終點(diǎn)Object.prototype。如果想要的屬性完全不存在原型鏈中,那么結(jié)果就是 undefined值。這個(gè)過(guò)程稱為委托。
原型關(guān)系是一種動(dòng)態(tài)的關(guān)系。
反射
原型鏈上的所有屬性都會(huì)產(chǎn)生值。有兩種方案可以處理掉對(duì)象上不需要的屬性。
①程序檢查時(shí)丟棄值為函數(shù)的屬性。但有可能有些值確實(shí)是函數(shù),所以該方法不可靠。
②使用hasOwnProperty方法,如果是對(duì)象擁有獨(dú)有的屬性,則返回true。該方法不會(huì)檢查原型鏈。
枚舉
① for in可以遍歷一個(gè)對(duì)象中所有的屬性名。但包含函數(shù)和一些不關(guān)心的原型中屬性。而且順序不確定,可以用 hasOwnProperty方法和typeof排除函數(shù)。
②for 循環(huán)不會(huì)出現(xiàn)for in那些情況。
刪除
delete運(yùn)算符可以用來(lái)刪除對(duì)象的屬性。
減少全局變量的污染
可以把全局性的資源納入一個(gè)名稱空間之下。這樣做能減少?zèng)_突。
函數(shù)用于①代碼復(fù)用②信息隱藏③組合調(diào)用。一般來(lái)說(shuō),所謂編程,就是將一組需求分節(jié)成一組函數(shù)與數(shù)據(jù)結(jié)構(gòu)的技能。
JavaScript的函數(shù)就是對(duì)象。
函數(shù)對(duì)象連接到Function.prototype(該原型對(duì)象本身連接到Object.prototype)。
每個(gè)函數(shù)在創(chuàng)建時(shí)會(huì)附加兩個(gè)隱藏屬性,函數(shù)的上下文和實(shí)現(xiàn)函數(shù)行為的代碼。
每個(gè)函數(shù)對(duì)象在創(chuàng)建時(shí)也隨配有一個(gè)prototype屬性。它的值是一個(gè)擁有constructor屬性且值為該函數(shù)的對(duì)象。
函數(shù)字面量
函數(shù)字面量包括4個(gè)部分。①保留字function②函數(shù)名,可以省略,③一組參數(shù)④一組語(yǔ)句。
函數(shù)字面量可以出現(xiàn)在任何允許表達(dá)式出現(xiàn)的地方。一個(gè)內(nèi)部函數(shù)除了可以訪問(wèn)自己的參數(shù)和變量,同時(shí)也可以自由訪問(wèn)把它嵌套在其中的父函數(shù)的參數(shù)和變量。通過(guò)函數(shù)字面量創(chuàng)建的函數(shù)對(duì)象包含一個(gè)連接到外部上下文的連接。這被稱為閉包。
調(diào)用
除了聲明時(shí)定義的形式參數(shù),每一個(gè)函數(shù)還接收兩個(gè)附加的參數(shù):this和argument。在JavaScript中一共有四種調(diào)用模式。①方法調(diào)用模式,②函數(shù)調(diào)用模式③構(gòu)造器調(diào)用模式④apply調(diào)用模式。
(this指向問(wèn)題一直困擾很多人。我一般是這樣記的,誰(shuí)調(diào)用this就指向誰(shuí)。)
方法調(diào)用模式
對(duì)象的方法執(zhí)行,this指向該對(duì)象。比如:
var myObj = { value: 0, showValue: function() { console.log("value:", this.value); } } myObj.showValue(); // value: 0
函數(shù)調(diào)用模式
var add = function(a,b) { return a + b; } add(3,4); //7 window.add(3,4); //7 // 這種this被綁定到全局對(duì)象(window)。 // 可以理解是window.add(3,4);
有種簡(jiǎn)單的辦法就是var that = this;把this存儲(chǔ)下。
例:
var myObj = { value: 0, age: 20, showValue: function() { console.log("value:",this.value); var that = this; var showAge = function() { // window上沒(méi)有age,所以是undefined console.log("這里的this是window ---age:", this.age); // undefined console.log("age:", that.age); // 20 } showAge(); } } myObj.showValue(); // 0, undefined,
構(gòu)造器調(diào)用模式
JavaScript是一門基于原型繼承的語(yǔ)言。
如果在一個(gè)函數(shù)前面帶上new 來(lái)調(diào)用。那么背地利將會(huì)創(chuàng)建一個(gè)連接到該函數(shù)的prototype成員的新對(duì)象,同時(shí)this會(huì)被綁定到那個(gè)新對(duì)象上。
new 前綴也會(huì)改變return 語(yǔ)句的行為。
例:
var Quo = function (string) { this.status = string; } Quo.prototype.get_status = function () { return this.status; } var myQuo = new Quo("confused"); // "confused"
一個(gè)函數(shù),如果創(chuàng)建的目的就是希望結(jié)合new 前綴來(lái)調(diào)用。那么它就被稱為構(gòu)造器函數(shù)。按照約定,它們保存在以大寫(xiě)函數(shù)命名的變量里。如果調(diào)用構(gòu)造器函數(shù)時(shí)沒(méi)有在前面加上new,可能會(huì)發(fā)生非常糟糕的事情,既沒(méi)有編譯時(shí)的警告,也沒(méi)有運(yùn)行時(shí)廣告,所以大寫(xiě)約定非常重要。
作者不推薦這種形式的構(gòu)造器函數(shù)。有更好的替代方式。
Apply調(diào)用模式
JavaScript是一門函數(shù)式的面向?qū)ο缶幊陶Z(yǔ)言,所以對(duì)象可以擁有方法。
apply方法讓我們構(gòu)建一個(gè)參數(shù)數(shù)組傳遞給調(diào)用函數(shù),它也允許我們選擇this的值。
參數(shù)
arguments,雖然擁有length屬性,但不是真正的數(shù)組。而是類似數(shù)組(array-like)的對(duì)象。
返回
return 可用來(lái)是函數(shù)提前返回。當(dāng)return 被執(zhí)行時(shí),函數(shù)立即返回而不再執(zhí)行余下的語(yǔ)句。
一個(gè)函數(shù)總會(huì)返回一個(gè)值,如果沒(méi)指定,那就是返回undefined值。
如果函數(shù)調(diào)用時(shí)在前面加上了new 前綴,且返回值不是一個(gè)對(duì)象,則返回this(該新對(duì)象)。
異常
JavaScript提供了一套異常處理機(jī)制。
throw語(yǔ)句和try catch,try catch中finally是可選的。
擴(kuò)展類型的功能
JavaScript允許給語(yǔ)言的基本類型擴(kuò)充功能。在第3章中我們已經(jīng)看到,可以通過(guò)Object.prototype添加方法,可以讓該方法對(duì)所有對(duì)象都可用。這樣的方式對(duì)函數(shù)、數(shù)組、字符串、數(shù)字、正則表達(dá)式和布爾值同樣適用。
例如:
Function.prototype.method = function () { this.prototype[name] = func; return this; }
基本類型的原型是公用結(jié)構(gòu),所以在類庫(kù)混用時(shí)務(wù)必小心。一個(gè)保險(xiǎn)的做法就是只在確認(rèn)沒(méi)有該方法時(shí)才添加它。
Function.prototype.methods = function(name, func) { if (!this.prototype[name]) { this.prototype[name] = func; } return this; }
遞歸
遞歸函數(shù)就是會(huì)直接或間接地調(diào)用自身的一種函數(shù)。遞歸是一種強(qiáng)大的編程技術(shù),遞歸是用一般的方式去解決每一個(gè)子問(wèn)題。書(shū)中舉了一個(gè)漢諾塔的例子,是程序設(shè)計(jì)中經(jīng)典遞歸問(wèn)題。詳細(xì)說(shuō)明可以參見(jiàn) 百度百科“漢諾塔”詞條。
一些語(yǔ)言提供了尾遞歸優(yōu)化。尾遞歸是一種在函數(shù)的最后執(zhí)行調(diào)用語(yǔ)句的特殊形式的遞歸。參見(jiàn)Tail call。 ES6版本擴(kuò)展了尾遞歸。參見(jiàn)阮一峰老師的《ES6標(biāo)準(zhǔn)入門》中的尾調(diào)用優(yōu)化
作用域
在編程語(yǔ)言中,作用域控制著變量與參數(shù)的可見(jiàn)性和聲明周期。
書(shū)中指出當(dāng)前JavaScript沒(méi)有塊級(jí)作用域。因?yàn)闆](méi)有塊級(jí)作用域,所以最好的做法是在函數(shù)體的頂部聲明函數(shù)中可能用到的所有變量。不過(guò)ES6擴(kuò)展了有塊級(jí)作用域。
閉包
作用域的好處是內(nèi)部函數(shù)可以訪問(wèn)定義它們的外部函數(shù)的參數(shù)和變量(除了this和arguments)。
例子:
// 點(diǎn)擊相應(yīng)節(jié)點(diǎn)時(shí),顯示對(duì)應(yīng)的序號(hào)。可以使用閉包來(lái)解決。 var add_the_handlers = function() { var helper = function(i) { return function(e) { alert(i); } } var i; for (i = 0; i < nodes.length; i += 1) { nodes[i].onclick = helper(i); } } // 擴(kuò)展 另外可以用let i = 0,或者把nodes類數(shù)組轉(zhuǎn)成數(shù)組等方案實(shí)現(xiàn)。 // 閉包特性:1、函數(shù)內(nèi)再嵌套函數(shù),2、內(nèi)部函數(shù)可以調(diào)用外層的參數(shù)和變量,3、參數(shù)和變量不會(huì)被垃圾回收機(jī)制回收。 // 閉包優(yōu)點(diǎn) 靈活和方便,便于封裝。缺點(diǎn):空間浪費(fèi)、內(nèi)存泄露、性能消耗。
回調(diào)
發(fā)起異步請(qǐng)求,提供一個(gè)當(dāng)服務(wù)器響應(yīng)到達(dá)時(shí)隨即出發(fā)的回調(diào)函數(shù)。異步函數(shù)立即返回,這樣客戶端就不會(huì)被阻塞。
模塊
我們可以使用函數(shù)和閉包來(lái)構(gòu)造模塊。模塊是一個(gè)提供接口卻隱藏狀態(tài)與實(shí)現(xiàn)的函數(shù)或?qū)ο蟆?br>舉例:給String添加一個(gè)deentityify方法。它的任務(wù)是尋找字符串中的HTML字符實(shí)體并把它們替換成對(duì)應(yīng)的字符。
String.method("deentityify", function () { // 字符實(shí)體表。它映射字符實(shí)體的名字到對(duì)應(yīng)的字符。 var entity = { quot: """, lt: "<", gt: ">" }; // 返回 deentityify方法 return function () { return this.replace(/&([^&;]+);)/g, function (a,b) { var r = entity[b]; return typeof r === "string"? r : a; } }; }());
模塊模式利用了函數(shù)作用域和閉包來(lái)創(chuàng)建被綁定對(duì)象與私有成員的關(guān)聯(lián),在上面例子中,只有deentityify方法有權(quán)訪問(wèn)字符實(shí)體表這個(gè)數(shù)據(jù)對(duì)象。
模塊模式的一般形式是:一個(gè)定義了私有變量和函數(shù)的函數(shù);利用閉包創(chuàng)建可以訪問(wèn)私有變量和函數(shù)的特權(quán)函數(shù);最后返回這個(gè)特權(quán)函數(shù),或者把它們保存到一個(gè)可以訪問(wèn)的地方。
使用模塊模式就可以摒棄全局變量的使用。它促進(jìn)了信息隱藏和其他優(yōu)秀的設(shè)計(jì)實(shí)踐。對(duì)于應(yīng)用程序的封裝,或者構(gòu)造其他單例對(duì)象,模塊模式非常有效。
單例譯注
模塊模式通常結(jié)合單例模式使用。JavaScript的單例就是用對(duì)象字面量表示法創(chuàng)建的對(duì)象,對(duì)象的屬性值可以是數(shù)值或函數(shù),并且屬性值在該對(duì)象的生命周期中不會(huì)發(fā)生變化。更多內(nèi)容參見(jiàn):?jiǎn)卫J?
級(jí)聯(lián)
有一些方法沒(méi)有返回值。如果我們讓這些方法返回this而不是undefined,就可以啟用級(jí)聯(lián)。
在一個(gè)級(jí)聯(lián)中,我們可以在多帶帶一條語(yǔ)句中依次調(diào)用同一個(gè)對(duì)象的很多方法。比如jQuery獲取元素、操作樣式、添加事件、添加動(dòng)畫(huà)等。
柯里化
柯里化,是把多參數(shù)函數(shù)轉(zhuǎn)換為一系列單參數(shù)函數(shù)并進(jìn)行調(diào)用的技術(shù)。更多詳情可參見(jiàn):柯里化
函數(shù)也是值。柯里化允許我們把函數(shù)與傳遞給它的參數(shù)相結(jié)合,產(chǎn)生一個(gè)新的函數(shù)。
var add1 = add.curry(1); document.writeln(add1(6));
JavaScript并沒(méi)有curry方法,但可以擴(kuò)展該功能。
arguments不是真正的數(shù)組,所以使用了Array.prototype.slice方法。
Function.method("curry",function(){ var slice = Array.prototype.slice, args = slice.apply(arguments), that = this; return function() { return that.apply(null, args.concat(slice.apply(arguments))); } });
記憶
函數(shù)可以將先前操作的結(jié)果記錄在某個(gè)對(duì)象里,從而避免無(wú)謂的重復(fù)運(yùn)算。這種優(yōu)化稱作記憶。
比如說(shuō),我們想要一個(gè)遞歸函數(shù)來(lái)計(jì)算Fibonacci(斐波那契)數(shù)列,它的特點(diǎn)是,前面相鄰兩項(xiàng)之和等于后一項(xiàng)的值。更多參考:斐波那契。最前面兩個(gè)數(shù)字是0和1。
var fibonacci = function() { return n < 2? n : fibonacci(n-1) + fibonacci(n-2); }
這樣雖然能完成工作,但它做了很多無(wú)謂的工作。
構(gòu)造一個(gè)帶有記憶功能的函數(shù):
var memoizer = function(mome, formula) { var recur = function(n) { var result = meno[n]; if (typeof result !== "number") { result = formula(recur, n); meno[n] = result; } return result; }; return recur; }
再用這個(gè)memoizer函數(shù)來(lái)定義fibonacci函數(shù),提供其初始的memo數(shù)組和formula函數(shù)。
var fibonacci = memoizer([0,1],function(recur, n){ return recur(n-1) + recur (n-2); })
極大的減少了我們的工作量。例如要產(chǎn)生一個(gè)記憶的階乘函數(shù),只需要提供基本的階乘公式即可:
var factorial = meoizer([1,1], function(recur, n){ return n * recur(n-1); });第5章 繼承
偽類
JavaScript的原型存在諸多矛盾。它不直接讓對(duì)象從其他對(duì)象繼承,反而插入了一個(gè)多余的間接層:通過(guò)構(gòu)造器函數(shù)產(chǎn)生對(duì)象。
Function構(gòu)造器產(chǎn)生的函數(shù)對(duì)象會(huì)運(yùn)行類似這樣的一些代碼:
this.prototype = {constructor:this}
新函數(shù)對(duì)象被賦予一個(gè)prototype屬性,這個(gè)prototype對(duì)象是存放繼承特征的地方。
當(dāng)采用構(gòu)造器調(diào)用模式,即用new前綴去調(diào)用一個(gè)函數(shù)時(shí),函數(shù)執(zhí)行的方式會(huì)被修改。如果new 運(yùn)算符是一個(gè)方法而不是一個(gè)運(yùn)算符,它可能像這樣執(zhí)行:
Function.method("new",function(){ // 創(chuàng)建一個(gè)新對(duì)象,它繼承自構(gòu)造器函數(shù)的原型對(duì)象。 var that = Object.create(this.prototype); // 調(diào)用構(gòu)造器函數(shù),綁定 -this- 到新對(duì)象上。 var other = this.apply(that,arguments); // 如果它的返回值不是一個(gè)對(duì)象,就返回該新對(duì)象。 return (typeof other === "object" && other) || that; });
所有構(gòu)造器函數(shù)都約定命名成大寫(xiě)字母。一種更好的備選方案就是根本不使用new。
對(duì)象說(shuō)明符
就是指?jìng)鞫鄠€(gè)參數(shù)時(shí),可以直接傳遞一個(gè)對(duì)象。
原型
可以用Object.create方法構(gòu)造出更多實(shí)例來(lái)。
函數(shù)化
迄今為止,我們所看到的繼承模式的一個(gè)弱點(diǎn)就是沒(méi)法保護(hù)隱私。對(duì)象的所有屬性都是可見(jiàn)的。我們無(wú)法得到私有變量和私有函數(shù)。
幸運(yùn)的是,我們有一個(gè)更好的選擇,那就是應(yīng)用模塊模式。
我們從構(gòu)造一個(gè)生成對(duì)象的函數(shù)開(kāi)始。我們以小寫(xiě)字母開(kāi)頭來(lái)命名。
該函數(shù)包括以下四個(gè)步驟
1、創(chuàng)建一個(gè)新對(duì)象。
2、有選擇地私有實(shí)例變量和方法。
3、給這個(gè)新對(duì)象擴(kuò)充方法。
4、返回那個(gè)新對(duì)象。
以下是一個(gè)函數(shù)化構(gòu)造器的偽代碼模板
var constructor = function (spec, my) { var that, 其他的私有實(shí)例變量; my = my || {}; 把共享的變量和函數(shù)添加到my中 that = 一個(gè)新對(duì)象 添加給 that 的特權(quán)方法 return that; }
函數(shù)化模式有很大的靈活性。它相比偽類模式不僅帶來(lái)的工作更少,還讓我們更好的封裝和信息隱藏,以及訪問(wèn)父類方法的能力。
部件
我們可以從一套部件中把對(duì)象組裝出來(lái)。
數(shù)組是一段線性分配的內(nèi)存,它通過(guò)整數(shù)計(jì)算偏移并訪問(wèn)其中的元素。
數(shù)組是一種性能出色的數(shù)據(jù)結(jié)構(gòu)。不幸的是,JavaScript沒(méi)有像此類數(shù)組一樣的數(shù)據(jù)結(jié)構(gòu)。
數(shù)組字面量
對(duì)象字面量
數(shù)組繼承了Array.prototype大量有用的方法。而對(duì)象字面量是繼承自Object.prototype。
數(shù)組有length屬性,而對(duì)象沒(méi)有。
長(zhǎng)度
每個(gè)數(shù)組都有一個(gè)length屬性。
可以直接設(shè)置length的值。設(shè)置更大的length不會(huì)給數(shù)組分配更多的空間,而設(shè)小導(dǎo)致所有下標(biāo)大于等于新length的屬性被刪除。
var arr = [1,2,3]; arr.length = 1; console.log(arr) // [1]
也可以通過(guò)length來(lái)通過(guò)添加值
var arr = [1,2,3]; arr[arr.length] = 4; console.log(arr) // [1,2,3,4]
有時(shí)用push方法更方便。
刪除
由于JavaScript的數(shù)組也是對(duì)象,所以delete運(yùn)算符可以用來(lái)從數(shù)組中移出元素。移除后,長(zhǎng)度不變,原位置上變成了undefined。
可以使用Array.prototype.splice方法刪除數(shù)組。
枚舉
JS數(shù)組就是對(duì)象,所以for in語(yǔ)句可以用來(lái)遍歷數(shù)據(jù)的所有屬性。
不過(guò),for in無(wú)法保證屬性順序。并且可能從原型鏈中得到意外的屬性。
for循環(huán)可以避免以上問(wèn)題。
容易混淆的地方
typeof [] === "object"; // true typeof {} === "object"; // true
識(shí)別是否是數(shù)組。
// 方法一、 var is_array = function (value) { return value && typeof value === "object" && value.constructor === Array; };
但它在識(shí)別從不同窗口(window)或幀(frame)里的構(gòu)造的數(shù)組時(shí)會(huì)失敗。
有一個(gè)更好的方式:
// 方法二、 var is_array = function (value) { return Object.prototype.toString.apply(value) === "[object Array]"; }
擴(kuò)展:
ES5 提供了Array.isArray()的方法。不過(guò)兼容性是IE9+。
要做到兼容,可以用如下方法。MDN上提供的。MDN Array.isArray
// 方法三、 if (!Array.isArray){ Array.isArray = function(arg){ return Object.prototype.toString.call(arg) === "[object Array]"; }; }
var arr = []; // 方法四 arr instanceof Array; // 方法五 Array.prototype.isPrototypeOf(arr); // 方法六 Object.getPrototypeOf(arr) === Array.prototype;
方法四、instanceof 運(yùn)算符用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 prototype 屬性。
方法五、isPrototypeOf() 方法用于測(cè)試一個(gè)對(duì)象是否存在于另一個(gè)對(duì)象的原型鏈上。
方法六、[Object.getPrototypeOf() 方法返回指定對(duì)象的原型(即, 內(nèi)部[[Prototype]]屬性的值)。](https://developer.mozilla.org...
小結(jié):除了方法二、三外,面對(duì)復(fù)雜的環(huán)境,其他的都不能準(zhǔn)確的判斷是否是數(shù)組。
方法
JavaScript提供了一套數(shù)組可用的方法,這些方法是被存儲(chǔ)在Array.prototype中的函數(shù)。
Object.prototype是可以擴(kuò)充的。
Array.prototype也是可以擴(kuò)充的。
ES5中提供的Object.create方法。這方法用在數(shù)組是沒(méi)有意義的,因?yàn)樗a(chǎn)生的是一個(gè)對(duì)象,而不是一個(gè)數(shù)組,產(chǎn)生的對(duì)象將繼承這個(gè)數(shù)組的值和方法,但它沒(méi)有length特殊屬性。
指定初始值
JavaScript的數(shù)組通常不會(huì)預(yù)設(shè)值。書(shū)中寫(xiě)了一個(gè)循環(huán)來(lái)擴(kuò)展,生成初始值。
擴(kuò)展:ES6中提供了fill來(lái)填充。比如:
["a","b","c"].fill(0); // [0,0,0] new Array(3).fill(0); // [0,0,0] // fill方法還可以接受第二、第三個(gè)參數(shù),用于指定填充的起始位置和結(jié)束位置(不包含)。 new Array(3).fill(0,1,2); // [ ,0, ,] 空位不是undefined。空位沒(méi)有任何值。ES6則是明確將空位轉(zhuǎn)為undefined。第7章 正則表達(dá)式
正則表達(dá)式對(duì)字符串中的信息實(shí)現(xiàn)查找、替換和提取操作。
可處理正則表達(dá)式的方法有regexp.exec、regexp.test、string.match、string.search和string.split。通常來(lái)說(shuō),正則相較于等效的字符串處理有著顯著的性能優(yōu)勢(shì)。
一個(gè)例子
// 正則表達(dá)式必須寫(xiě)在一行中 var parse_url = /^(?:([A-Za-z]+):)?(/{0,3})([0-9.-A-Za-z]+)(?::(d+))?(?:/([^?#]*))?(?:?([^#]*))?(?:#(.*))?$/; var url = "http://www.ora.com:80/goodparts?q#fragment"; var result = parse_url.exec(url); // ……
依次匹配到的是:
url: "http://www.ora.com:80/goodparts?q#fragment", scheme: "http", slash: "http://" host: "www.ora.com" port:"80" path:"goodparts" query: "q" hash: "fragment"
個(gè)人擴(kuò)展:這里推薦 在線測(cè)試正則表達(dá)式的網(wǎng)站regex101,默認(rèn)是PHP語(yǔ)言,選擇JavaScript語(yǔ)言。
在線圖形化RegExp工具
MDN RegExp.prototype.exec()
大概解釋下這個(gè)正則,
這里的^ 起始位置,$結(jié)束位置
() 分組捕獲 ?:不捕獲
.表示除換行以外的任意單個(gè)字符,對(duì)于碼點(diǎn)大于0xFFFF的Unicode字符,點(diǎn)(.)不能識(shí)別(ES6中加u修飾符才可識(shí)別),+表示一個(gè)或多個(gè),*表示零個(gè)或多個(gè),?表示0個(gè)或一個(gè)。[]表示或者,里面符合一個(gè)即可。
d表示數(shù)字0-9。
不嚴(yán)謹(jǐn)?shù)恼齽t表達(dá)式是一個(gè)常見(jiàn)的安全漏洞的發(fā)源地。在執(zhí)行某些匹配時(shí),嵌套的正則表達(dá)式也能導(dǎo)致極其惡劣的性能問(wèn)題。因此簡(jiǎn)單是最好的策略。
再看一個(gè) 匹配數(shù)字的例子。
var parse_number = /^-?d+(?:.d*)?(?:e[+-]?d+)?$/i; parse_number.test("1"); // true parse_number.test("number"); // false parse_number.test("98.6"); // true parse_number.test("132.21.86.100"); // false parse_number.test("123.45E-67"); // true parse_number.test("123.45D-67"); // false
結(jié)構(gòu)
有兩個(gè)方法來(lái)創(chuàng)建一個(gè)RegExp對(duì)象。優(yōu)先考慮的是正則表達(dá)式字面量,還有一種方式是new RegExp("","g")。
正則表達(dá)式標(biāo)識(shí):g全局(匹配多次,不同的方法對(duì)g標(biāo)識(shí)的處理防范各不相同),i忽略大小寫(xiě)。m多行
元素
正則表達(dá)式分支
|表示或,也表示分支 比如:
"info".match(/in|int/) // 匹配成功,["in", index: 0, input: "info"]
正則表達(dá)式序列
一個(gè)正則表達(dá)式序列飽和一個(gè)或多個(gè)正則表達(dá)式因子。每一個(gè)因子能選擇是否跟隨一個(gè)量詞,這個(gè)量詞決定著這個(gè)因子被允許出現(xiàn)的次數(shù),若沒(méi)指定,這個(gè)因子則只匹配一次。
正則表達(dá)式因子
/ [ ] () { } ? + * | . ^ $
正則表達(dá)式轉(zhuǎn)義
表轉(zhuǎn)義 f 分頁(yè)
換行
回車 制表
u 允許制定一個(gè) Unicode 字符來(lái)表示一個(gè)十六進(jìn)制的常量。
d 等同于[0-9] D 取反等同于 [^0-9]
s Unicode 空白符一個(gè)不完全子集。 S 與s相反
w [0-9A-Z_a-z] W 與其相反 [^0-9A-Z_a-z]
表示 字邊界
1 表示 分組1所捕獲的文本的一個(gè)引用,所以它能被再次匹配。
2 表示 指向分組2的引用,3 是表示分組3的引用,以此類推。
正則表達(dá)式分組
捕獲型 ()
非捕獲型?:
向前正向匹配?=
有一個(gè)(?=前綴。它類似于非捕獲類型分組,但在這個(gè)組匹配后,文本會(huì)倒回到它它開(kāi)始的地方,實(shí)際上并不匹配任何東西。也可以理解為匹配位置。
向后負(fù)向匹配
有一個(gè)(?!前綴。它類似于向前正向匹配分組,但只有當(dāng)它匹配失敗時(shí)它才繼續(xù)向前進(jìn)行匹配。這不是一個(gè)好的特性。
正則表達(dá)式字符集
正則表達(dá)式字符集是一種指定一組字符的便利方式。例如,要匹配一個(gè)元音字母,(?:a|e|i|o|u),可以方便的寫(xiě)成[aeiou]。
類提供另外兩個(gè)便利:①指定字符范圍
所以,一組由32個(gè)ASCII的特殊組合,可以寫(xiě)成[!-/:-@[-{-~]`
②類的取反
取反
[^!-/:-@[-`{-~]
正則表達(dá)式字符轉(zhuǎn)義
字符類內(nèi)部的轉(zhuǎn)義規(guī)則和正則表達(dá)式因子的相比稍有不同。下面是在字符類中需要被轉(zhuǎn)義的特殊字符。
- / [ ]
正則表達(dá)式量詞
量詞后綴決定正則表達(dá)式因子應(yīng)該被匹配的次數(shù)。
{3}三次
{3,6} 3、4、5、6次
{3,}3次或更多次
?等同于{0,1},*等同于{0,},+等同于{1,}。
array.concat(item...)
concat 方法產(chǎn)生一個(gè)新數(shù)組,它包含一份array的淺復(fù)制并把一個(gè)或多個(gè)參數(shù)item附加在其后。如果item是數(shù)組,那么每個(gè)元素分別被添加。后面有和它功能類似的array.push(item...)方法。
var a = ["a","b","c"]; var b = ["x","y","z"]; var c = a.concat(b, true); // c => ["a","b","c","x","y","z",true]
擴(kuò)展: ES6 有更便捷的擴(kuò)展運(yùn)算符...
var a = ["a","b","c"]; var b = ["x","y","z"]; var c = [...a,true,...b]; // ["a", "b", "c", true, "x", "y", "z"]
array.join(separator)
join方法把一個(gè)array構(gòu)造成一個(gè)字符串。
separator 默認(rèn)值就是逗號(hào)","。
如果你想把大量的字符串片段組裝成一個(gè)字符串,把這些片段放在一個(gè)數(shù)組中,并用join方法連接起來(lái)通常比用+元素運(yùn)算符連接起來(lái)要快。
譯注:對(duì)于IE6/7,使用join連接大量字符串效率確實(shí)優(yōu)于加號(hào)運(yùn)算符。但目前主流瀏覽器,包括IE8以后的版本,都對(duì)+元素運(yùn)算符連接字符串做了優(yōu)化,性能已經(jīng)顯著高于Array.join()。所以目前大多數(shù)情況下,建議首選使用+ 連接字符串。更多參看《高性能網(wǎng)站建設(shè)進(jìn)階指南》中字符串優(yōu)化相關(guān)章節(jié)。
array.pop()
pop方法移除array中的最后一個(gè)元素,并返回這個(gè)元素。如果array為空,則返回undefined。
var a = ["a","b","c"]; var c = a.pop(); // a 是 ["a","b"] c是 "c" // pop 可以像這樣實(shí)現(xiàn)。 // 這里的 Array.method()在第一章例子中已經(jīng)定義了,并且貫穿全書(shū)。其實(shí)就是相當(dāng)于Array.prototype Array.method("pop", function () { return this.splice(this.length-1,1)[0]; });
array.push(item...)
與concat不同的是,它會(huì)修改array,如果參數(shù)item是數(shù)組,它會(huì)把參數(shù)數(shù)組作為單個(gè)元素整個(gè)添加到數(shù)組中。并返回這個(gè)array的新長(zhǎng)度值。
var a = [1,2,3]; var b = [4,5,6]; var c = a.push(b,true); // a 是 [1,2,3,[4,5,6],true] // c 是 5
push可以像這樣實(shí)現(xiàn):
Array.method("push", function () { this.splice.apply( this, [this.length,0]. concat(Array.prototype.slice.apply(arguments))); return this.length; });
array.reverse()
reverse反轉(zhuǎn)array元素順序,并返回array本身。
var a = [1,2,3]; var b = a.reverse(); // a 和 b都是 [3,2,1]
array.shift()
shift移除array的第一個(gè)元素并返回這個(gè)元素。如果array為空,則返回undefined。shift通常比pop慢的多。
var a = [1,2,3]; var c = a.shift(); // a 是[2,3] , c 是1
shift可以這樣實(shí)現(xiàn):
Array.method("shift", function(){ return this.splice(0,1)[0]; });
array.slice(start[, end])
slice是對(duì)array中的一段做淺復(fù)制。end是可選的。默認(rèn)是array.length,如果兩個(gè)參數(shù)任何一個(gè)是負(fù)數(shù),array.length會(huì)和相加。如果start大于array.length,獲得一個(gè)[],字符串也有Sting.slice這個(gè)同名方法。
array.sort
默認(rèn)不能給一組數(shù)字排序。默認(rèn)把要被排序的元素都視為字符串。
幸運(yùn)的是,可以使用自己的比較函數(shù)替換默認(rèn)的比較函數(shù)。
比較函數(shù)應(yīng)該接受兩個(gè)參數(shù),并且如果這兩個(gè)參數(shù)相等則返回0,如果第1個(gè)參數(shù)應(yīng)該排列在前面,則返回一個(gè)負(fù)數(shù),如果第二個(gè)參數(shù)應(yīng)該排列在前面,則返回一個(gè)正數(shù)。
sort方法是不穩(wěn)定的。JavaScript的sort方法的穩(wěn)定性根據(jù)不同瀏覽器的實(shí)現(xiàn)而不一致。
可參見(jiàn)MDN sort
array.splice(start, deleteCount,item...)
splice方法從array中移除一個(gè)或多個(gè)元素,并用新的item替換它們。
// splice 可以像這樣實(shí)現(xiàn) Array.method("splice",function (start, deleteCount) { var max = Math.max, min = Math.min, delta, element, insertCount = max(arguments.length - 2, 0), k = 0, len = this.length, new_len, result = [], shift_count; start = start || 0; if (start < 0) { start += len; } start = max(min(start, len), 0); deleteCount = max(min(typeof deleteCount === "number" ? deleteCount : len, len - start), 0); delta = insertCount - deleteCount; new_len = len + delta; while (k < deleteCount) { element = this[start + k]; if (element !== undefined) { result[k] = element; } k += 1; } shift_count = len - start - deleteCount; if (delta < 0) { k = start + insertCount; while (shift_count) { this[k] = this[k - delta]; k += 1; shift_count -= 1; } this.length = new_len; } else if (delta > 0) { k = 1; while (shift_count) { this[new_len - k] = this[len - k]; k += 1; shift_count -= 1; } this.length = new_len; } for (k = 0; k < insertCount; k += 1) { this[start + k] = arguments[k + 2]; } return result; });
array.unshift(item...)
unshift 方法像push方法一樣,不過(guò)是用于把元素添加到數(shù)組的開(kāi)始部分,返回新array的length。
// unshift 可以像這樣實(shí)現(xiàn) Array.method("unshift", function(){ this.splice.apply(this, [0,0].concat(Array.prototype.slice.apply(arguments))); return this.length; });Function
function.apply(thisArg,argArray)
apply方法調(diào)用function,傳遞一個(gè)會(huì)被綁定到this上的對(duì)象和一個(gè)可選的數(shù)組作為參數(shù)。
number.toExponential(fractionDigits)
toExponential方法 把這個(gè)number轉(zhuǎn)換成一個(gè)指數(shù)形式的字符串。可選參數(shù)控制其小數(shù)點(diǎn)后的數(shù)字位數(shù)。它的值必須在0~20。
number.toFixed(fractionDigits)
toFixed方法把這個(gè)number轉(zhuǎn)換成一個(gè)十進(jìn)制數(shù)形式的字符串。可選參數(shù)控制其小數(shù)點(diǎn)后的數(shù)字位數(shù)。它的值必須在0~20。
number.toPrecision(precision)
toPrecision方法把這個(gè)number轉(zhuǎn)換成一個(gè)十進(jìn)制數(shù)形式的字符串。可選參數(shù)控制數(shù)字的精度。它的值必須在0~21。
number.toString(radix)
把number轉(zhuǎn)換成字符串。可選參數(shù)控制基數(shù)。它的值必須是2~36。默認(rèn)的radix是以10為基數(shù)的。radix參數(shù)最常用的是整數(shù),但是它可以用任意的數(shù)字。
object.hasOwnProperty(name)
如果這個(gè)object包含名為name的屬性,那么返回true。原型鏈中的同名方法不會(huì)被檢測(cè)。這個(gè)方法對(duì)name就是“hasOwnProperty”時(shí)不起作用。
regexp.exec(string)
exec是正則中最強(qiáng)大(和最慢)的方法。
如果成功匹配,它會(huì)返回一個(gè)數(shù)組。下標(biāo)為0 的元素包含正則匹配的子字符串。下標(biāo)為1的則是分組1捕獲的文本。下標(biāo)為2的則是分組2捕獲的文本。以此類推。如果匹配失敗則返回null。
regexp.test(string)
test是最簡(jiǎn)單(和最快)的方法。匹配成功,返回true,否則返回false。不要對(duì)這個(gè)方法使用g標(biāo)識(shí)。
比如:
var reg = /w+/g; reg.test("ab"); // true // 再執(zhí)行一遍就是false了。 reg.test("ab"); // false // 再執(zhí)行一遍就是true了。 reg.test("ab"); // true // 再執(zhí)行一遍又是false了,如此反復(fù),所以用g標(biāo)識(shí)后,看起來(lái)很詭異。因?yàn)槊看纹ヅ溟_(kāi)始位置變了。 reg.test("ab"); // false
test可以像這樣實(shí)現(xiàn):
RegExp.method("test", function(string){ return this.exec(string) !== null; });String
string.charAt(pos)
返回在string中的pos位置處的字符。
string.charCodeAt(pos)
與charAt一樣,不過(guò)返回整數(shù)形式表示字符碼位。
string.concat(string)
很少用,用+號(hào)運(yùn)算符更方便。
string.indexOf(searchString,position)
在string中查找第一個(gè)參數(shù),如果被找到返回該字符的位置,否則返回-1。position可設(shè)置指定位置開(kāi)始查找。
string.lastIndexOf(searchString,position)
lastIndexOf 方法和indexOf方法類似,不過(guò)它是從末尾開(kāi)始查找,不是從頭開(kāi)始。
string.localeCompare(that)
比較兩個(gè)字符串。類似于array.sort。
string.match(regexp)
如果沒(méi)有g標(biāo)識(shí),那么調(diào)用string.match(regexp)和調(diào)用regexp.exec(string)結(jié)果相同。如果帶有g標(biāo)識(shí),那么它生成一個(gè)包含所有匹配(除捕獲分組之外)的數(shù)組。
string.replace(searchValue,replaceValue)
對(duì)string進(jìn)行查找和替換操作,并返回一個(gè)新的字符串。參數(shù)searchvalue可以是一個(gè)字符串也可以是一個(gè)正則表達(dá)式對(duì)象。參數(shù)replaceValue可以是一個(gè)字符串或一個(gè)函數(shù)。
string.search(regexp)
和indexOf類似,不過(guò)它接收正則為參數(shù)。
string.slice(start, end)
slice方法復(fù)制string的一部分來(lái)構(gòu)造一個(gè)新的字符串。如果start參數(shù)是負(fù)數(shù),它將與string.length相加。end參數(shù)是可選的。
string.split(separator,limit)
把string分割成片段來(lái)創(chuàng)建一個(gè)字符串?dāng)?shù)組。可選參數(shù)limit可以限制分割的片段數(shù)量。separator參數(shù)可以是字符串或者正則。
string.substring(start,end)
與slice方法一樣,不過(guò)它不能處理負(fù)數(shù)參數(shù)。
string.toLocaleLowerCase()
它使用本地化的規(guī)則把這個(gè)string中的字母轉(zhuǎn)換成小寫(xiě)格式。這個(gè)方法主要用在土耳其語(yǔ)上。
string.toLocaleUpperCase()
它使用本地化的規(guī)則把這個(gè)string中的字母轉(zhuǎn)換成大寫(xiě)格式。這個(gè)方法主要用在土耳其語(yǔ)上。
string.toLowerCase()
返回新字符串,所有字母轉(zhuǎn)成小寫(xiě)格式。
string.toUpperCase()
返回新字符串,所有字母轉(zhuǎn)成大寫(xiě)格式。
String.fromCharCode(char...)
根據(jù)一串?dāng)?shù)字編碼返回一個(gè)字符串。
var a = String.fromCharCode(67,97,116) // a是"Cat"第9章 代碼風(fēng)格
這一章中,簡(jiǎn)短的說(shuō)了一些代碼風(fēng)格。事實(shí)證明代碼風(fēng)格在編程中是很重要的。
第10章 優(yōu)美的特性精簡(jiǎn)的JavaScript里都是好東西。
包括:1、函數(shù)是頂級(jí)對(duì)象;2、基于原型繼承的動(dòng)態(tài)作用域;3、對(duì)象字面量和數(shù)組字面量。
到此,讀書(shū)筆記已完結(jié)。文章有什么不妥之處,歡迎指出~
關(guān)于作者:常以軒轅Rowboat若川為名混跡于江湖。前端路上 | PPT愛(ài)好者 | 所知甚少,唯善學(xué)。
個(gè)人博客
segmentfault前端視野專欄,開(kāi)通了前端視野專欄,歡迎關(guān)注
掘金專欄,歡迎關(guān)注
知乎前端視野專欄,開(kāi)通了前端視野專欄,歡迎關(guān)注
github,歡迎follow~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/84245.html
摘要:語(yǔ)言精粹讀書(shū)筆記第四章函數(shù)函數(shù)字面量函數(shù)字面量包含個(gè)部分第一部分,保留字第二部分,函數(shù)名,它可以被忽略。這個(gè)超級(jí)延遲綁定使得函數(shù)對(duì)高度復(fù)用。構(gòu)造器調(diào)用模式一個(gè)函數(shù),如果創(chuàng)建的目的就是希望結(jié)合的前綴來(lái)調(diào)用,那它就被稱為構(gòu)造器構(gòu)造。 《JavaScript 語(yǔ)言精粹》 讀書(shū)筆記 第四章 函數(shù) Functions 函數(shù)字面量 函數(shù)字面量包含4個(gè)部分: 第一部分, 保留字 function...
摘要:對(duì)象被傳遞到從句中被捕獲。一些語(yǔ)言提供了尾遞歸優(yōu)化。這意味著如果一個(gè)函數(shù)返回自身遞歸調(diào)用的結(jié)果,那么調(diào)用的過(guò)程會(huì)被替換為一個(gè)循環(huán),可以顯著提高速度。構(gòu)建一個(gè)帶尾遞歸的函數(shù)。語(yǔ)言精粹讀書(shū)筆記函數(shù) 第四章 函數(shù) Functions (二) 參數(shù) arguments arguments數(shù)組: 函數(shù)可以通過(guò)此參數(shù)訪問(wèn)所有它被調(diào)用時(shí)傳遞給它的參數(shù)列表,包括哪些沒(méi)有被分配給函數(shù)聲明時(shí)定義的形式參數(shù)...
摘要:使用構(gòu)造器有個(gè)嚴(yán)重的危害,如果在調(diào)用構(gòu)造器函數(shù)的時(shí)候忘記使用前綴,不僅不會(huì)綁定到新對(duì)象,還會(huì)污染全局變量原型模式原型模式中,我們采用對(duì)象來(lái)繼承。 構(gòu)造器調(diào)用模式 當(dāng)一個(gè)函數(shù)對(duì)象被創(chuàng)建時(shí),F(xiàn)unction構(gòu)造器會(huì)運(yùn)行類似這樣的代碼: this.prototype = {constructor: this} new一個(gè)函數(shù)事會(huì)發(fā)生: Function.method(new, functio...
摘要:本文最早為雙十一而作,原標(biāo)題雙大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在上。發(fā)布完本次預(yù)告后,捕捉到了一個(gè)友善的吐槽讀書(shū)清單也要收費(fèi)。這本書(shū)便從的異步編程講起,幫助我們?cè)O(shè)計(jì)快速響應(yīng)的網(wǎng)絡(luò)應(yīng)用,而非簡(jiǎn)單的頁(yè)面。 本文最早為雙十一而作,原標(biāo)題雙 11 大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在 GitChat 上。發(fā)布之后在讀者圈群聊中和讀者進(jìn)行了深入的交流,現(xiàn)免費(fèi)分享到這里,不足之處歡迎指教...
摘要:本文最早為雙十一而作,原標(biāo)題雙大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在上。發(fā)布完本次預(yù)告后,捕捉到了一個(gè)友善的吐槽讀書(shū)清單也要收費(fèi)。這本書(shū)便從的異步編程講起,幫助我們?cè)O(shè)計(jì)快速響應(yīng)的網(wǎng)絡(luò)應(yīng)用,而非簡(jiǎn)單的頁(yè)面。 本文最早為雙十一而作,原標(biāo)題雙 11 大前端工程師讀書(shū)清單,以付費(fèi)的形式發(fā)布在 GitChat 上。發(fā)布之后在讀者圈群聊中和讀者進(jìn)行了深入的交流,現(xiàn)免費(fèi)分享到這里,不足之處歡迎指教...
閱讀 984·2021-11-23 09:51
閱讀 3470·2021-11-22 12:04
閱讀 2716·2021-11-11 16:55
閱讀 2921·2019-08-30 15:55
閱讀 3222·2019-08-29 14:22
閱讀 3351·2019-08-28 18:06
閱讀 1240·2019-08-26 18:36
閱讀 2126·2019-08-26 12:08