1.module.exports 初始值為一個空對象 {}
2.exports 是指向的 module.exports 的引用
3.require() 返回的是 module.exports 而不是 exports
常用寫法:exports = module.exports = {...} 等價于 module.exports = {...}和exports = module.exports
原理:module.exports 指向新的對象時,exports 斷開了與 module.exports 的引用贸宏,那么通過 exports = module.exports 讓 exports 重新指向 module.exports捍岳。
npm i express --save/npm i express -S (安裝 express讥巡,同時將 "express": "^4.14.0" 寫入 dependencies )
npm i express --save-dev/npm i express -D (安裝 express,同時將 "express": "^4.14.0" 寫入 devDependencies )
npm i express --save --save-exact (安裝 express,同時將 "express": "4.14.0" 寫入 dependencies )
第三種方式將固定版本號寫入 dependencies呆躲,建議線上的 Node.js 應用都采取這種鎖定版本號的方式捣卤,因為你不可能保證第三方模塊下個小版本是沒有驗證 bug 的忍抽,即使是很流行的模塊。
一段js在執(zhí)行之前董朝,瀏覽器在全局環(huán)境會先做一些準備工作:
1.給變量鸠项、函數(shù)表達式進行聲明,默認賦值為undefined子姜;
- 給this賦值祟绊;
3.給函數(shù)聲明賦值;
4.函數(shù)每次被調用哥捕,都會產(chǎn)生一個新的執(zhí)行上下文環(huán)境牧抽,函數(shù)體內的語句在執(zhí)行之前,arguments變量和函數(shù)的參數(shù)都已經(jīng)被賦值
以上這些準備工作就稱之為執(zhí)行上下文或者執(zhí)行上下文環(huán)境遥赚;
通俗定義:在執(zhí)行代碼之前,把將要用到的所有的變量都事先拿出來呼巴,有的直接賦值了,有的先用undefined占個空府瞄。
執(zhí)行上下文棧
正如我們所知鲸郊,執(zhí)行全局代碼時會產(chǎn)生一個執(zhí)行上下文環(huán)境秆撮,每次調用函數(shù)又會產(chǎn)生一個執(zhí)行上下文環(huán)境职辨。當函數(shù)調用完成時舒裤,這個上下文環(huán)境以及其中的數(shù)據(jù)都會被消除,再回到全局上下文環(huán)境伴鳖。處于活動狀態(tài)的執(zhí)行上下文環(huán)境只能有一個。其實這就是一個壓棧出棧的過程,稱之為執(zhí)行上下文棧脐往。
|| 和 &&
只要"||"前面為true,無論"||"后面是true還是false,結果都返回"||"前面的值
只要"&&"前面為false巷燥,無論"&&"后面是true還是false,結果都返回"&&"前面的值
call和apply:為了動態(tài)改變this的值而存在的钝腺,當一個對象沒有某個方法定硝,別的對象有這個方法毫目,我們又不想對這個對象重新定義一個一樣的方法星爪,我們就可以通過call或者apply來使用其他對象的方法來操作顽腾。
對象的含義:帶有屬性和方法的特殊數(shù)據(jù)類型。
函數(shù)和對象之間漓摩,不僅僅是包含和被包含的關系管毙,有一點雞生蛋檔蛋生雞的邏輯夭咬。
對象都是通過函數(shù)來創(chuàng)建的,函數(shù)又是一種對象掏湾,像var obj = {name:"xixi",age:12}這種新建對象的方法,其實是一種語法糖來的砚嘴,本質還是通過var obj = new Object();obj.name = "xx"...這種函數(shù)的方式來創(chuàng)建耸采。
每個函數(shù)都有一個叫做prototype的屬性虾宇,這個prototype的屬性值是一個對象,該對象默認的只有constructor的屬性搪泳,指向這個函數(shù)本身。每個對象都有一個proto,并且proto指向創(chuàng)建該對象的函數(shù)的prototype罚攀。
比如:
function Fn(){} var fn = new Fn() Fn是一個函數(shù)杯瞻,fn對象是從Fn()函數(shù)new出來的,這樣fn對象就可以調用Fn.prototype中的屬性是己。因為每一個對象都有一個隱藏的屬性“proto”又兵,這個屬性引用了創(chuàng)建這個對象的函數(shù)的prototype任柜。即:fn.proto === Fn.prototype
對象是被函數(shù)創(chuàng)建的卒废,函數(shù)是被Function(函數(shù))創(chuàng)建的。Function是被自身創(chuàng)建的宙地。
js中繼承是通過原型鏈來體現(xiàn)的摔认。訪問一個對象的屬性時,先在基本屬性中查找宅粥,如果沒有参袱,再沿著proto這條鏈向上找,這就是原型鏈∧ㄊ矗可以用hasOwnProperty函數(shù)來判斷一個對象的屬性到底是基本屬性還是繼承屬性剿牺。但是hasOwnProperty是從哪里來的呢?它是從Object.prototype中來的环壤。
由于所有的對象的原型鏈都會找到Object.prototype,因此所有的對象都會有Object.prototype的方法晒来,這就是所謂的“繼承”。每個函數(shù)都有call,apply方法郑现,都有l(wèi)ength,arguments,caller等屬性湃崩,這些都是繼承的。函數(shù)由Function函數(shù)創(chuàng)建接箫,因此繼承了Function.prototype中的方法攒读。
數(shù)組去重:
數(shù)組排序:數(shù)組的sort()方法默認是把所有的元素先轉化為字符串再排序,而字符串的排序是根據(jù)ASCLL碼排序的辛友,小寫字母a的ASCLL碼排在大寫字母之后薄扁。
冒泡排序:
快速排序:
其他排序方法:
通常規(guī)定,對于兩個元素x和y瞎领,如果認為x < y泌辫,則返回-1;如果x == y九默,則返回0震放;如果x > y;則返回1驼修。這樣排序算法就不用關心具體的比較過程殿遂,而是根據(jù)比較結果直接排序。但是需要注意的事這個方法需要忽略大小寫乙各。
原型對象的結構
Function.prototype = {
constructor : Function,
proto : parent prototype (原型指針墨礁,指向上一級的原型對象),
some prototype properties : 一些原型屬性
}
解釋:函數(shù)的原型對象的constructor默認指向函數(shù)本身耳峦,原型對象除了有原型屬性外恩静,為了實現(xiàn)繼承,還有一個原型鏈指針proto蹲坷,該指針指向上一層的原型對象驶乾,而上一層的原型對象的結構依然類似,這樣利用proto一直指向Object的原型對象上循签,而Object的原型對象Object.prototype.proto = null表示原型鏈的最頂端级乐,如此便形成了JavaScript的原型鏈繼承,同時也結識了為什么所有的JavaScript對象都具有Object的基本方法县匠。