JS中的對象
一系列的無序的 key: value 的集合 (數(shù)組、函數(shù)侠鳄、對象)
獲取對應值 對象.屬性
/ 對象[key]
面向?qū)ο缶幊?OOP (Object-oriented programming)
Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which may contain data, in the form of fields, often known as attributes; and code, in the form of procedures, often known as methods. A feature of objects is that an object's procedures can access and often modify the data fields of the object with which they are associated (objects have a notion of "this" or "self"). In OOP, computer programs are designed by making them out of objects that interact with one another. There is significant diversity of OOP languages, but the most popular ones are class-based, meaning that objects are instances of classes, which typically also determine their type. -- 來自 wiki
面向?qū)ο缶幊淌且粋€可能包含 以字段形式出現(xiàn)的數(shù)據(jù)(稱為屬性) 和 以程序形式出現(xiàn)的代碼(稱為方法) 的基于對象的概念的編程范式。對象的一個特征是對象的方法可以(從外部)訪問對象的數(shù)據(jù)和修改對象的數(shù)據(jù)死宣。在面向?qū)ο缶幊讨形岸瘢嬎銠C程序的設(shè)計使他們在對象之外程序之間進行交互。面向?qū)ο笳Z言是有顯著多樣性的毅该,但大部分流行的是基于類的->對象是類的實例博秫,通常也通過類確定其類型。
一遍學編程一遍學英語
paradigm: 范式
concept: 概念
in the form of fields: 以字段形式出現(xiàn)
feaure: 特性
procedures: 程序
access: 訪問 modify: 修改
interact with ...: 與...交互
significant diversity: 顯著的多樣性
instances of: ...的實例
面向過程的思路:一次性實現(xiàn)所有的流程
面向?qū)ο蟮乃悸罚?/strong>把某個功能看成一個整體(對象)眶掌,通過調(diào)用對象的某個方法來啟動功能挡育。用的時候不用考慮這個對象內(nèi)部的實現(xiàn)細節(jié),在去實現(xiàn)這個對象細節(jié)的時候不用管誰去調(diào)用朴爬。
面向?qū)ο蟮暮锰帲?/strong>簡潔可控容易維護
構(gòu)造對象
一即寒、拋開類,使用 字面量 來構(gòu)造一個對象
var person = {
name: "Nicholas",
age: 29,
job: "Software Engineer",
sayName: function() {
console.log(this.name)
}
}
這樣做的問題:
- 麻煩召噩,每次構(gòu)建一個對象都是復制一遍代碼
- 想要個性化母赵,只能通過手工賦值->使用者必須了解對象的詳細內(nèi)容
這兩個問題也是不能拋開類的重要原因,也是類的重要作用
二具滴、使用函數(shù)做自動化
function createObj(nick, age) {
var obj = {
nick: nick,
age: age,
printName: function() {
console.log(this.nick)
}
}
return obj
}
var newObj = createObj("kofe", 20)
newObj.printName() // "kofe"
通過創(chuàng)建一個函數(shù)來實現(xiàn)自動創(chuàng)建對象的過程市咽,個性化通過參數(shù)實現(xiàn),使用者不必關(guān)注細節(jié)抵蚊,只需傳入指定參數(shù)即可
這樣做的問題:
方法解決了構(gòu)造過于復雜施绎、需要了解細節(jié)的問題溯革,但是構(gòu)造出來的都是 object ,沒有識別度
new
new 運算符接受一個函數(shù) F 及其參數(shù):new F(arguments)
function Person(name, age) {
this.name = name
this.age = age
this.sayName = function() {
console.log(this.name)
}
}
var chen = new Person('kofe', 20)
上面的代碼谷醉,簡單理解為:
- 執(zhí)行new Person
- 創(chuàng)建一個空對象 {}致稀,名字為 tmpObj
- 執(zhí)行 Person 函數(shù) ,過程中對 this 操作就是對 tmpObj 進行操作
- 函數(shù)執(zhí)行完后返回剛創(chuàng)建的 tmpObj
- 把 tmpObj 賦值給 chen (指向同一個對象)
深入理解為:
- 創(chuàng)建類的實例俱尼。把一個空的對象的 __ proto __ 屬性設(shè)置為 F.prototype
- 初始化實例抖单。函數(shù) F 被傳入?yún)?shù)并調(diào)用,關(guān)鍵字 this 被設(shè)定為該實例
- 返回實例
instanceof
操作符遇八,可以判斷對象是否為某個類型的實例
chen instanceof Person // true
chen instanceof Object // true
構(gòu)造函數(shù)解決了上面所有問題矛绘,同時為實例帶來了類型,但可以注意到每個實例的printName方法在實際作用上是一樣的刃永,但是每個實例要重復一遍货矮,大量對象存在的時候就浪費內(nèi)存了
構(gòu)造函數(shù)
- 任何函數(shù)使用 new 表達式就是構(gòu)造函數(shù)
- 每個函數(shù)都自動添加一個 prototype 屬性,這是一個對象
- 每個對象都有一個內(nèi)部屬性 __ proto __ (規(guī)范中沒有指定這個名稱斯够,但是瀏覽器都這么實現(xiàn))指向其類型的 prototype 屬性囚玫,類的實例也是對象,其 __ proto __ 屬性指向“類”的 prototype
通過圖示我們可以看出读规,實例可以通過 __ proto __ 訪問到其類型的 prototype 屬性抓督,意味著類的 prototype 對象可以作為一個公共容器,供所有實例訪問束亏。
抽象重復
- 所有實例都會通過原型鏈引用到類型的 prototype
- prototype 相當于特定類型所有實例都可以訪問到的一個公共容器
- 重復的東西可以移動到這個公共容器里放一份就OK
(例如:默認參數(shù)可以放到 prototype 里)
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.sayName = function() {
console.log(this.name)
}
var p1 = new Person()
p1.sayName()
通過函數(shù)定義了類 Person
铃在,類(函數(shù))自動獲得屬性 prototype
每個類的實例都會有一個內(nèi)部屬性 __proto__
,指向類的 prototype
屬性