2018-04-21 js 面向?qū)ο缶?------ 總結(jié)

前兩天看完了 js 面向?qū)ο缶? 有所收獲, 因此趁熱打鐵做一下記錄. 這本書很薄, 只用了兩天午休的時(shí)間就看完了, 但作者的講述是十分清晰的.

引用類型和原始類型

js 中的數(shù)據(jù), 要么是一個(gè)對(duì)象, 要么從一個(gè)對(duì)象中獲取

原始類型
  1. 原始類型直接保存值, 引用類型保存指向內(nèi)存的指針
  2. 用原始類型給變量賦值時(shí), 值會(huì)直接被賦值到改變量中
  3. 對(duì)于原始類型, 用 typeof 函數(shù)
  4. 原始類型擁有方法, 但它們不是對(duì)象, js 使它們用起來像對(duì)象, 是為了提供語言上的一致性體驗(yàn).
引用類型(對(duì)象)

創(chuàng)建對(duì)象

  1. 構(gòu)造函數(shù)和 new 操作符
  2. 使用字面量

內(nèi)建類型

  1. 六種內(nèi)建類型
  2. 鑒別引用類型使用 instanceof 函數(shù)
  3. 所有類型都繼承自 Object
  4. 使用 Array.isArray 鑒別數(shù)組. 由于不同框架會(huì)實(shí)現(xiàn)不同的 Array 實(shí)例.

原始封裝類型
String, Number, Boolean

  • 每當(dāng)讀取字符串, 數(shù)字或布爾值時(shí), 原始封裝對(duì)象會(huì)自動(dòng)創(chuàng)建
  • 原始封裝對(duì)象僅存在于該語句
  • 語句執(zhí)行完成后會(huì)自動(dòng)銷毀所創(chuàng)建的原始封裝對(duì)象

函數(shù)

函數(shù)也是一個(gè)對(duì)象, 內(nèi)部獨(dú)有一個(gè) [[call]] 屬性, 表明該對(duì)象可以被執(zhí)行.

兩種定義方式:

var a = function() {
}

// 這種寫法會(huì)有聲明提升, 函數(shù)定義會(huì)被提升到上下文的頂部
function a() {
}
函數(shù)的參數(shù)
  1. 保存在 arguments 對(duì)象中(這個(gè)對(duì)象的行為表現(xiàn)類似于數(shù)組)
  2. arguments 不是 Array 的實(shí)例
  3. arguments.length 表示期望的參數(shù)的長度
  4. js 不存在函數(shù)重載, 但可以根據(jù) arguments 的狀態(tài)去模擬
this 對(duì)象
  1. js 的每個(gè)函數(shù)的作用域中都有一個(gè) this 對(duì)象, 代表 調(diào)用改函數(shù)的對(duì)象
  2. 改變 this 指向的三種方法
    • call(target, param1, param2, ...)
    • apply(target, [params...])
    • bind(target, 其余參數(shù)會(huì)被設(shè)為新函數(shù)中的命名參數(shù))

理解對(duì)象

  1. 屬性第一次被添加給對(duì)象時(shí), js 在對(duì)象上調(diào)用一個(gè)名為 [[put]] 的內(nèi)部方法
  2. 調(diào)用 [[put]] 方法在對(duì)象上創(chuàng)建了自有屬性
  3. 對(duì)已有屬性賦新值時(shí), 調(diào)用了內(nèi)部的 [[set]] 方法
  4. 使用 in 操作符判斷屬性是否存在于方法中, 其實(shí)就是在 hashtable 中查找一個(gè)鍵是否存在. in 操作符會(huì)檢查自由屬性和原型屬性
  5. delete 刪除一個(gè)屬性, 其實(shí)是調(diào)用了內(nèi)部的 [[delete]] 方法
屬性枚舉
  1. [[Enumerable]] 屬性表示屬性是否可枚舉
  2. 使用 for-in 循環(huán)枚舉一個(gè)對(duì)象的可枚舉屬性
  3. Object.keys() 得到一個(gè)對(duì)象的所有可枚舉自有屬性的名稱數(shù)組.
屬性類型

