ECMAScript 有兩種開(kāi)發(fā)模式:1.函數(shù)式(過(guò)程化),2.面向?qū)ο?OOP),本文先來(lái)了解面向?qū)ο缶幊蹋紫任覀兿葋?lái)看一下,什么是面向?qū)ο螅?/strong>
面向?qū)ο?Object Oriented)是軟件開(kāi)發(fā)方法,一種編程范式,是一種對(duì)現(xiàn)實(shí)世界理解和抽象的方法,是計(jì)算機(jī)編程技術(shù)發(fā)展到一定階段后的產(chǎn)物。
面向?qū)ο蟪绦蛟O(shè)計(jì)(Object Oriented Programming)本質(zhì)是以建立模型體現(xiàn)出來(lái)的抽象思維過(guò)程和面向?qū)ο蟮姆椒āC嫦驅(qū)ο蠓椒?,則是把相關(guān)的數(shù)據(jù)和方法組織為一個(gè)整體來(lái)看待。
js是一種面向?qū)ο蟮木幊谭绞剑梢酝ㄟ^(guò)構(gòu)造、繼承等方法創(chuàng)建對(duì)象概念,擴(kuò)展對(duì)象的屬性和行為(方法),從而封裝一個(gè)抽象類(lèi)。
js沒(méi)有真正的類(lèi),ES6中引入類(lèi)class的概念,作為對(duì)象的模板被引入,可以通過(guò) class 關(guān)鍵字定義類(lèi),其本質(zhì)是Function,是函數(shù)式編程的最直接體現(xiàn)方式。
面向?qū)ο缶幊痰幕咎卣魅缦?/p>
那我們?nèi)绾蝿?chuàng)建對(duì)象,進(jìn)而擴(kuò)展屬性和方法(行為),對(duì)象實(shí)例化(封裝)方式有哪些?
一、原始模式
var oop = {
var oop2 = {}
這種方式存在兩個(gè)缺點(diǎn):
1、需要?jiǎng)?chuàng)建多個(gè)實(shí)例,單一賦值,消耗內(nèi)存
2、實(shí)例和原型之間沒(méi)有公用方法,看不出內(nèi)在聯(lián)系
二、定義函數(shù)****,對(duì)原始模式進(jìn)行改進(jìn)
function Obj(a, b) {
缺點(diǎn): person1 和person2沒(méi)有任何關(guān)聯(lián)關(guān)系,不能反映出他們是同一個(gè)原型的實(shí)例對(duì)象
三、工廠模式定義對(duì)象
function createObj(a, b){ //對(duì)象工廠
缺點(diǎn):工廠模式可以創(chuàng)建多個(gè)相似的對(duì)象,但是卻沒(méi)有解決對(duì)象的識(shí)別問(wèn)題,無(wú)法區(qū)分對(duì)象類(lèi)型。
四、構(gòu)造函數(shù)
function CreateObj(a, b){
”構(gòu)造函數(shù)”,其實(shí)就是一個(gè)普通函數(shù),在內(nèi)部使用了this變量。也可以理解為:構(gòu)造函數(shù)就是類(lèi),person1, person2其實(shí)就是createObj類(lèi)的實(shí)例對(duì)象。
加new執(zhí)行的函數(shù)構(gòu)造內(nèi)部變化:自動(dòng)生成一個(gè)對(duì)象,this指向這個(gè)新創(chuàng)建的對(duì)象,函數(shù)自動(dòng)返回這個(gè)新創(chuàng)建的對(duì)象。
function CreateObj(a, b){
對(duì)于每一個(gè)實(shí)例對(duì)象,sex屬性和address()方法都是一模一樣的內(nèi)容,每一次生成一個(gè)實(shí)例,都必須為重復(fù)的內(nèi)容,多占用一些內(nèi)存。這樣既不環(huán)保,也缺乏效率。
缺點(diǎn):浪費(fèi)內(nèi)存,容易造成內(nèi)存泄漏。
五: 原型創(chuàng)建方式 -- Prototype 原型
Javascript規(guī)定,每一個(gè)構(gòu)造函數(shù)都有一個(gè)prototype屬性,指向另一個(gè)對(duì)象。這個(gè)對(duì)象的所有屬性和方法,都會(huì)被構(gòu)造函數(shù)的實(shí)例繼承。這意味著,我們可以把那些不變的屬性和方法,直接定義在prototype對(duì)象上。proto是原型鏈,指向?qū)嵗暮瘮?shù)原型。
function CreateObj(a, b){
CreateObj.prototype.sex = 'male'
所有實(shí)例的sex屬性和address()方法,其實(shí)都是同一個(gè)內(nèi)存地址,指向prototype對(duì)象,減少內(nèi)存占用,提高了運(yùn)行效率。
六:Prototype模式的驗(yàn)證方法
為了配合prototype屬性,Javascript定義了一些輔助方法,幫助我們使用它。
hasOwnProperty() -- 查看該屬性是否在這個(gè)對(duì)象本身上,只有在自身屬性上才會(huì)返回真,在原型鏈上會(huì)返回假
person1.hasOwnProperty('name') // true
isPrototypeOf()-- 查看某個(gè)proptotype對(duì)象和某個(gè)實(shí)例之間的關(guān)系。
createObj.isPrototypeOf('person1') // true
了解了對(duì)象的創(chuàng)建方法,我們一起來(lái)看看對(duì)象和函數(shù)之間的關(guān)系
對(duì)象是由函數(shù)構(gòu)造出來(lái)的,Object是Function構(gòu)造出來(lái)的實(shí)例
Object.constructor == Function; // true constructor構(gòu)造器
函數(shù)是Function 的實(shí)例,但不是Object 的實(shí)例
Function.constructor === Function // true
實(shí)例對(duì)象不可訪問(wèn)類(lèi)中的靜態(tài)方法和靜態(tài)屬性
function CreateObj(a){
講完面向?qū)ο蟮姆庋b,我們一起來(lái)看一下多態(tài)。
同一個(gè)方法(類(lèi)), 面對(duì)不同的對(duì)象有不同的表現(xiàn)形式就叫做多態(tài)。
function createObj(a){
這種方法的封裝有很大的局限性,比如我新增新人類(lèi)、無(wú)性別人士、跨性別人士,則需要改動(dòng)createObj方法以擴(kuò)展對(duì)新對(duì)象的兼容??梢酝ㄟ^(guò)重寫(xiě)子類(lèi)來(lái)重新定義父類(lèi)方法。
function createObj(a){
重載是指多個(gè)同名但參數(shù)不同的方法,大家感興趣的可以自己嘗試重載擴(kuò)展對(duì)象屬性/方法。
"多態(tài)"的思想把不變的部分隔離出來(lái),把可變的部分封裝起來(lái),這給予我們擴(kuò)展程序的能力,相對(duì)于修改代碼,僅僅增加代碼就能完成相同的功能,這樣優(yōu)雅和安全很多。
關(guān)于繼承,后面會(huì)單獨(dú)抽出一篇文章進(jìn)行講解。面向?qū)ο蟮牟糠?,我們就講這些,感興趣的小伙伴可以自行查閱資料擴(kuò)展。下一篇文章,我們將來(lái)學(xué)一下js中常用的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)類(lèi)型, 敬請(qǐng)期待。