數(shù)據(jù)屬性和訪問器屬性

  • 數(shù)據(jù)屬性包含值
  • 訪問器屬性不包含值, 包含 setter 和 getter 兩個(gè)函數(shù)
  • 只定義 getter 就是只讀
  • [[Configureable]] 決定該屬性是否可配置, 手動(dòng)聲明的所有默認(rèn)屬性都是可枚舉, 可配置的
  • 可以用 Object.defineProperty() 方法改變屬性特征. 需要為所有特征指定一個(gè)值, 否則布爾值類型的特征會(huì)被默認(rèn)設(shè)置為 false.
  • 無法將不可配置的屬性變成可配置的.
  • 數(shù)據(jù)屬性有一個(gè) [[value]] 屬性, 里面保存了值. 還有一個(gè) [[writable]] 表示是否可寫.
  • 訪問器屬性也有兩個(gè)額外特征, [[get]] 和 [[set]]
  • 定義多重屬性使用 Object.defineProperties() 函數(shù)
  • Object.getOwnPropertyDescriptor() 方法獲取屬性的特征
  • [[extensible]] 是否可修改, false 時(shí)表示不可修改, 無法添加新屬性
  • Object.preventExtensions() 創(chuàng)建一個(gè)不可擴(kuò)展的對(duì)象
  • Object.isExtensible() 方法檢查 [[extensible]] 的值
  • Object.seal() 方法創(chuàng)建一個(gè)封印的對(duì)象, [[extensible]] 為 false, 所有屬性的 [[Configureable]] 也是 false
  • Object.isSealed() 方法判斷一個(gè)對(duì)象是否被封印
  • Object.freeze() 方法凍結(jié)一個(gè)對(duì)象. 改對(duì)象是一個(gè)所有屬性都是只讀的 sealed 對(duì)象
  • Object.isFrozen() 判斷是否被凍結(jié)

構(gòu)造函數(shù)和原型函數(shù)

構(gòu)造函數(shù)就是你用 new 創(chuàng)建對(duì)象時(shí)調(diào)用的函數(shù), 所有使用同一個(gè)構(gòu)造函數(shù)創(chuàng)建的對(duì)象都有相同的屬性和方法

  • 與普通函數(shù)的區(qū)別: 首字母大寫
  • 調(diào)用構(gòu)造函數(shù)時(shí), new 關(guān)鍵字會(huì)自動(dòng)創(chuàng)建 this 對(duì)象, 且類型就是構(gòu)造函數(shù)的類型.
  • 也可以在構(gòu)造函數(shù)中顯式 return, 如果 return 的是對(duì)象, 則返回該對(duì)象實(shí)例; 如果是原始值, 會(huì)被忽略, 返回的依舊是對(duì)象實(shí)例.
  • 忘記用 new 調(diào)用構(gòu)造函數(shù)時(shí), this 是 window
原型對(duì)象

幾乎所有函數(shù)都有 prototype 屬性, 所有創(chuàng)建的實(shí)例都共享原型對(duì)象, 且可以訪問到原型對(duì)象的屬性.

  • 鑒別一個(gè)屬性是否是原型對(duì)象的屬性:
var hasPrototypeProperty(object, name) {
  var result = (name in object) && !(Object.hasOwnProperty(name))
  return result
}
  • 對(duì)象實(shí)例通過 [[prototype]] 跟蹤其原型對(duì)象
  • 當(dāng) new 一個(gè)對(duì)象時(shí), 構(gòu)造函數(shù)的原型對(duì)象會(huì)被賦值給該對(duì)象的 [[prototype]] 屬性
  • 可以使用 Object.getPrototypeOf() 方法讀取 [[prototype]] 屬性的值
  • 對(duì)于所有的泛用對(duì)象, 其 [[prototype]] 屬性始終指向 Object.prototype
  • 使用 _proto_ 屬性可直接讀寫 [[prototype]] 屬性.
  • 原型屬性無法賦值
  • 可以直接用字面量替換原型對(duì)象, 但需要注意的是 constructor 屬性需要手動(dòng)替換, 不指定的話默認(rèn)是指向 Object
  • 可以給內(nèi)建對(duì)象的 prototype 增加方法, 但不推薦, 因?yàn)榭赡軙?huì)誤導(dǎo)其他程序員

繼承

js 中的繼承是通過原型對(duì)象鏈繼承的.

對(duì)象通常都繼承自 Object.prototype, 因此也都有一下方法:


hasOwnProperty()

properTyIsEnumerable()

isPrototypeOf()

// 當(dāng)一個(gè)操作符作用于一個(gè)對(duì)象時(shí), 就會(huì)調(diào)用 valueOf() 方法
// 原始封裝類型重寫了該方法, 使 String 有不同的表現(xiàn)形式
valueOf()

// 當(dāng) valueOf 方法返回的是一個(gè)引用時(shí), 就會(huì)調(diào)用 toString 方法
toString()
對(duì)象的繼承
  • 只需要指定哪個(gè)對(duì)象是新對(duì)象的 [[prototype]], 也可以用 Object.create() 方法顯式創(chuàng)建
  • 所有繼承鏈的末端通常是 Object.prototype, 其 [[prototype]] 為 null
  • 訪問父類方法時(shí), 使用 call 或 apply 指定 this
對(duì)象模式

私有成員:

  1. 通過 _name 來約束
  2. 通過立即函數(shù)來返回對(duì)象
  3. 通過閉包返回對(duì)象, 在閉包內(nèi)調(diào)用外部的變量(模塊模式)

混入:
一個(gè)對(duì)象在不改變?cè)蛯?duì)象鏈的情況下, 得到了另一個(gè)對(duì)象的屬性和方法, 被稱為混入
混入的實(shí)現(xiàn):

  1. 使用 for-in 淺拷貝
  2. 使用 foreach 實(shí)現(xiàn) mixin 函數(shù)
var mixin = function(receiver, supplier) {
  Object.keys(supplier).forEach(function(property) {
    var descriptor = Object.getOwnPropertyDescriptor(supplier, property)  
    Object.defineProperty(receiver, property, descriptor)
    return receiver
  })
}
作用域安全的構(gòu)造函數(shù)

在函數(shù)內(nèi)判斷自己是否被 new 調(diào)用, 處理不同的情況

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末车遂,一起剝皮案震驚了整個(gè)濱河市氛赐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赦役,老刑警劉巖挨摸,帶你破解...
    沈念sama閱讀 217,406評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異际歼,居然都是意外死亡惶翻,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門鹅心,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吕粗,“玉大人,你說我怎么就攤上這事旭愧÷睿” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵输枯,是天一觀的道長议泵。 經(jīng)常有香客問我,道長桃熄,這世上最難降的妖魔是什么先口? 我笑而不...
    開封第一講書人閱讀 58,380評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮瞳收,結(jié)果婚禮上碉京,老公的妹妹穿的比我還像新娘。我一直安慰自己螟深,他們只是感情好谐宙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,432評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著界弧,像睡著了一般凡蜻。 火紅的嫁衣襯著肌膚如雪搭综。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評(píng)論 1 301
  • 那天咽瓷,我揣著相機(jī)與錄音设凹,去河邊找鬼。 笑死茅姜,一個(gè)胖子當(dāng)著我的面吹牛闪朱,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钻洒,決...
    沈念sama閱讀 40,145評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼奋姿,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了素标?” 一聲冷哼從身側(cè)響起称诗,我...
    開封第一講書人閱讀 39,008評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎头遭,沒想到半個(gè)月后寓免,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,443評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡计维,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,649評(píng)論 3 334
  • 正文 我和宋清朗相戀三年袜香,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲫惶。...
    茶點(diǎn)故事閱讀 39,795評(píng)論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蜈首,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出欠母,到底是詐尸還是另有隱情欢策,我是刑警寧澤,帶...
    沈念sama閱讀 35,501評(píng)論 5 345
  • 正文 年R本政府宣布赏淌,位于F島的核電站,受9級(jí)特大地震影響六水,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缩擂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,119評(píng)論 3 328
  • 文/蒙蒙 一添寺、第九天 我趴在偏房一處隱蔽的房頂上張望胯盯。 院中可真熱鬧,春花似錦计露、人聲如沸憎乙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疗杉,卻和暖如春阵谚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烟具。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評(píng)論 1 269
  • 我被黑心中介騙來泰國打工梢什, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留朝聋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,899評(píng)論 2 370
  • 正文 我出身青樓荔睹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親僻他。 傳聞我的和親對(duì)象是個(gè)殘疾皇子猜极,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,724評(píng)論 2 354

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