JavaScript 進(jìn)階教程(1)--面向?qū)ο缶幊?/h1>

1 學(xué)習(xí)目標(biāo)

理解面向?qū)ο箝_發(fā)思想

掌握 JavaScript 面向?qū)ο箝_發(fā)相關(guān)模式

2.面向?qū)ο蠼榻B

2.1什么是對(duì)象

Everything is object (一切皆對(duì)象)

我們可以從兩個(gè)層次來理解對(duì)象:

(1) 對(duì)象是單個(gè)事物的抽象耳舅。

一本書碌上、一輛汽車倚评、一個(gè)人都可以是對(duì)象浦徊,一個(gè)數(shù)據(jù)庫(kù)、一張網(wǎng)頁(yè)天梧、一個(gè)與遠(yuǎn)程服務(wù)器的連接也可以是對(duì)象盔性。當(dāng)實(shí)物被抽象成對(duì)象,實(shí)物之間的關(guān)系就變成了對(duì)象之間的關(guān)系呢岗,從而就可以模擬現(xiàn)實(shí)情況冕香,針對(duì)對(duì)象進(jìn)行編程蛹尝。

(2) 對(duì)象是一個(gè)容器,封裝了屬性(property)和方法(method)悉尾。

屬性是對(duì)象的狀態(tài)突那,方法是對(duì)象的行為(完成某種任務(wù))。比如构眯,我們可以把動(dòng)物抽象為animal對(duì)象愕难,使用“屬性”記錄具體是那一種動(dòng)物,使用“方法”表示動(dòng)物的某種行為(奔跑惫霸、捕獵猫缭、休息等等)。

在實(shí)際開發(fā)中壹店,對(duì)象是一個(gè)抽象的概念猜丹,可以將其簡(jiǎn)單理解為:數(shù)據(jù)集或功能集。ECMAScript-262 把對(duì)象定義為:無序?qū)傩缘募瞎杪鋵傩钥梢园局瞪渲稀?duì)象或者函數(shù)。 嚴(yán)格來講将塑,這就相當(dāng)于說對(duì)象是一組沒有特定順序的值轮洋。對(duì)象的每個(gè)屬性或方法都有一個(gè)名字,而每個(gè)名字都 映射到一個(gè)值抬旺。

提示:每個(gè)對(duì)象都是基于一個(gè)引用類型創(chuàng)建的弊予,這些類型可以是系統(tǒng)內(nèi)置的原生類型,也可以是開發(fā)人員自定義的類型开财。

2.2什么是面向?qū)ο?/b>

面向?qū)ο蟛皇切碌臇|西汉柒,它只是過程式代碼的一種高度封裝,目的在于提高代碼的開發(fā)效率和可維護(hù)性责鳍。

面向?qū)ο缶幊?—— Object Oriented Programming碾褂,簡(jiǎn)稱 OOP ,是一種編程開發(fā)思想历葛。 它將真實(shí)世界各種復(fù)雜的關(guān)系正塌,抽象為一個(gè)個(gè)對(duì)象,然后由對(duì)象之間的分工與合作恤溶,完成對(duì)真實(shí)世界的模擬乓诽。

在面向?qū)ο蟪绦蜷_發(fā)思想中,每一個(gè)對(duì)象都是功能中心咒程,具有明確分工鸠天,可以完成接受信息、處理數(shù)據(jù)帐姻、發(fā)出信息等任務(wù)稠集。 因此奶段,面向?qū)ο缶幊叹哂徐`活、代碼可復(fù)用剥纷、高度模塊化等特點(diǎn)痹籍,容易維護(hù)和開發(fā),比起由一系列函數(shù)或指令組成的傳統(tǒng)的過程式編程(procedural programming)晦鞋,更適合多人合作的大型軟件項(xiàng)目词裤。

面向?qū)ο笈c面向過程區(qū)別:

面向過程就是親力親為,事無巨細(xì)鳖宾,面面俱到吼砂,步步緊跟,有條不紊鼎文。

面向?qū)ο缶褪钦乙粋€(gè)對(duì)象渔肩,指揮得結(jié)果巢株。

面向?qū)ο髮?zhí)行者轉(zhuǎn)變成指揮者脱盲。

面向?qū)ο蟛皇敲嫦蜻^程的替代阿弃,而是面向過程的封裝贴唇。

面向?qū)ο蟮奶匦裕?/b>

封裝性

繼承性

多態(tài)性


2.3JavaScript?中面向?qū)ο蟮幕倔w現(xiàn)

在 JavaScript 中,所有數(shù)據(jù)類型都可以視為對(duì)象豌拙,當(dāng)然也可以自定義對(duì)象黎烈。 自定義的對(duì)象數(shù)據(jù)類型就是面向?qū)ο笾械念悾?Class )的概念唠粥。

我們以一個(gè)例子來說明面向過程和面向?qū)ο笤诔绦蛄鞒躺系牟煌帯?/p>

假設(shè)我們要處理學(xué)生的成績(jī)表胡嘿,為了表示一個(gè)學(xué)生的成績(jī)蛉艾,面向過程的程序可以用一個(gè)對(duì)象表示:

varstd1 = {name:'張三',score:98}

varstd2 = {name:'李四',score:81}

而處理學(xué)生成績(jī)可以通過函數(shù)實(shí)現(xiàn),比如打印學(xué)生的成績(jī):

functionprintScore(student){

console.log('姓名:'+ student.name +'? '+'成績(jī):'+ student.score)

}

如果采用面向?qū)ο蟮某绦蛟O(shè)計(jì)思想衷敌,我們首選思考的不是程序的執(zhí)行流程勿侯, 而是?Student?這種數(shù)據(jù)類型應(yīng)該被視為一個(gè)對(duì)象,這個(gè)對(duì)象擁有?name?和?score?這兩個(gè)屬性(Property)缴罗。 如果要打印一個(gè)學(xué)生的成績(jī)助琐,首先必須創(chuàng)建出這個(gè)學(xué)生對(duì)應(yīng)的對(duì)象,然后面氓,給對(duì)象發(fā)一個(gè)?printScore?消息兵钮,讓對(duì)象自己把自己的數(shù)據(jù)打印出來。

抽象數(shù)據(jù)行為模板(Class):

functionStudent(name, score){

this.name = name

this.score = score

}

Student.prototype.printScore =function(){

console.log('姓名:'+this.name +'? '+'成績(jī):'+this.score)

}

根據(jù)模板創(chuàng)建具體實(shí)例對(duì)象(Instance):

varstd1 =newStudent('張三',98)

varstd2 =newStudent('李四',81)

實(shí)例對(duì)象具有自己的具體行為(給對(duì)象發(fā)消息):

std1.printScore()// => 姓名:張三? 成績(jī):98

std2.printScore()// => 姓名:李四? 成績(jī) 81

面向?qū)ο蟮脑O(shè)計(jì)思想是從自然界中來的舌界,因?yàn)樵谧匀唤缰芯蚱悾–lass)和實(shí)例(Instance)的概念是很自然的。 Class 是一種抽象概念禀横,比如我們定義的 Class——Student 屁药,是指學(xué)生這個(gè)概念粥血, 而實(shí)例(Instance)則是一個(gè)個(gè)具體的 Student 柏锄,比如酿箭, 張三 和 李四 是兩個(gè)具體的 Student 。

面向?qū)ο蟮脑O(shè)計(jì)思想是:

抽象出 Class

根據(jù) Class 創(chuàng)建 Instance

指揮 Instance 得結(jié)果

面向?qū)ο蟮某橄蟪潭缺群瘮?shù)要高趾娃,因?yàn)橐粋€(gè) Class 既包含數(shù)據(jù)缭嫡,又包含操作數(shù)據(jù)的方法。

3JavaScript如何創(chuàng)建對(duì)象

3.1字面量方式

我們可以直接通過?new Object()?創(chuàng)建:

varperson =newObject()

person.name ='張三'

person.age =18

?

person.sayName =function(){

console.log(this.name)

}

每次創(chuàng)建通過?new Object()?比較麻煩抬闷,所以可以通過它的簡(jiǎn)寫形式對(duì)象字面量來創(chuàng)建:

varperson = {

name:'張三',

age:18,

sayName:function(){

console.log(this.name)

? }

}

上面的寫法是沒有問題的妇蛀,但是假如我們要生成兩個(gè)?person?實(shí)例對(duì)象呢?

varperson1 = {

name:'張三',

age:18,

sayName:function(){

console.log(this.name)

? }

}

?

varperson2 = {

name:'李四',

age:16,

sayName:function(){

console.log(this.name)

? }

}

通過上面的代碼我們不難看出笤成,這樣寫的代碼太過冗余评架,重復(fù)性太高。

3.2簡(jiǎn)單方法的改進(jìn):工廠函數(shù)

我們可以寫一個(gè)函數(shù)炕泳,解決上邊代碼重復(fù)的問題:

functioncreatePerson(name, age){

return{

name: name,

age: age,

sayName:function(){

console.log(this.name)

?? }

? }

}

生成實(shí)例對(duì)象:

varp1 = createPerson('張三',18)

varp2 = createPerson('李四',18)

這樣封裝比上邊的方式好多了纵诞,通過工廠模式我們解決了創(chuàng)建多個(gè)相似對(duì)象代碼冗余的問題, 但卻沒有解決對(duì)象識(shí)別的問題(即怎樣知道一個(gè)對(duì)象的類型)培遵。

3.3更優(yōu)雅的工廠函數(shù):構(gòu)造函數(shù)

一種更優(yōu)雅的工廠函數(shù)就是下面這樣浙芙,構(gòu)造函數(shù):

functionPerson(name, age){

this.name = name

this.age = age

this.sayName =function(){

console.log(this.name)

? }

}

?

varp1 =newPerson('張三',18)

p1.sayName()// => 張三

?

varp2 =newPerson('李四',23)

p2.sayName()// => 李四

在上面的示例中,Person()?函數(shù)取代了?createPerson()?函數(shù)籽腕,但是實(shí)現(xiàn)效果是一樣的嗡呼。 這是為什么呢?

我們注意到皇耗,Person()?中的代碼與?createPerson()?有以下幾點(diǎn)不同之處:

沒有顯示的創(chuàng)建對(duì)象

直接將屬性和方法賦給了?this?對(duì)象

沒有?return?語(yǔ)句

函數(shù)名使用的是大寫的?Person

3.4構(gòu)造函數(shù)代碼執(zhí)行過程

要?jiǎng)?chuàng)建?Person?實(shí)例南窗,則必須使用?new?操作符。 以這種方式調(diào)用構(gòu)造函數(shù)會(huì)經(jīng)歷以下 4 個(gè)步驟:

創(chuàng)建一個(gè)新對(duì)象郎楼。

將構(gòu)造函數(shù)的作用域賦給新對(duì)象(因此 this 就指向了這個(gè)新對(duì)象)矾瘾。

執(zhí)行構(gòu)造函數(shù)中的代碼。

返回新對(duì)象箭启。

下面是具體的偽代碼:

functionPerson(name, age){

// 當(dāng)使用 new 操作符調(diào)用 Person() 的時(shí)候壕翩,實(shí)際上這里會(huì)先創(chuàng)建一個(gè)對(duì)象

// var instance = {}

// 然后讓內(nèi)部的 this 指向 instance 對(duì)象

// this = instance

// 接下來所有針對(duì) this 的操作實(shí)際上操作的就是 instance

?

this.name = name

this.age = age

this.sayName =function(){

console.log(this.name)

? }

?

// 在函數(shù)的結(jié)尾處會(huì)將 this 返回,也就是 instance

// return this

}

3.5構(gòu)造函數(shù)和實(shí)例對(duì)象的關(guān)系

使用構(gòu)造函數(shù)的好處不僅僅在于代碼的簡(jiǎn)潔性傅寡,更重要的是我們可以識(shí)別對(duì)象的具體類型了放妈。 在每一個(gè)實(shí)例對(duì)象中的_proto_中同時(shí)有一個(gè)?constructor?屬性,該屬性指向創(chuàng)建該實(shí)例的構(gòu)造函數(shù):

console.log(p1.constructor === Person)// => true

console.log(p2.constructor === Person)// => true

console.log(p1.constructor === p2.constructor)// => true

對(duì)象的?constructor?屬性最初是用來標(biāo)識(shí)對(duì)象類型的荐操, 但是芜抒,如果要檢測(cè)對(duì)象的類型,還是使用?instanceof?操作符更可靠一些:

console.log(p1instanceofPerson)// => true

console.log(p2instanceofPerson)// => true

總結(jié):

1 構(gòu)造函數(shù)是根據(jù)具體的事物抽象出來的抽象模板托启。

2?實(shí)例對(duì)象是根據(jù)抽象的構(gòu)造函數(shù)模板得到的具體實(shí)例對(duì)象宅倒。

3?每一個(gè)實(shí)例對(duì)象都具有一個(gè)?constructor?屬性,指向創(chuàng)建該實(shí)例的構(gòu)造函數(shù)屯耸。( 此處constructor?是實(shí)例的屬性的說法不嚴(yán)謹(jǐn)拐迁,具體后面的原型會(huì)講到)

4 可以通過實(shí)例的?constructor?屬性判斷實(shí)例和構(gòu)造函數(shù)之間的關(guān)系蹭劈。(這種方式不嚴(yán)謹(jǐn),推薦使用?instanceof?操作符线召,后面學(xué)原型會(huì)解釋為什么)

3.6構(gòu)造函數(shù)的問題

使用構(gòu)造函數(shù)帶來的最大的好處就是創(chuàng)建對(duì)象更方便了铺韧,但是其本身也存在一個(gè)浪費(fèi)內(nèi)存的問題:

functionPerson(name, age){

this.name = name

this.age = age

this.type ='學(xué)生'

this.sayHello =function(){

console.log('hello '+this.name)

? }

}

?

varp1 =newPerson('王五',18)

varp2 =newPerson('李四',16)

上邊的代碼,從表面看上好像沒什么問題缓淹,但是實(shí)際上這樣做哈打,有一個(gè)很大的弊端。 那就是對(duì)于每一個(gè)實(shí)例對(duì)象讯壶,type?和?sayHello?都是一模一樣的內(nèi)容料仗, 每一次生成一個(gè)實(shí)例,都必須為重復(fù)的內(nèi)容伏蚊,多占用一些內(nèi)存罢维,如果實(shí)例對(duì)象很多,會(huì)造成極大的內(nèi)存浪費(fèi)丙挽。

console.log(p1.sayHello === p2.sayHello)// => false

對(duì)于這種問題我們可以把需要共享的函數(shù)定義到構(gòu)造函數(shù)外部:

functionsayHello=function(){

console.log('hello '+this.name)

}

?

functionPerson(name, age){

this.name = name

this.age = age

this.type ='學(xué)生'

this.sayHello = sayHello

}

?

varp1 =newPerson('王五',18)

varp2 =newPerson('李四',16)

?

console.log(p1.sayHello === p2.sayHello)// => true

這樣確實(shí)可以了肺孵,但是如果有多個(gè)需要共享的函數(shù)的話就會(huì)造成全局命名空間沖突的問題。如何解決這個(gè)問題呢颜阐?你肯定想到了可以把多個(gè)函數(shù)放到一個(gè)對(duì)象中用來避免全局命名空間沖突的問題:

varfns = {

sayHello:function(){

console.log('hello '+this.name)

? },

sayAge:function(){

console.log(this.age)

? }

}

?

functionPerson(name, age){

this.name = name

this.age = age

this.type ='學(xué)生'

this.sayHello = fns.sayHello

this.sayAge = fns.sayAge

}

?

varp1 =newPerson('王五',18)

varp2 =newPerson('李四',16)

?

console.log(p1.sayHello === p2.sayHello)// => true

console.log(p1.sayAge === p2.sayAge)// => true

至此平窘,我們利用自己的方式基本上解決了構(gòu)造函數(shù)的內(nèi)存浪費(fèi)問題。 但是代碼看起來還是那么的格格不入凳怨,那有沒有更好的方式呢瑰艘?

4原型

4.1更好的解決方案:prototype

Javascript 規(guī)定,每一個(gè)構(gòu)造函數(shù)都有一個(gè)?prototype?屬性肤舞,指向另一個(gè)對(duì)象紫新。 這個(gè)對(duì)象的所有屬性和方法,都會(huì)被構(gòu)造函數(shù)的實(shí)例繼承李剖。

這也就意味著芒率,我們可以把所有對(duì)象實(shí)例需要共享的屬性和方法直接定義在?prototype?對(duì)象上。

functionPerson(name, age){

this.name = name

this.age = age

}

?

console.log(Person.prototype)

?

Person.prototype.type ='學(xué)生'

?

Person.prototype.sayName =function(){

console.log(this.name)

}

?

varp1 =newPerson(...)

varp2 =newPerson(...)

?

console.log(p1.sayName === p2.sayName)// => true

這時(shí)所有實(shí)例的?type?屬性和?sayName()?方法篙顺, 其實(shí)都是同一個(gè)內(nèi)存地址偶芍,指向?prototype?對(duì)象,因此就提高了運(yùn)行效率德玫。

構(gòu)造函數(shù)匪蟀、實(shí)例、原型三者之間的關(guān)系:


任何函數(shù)都有一個(gè)?prototype?屬性宰僧,該屬性是一個(gè)對(duì)象材彪。

functionF(){}

console.log(F.prototype)// => object

?

F.prototype.sayHi =function(){

console.log('hi!')

}

構(gòu)造函數(shù)的?prototype?對(duì)象默認(rèn)都有一個(gè)?constructor?屬性,指向?prototype?對(duì)象所在函數(shù)。

console.log(F.constructor === F)// => true

通過構(gòu)造函數(shù)得到的實(shí)例對(duì)象內(nèi)部會(huì)包含一個(gè)指向構(gòu)造函數(shù)的?prototype?對(duì)象的指針?__proto__段化。

varinstance =newF()

console.log(instance.__proto__ === F.prototype)// => true

`__proto__` 是非標(biāo)準(zhǔn)屬性嘁捷。

實(shí)例對(duì)象可以直接訪問原型對(duì)象成員:

instance.sayHi()// => hi!

總結(jié):

任何函數(shù)都具有一個(gè)?prototype?屬性,該屬性是一個(gè)對(duì)象穗泵。

構(gòu)造函數(shù)的?prototype?對(duì)象默認(rèn)都有一個(gè)?constructor?屬性普气,指向?prototype?對(duì)象所在函數(shù)谜疤。

通過構(gòu)造函數(shù)得到的實(shí)例對(duì)象內(nèi)部會(huì)包含一個(gè)指向構(gòu)造函數(shù)的?prototype?對(duì)象的指針?__proto__佃延。

所有實(shí)例都直接或間接繼承了原型對(duì)象的成員。

4.2屬性成員的搜索原則:原型鏈

了解了?構(gòu)造函數(shù)-實(shí)例-原型對(duì)象?三者之間的關(guān)系后夷磕,接下來我們來解釋一下為什么實(shí)例對(duì)象可以訪問原型對(duì)象中的成員履肃。

每當(dāng)代碼讀取某個(gè)對(duì)象的某個(gè)屬性時(shí),都會(huì)執(zhí)行一次搜索坐桩,目標(biāo)是具有給定名字的屬性尺棋。

搜索首先從對(duì)象實(shí)例本身開始。

如果在實(shí)例中找到了具有給定名字的屬性绵跷,則返回該屬性的值膘螟。

如果沒有找到,則繼續(xù)搜索指針指向的原型對(duì)象碾局,在原型對(duì)象中查找具有給定名字的屬性荆残。

如果在原型對(duì)象中找到了這個(gè)屬性,則返回該屬性的值净当。

也就是說内斯,在我們調(diào)用?person1.sayName()?的時(shí)候,會(huì)先后執(zhí)行兩次搜索:

首先像啼,解析器會(huì)問:“實(shí)例 person1 有 sayName 屬性嗎俘闯?”答:“沒有。

然后忽冻,它繼續(xù)搜索真朗,再問:“ person1 的原型有 sayName 屬性嗎?”答:“有僧诚。

于是蜜猾,它就讀取那個(gè)保存在原型對(duì)象中的函數(shù)。

當(dāng)我們調(diào)用 person2.sayName() 時(shí)振诬,將會(huì)重現(xiàn)相同的搜索過程蹭睡,得到相同的結(jié)果。

這就是多個(gè)對(duì)象實(shí)例共享原型所保存的屬性和方法的基本原理赶么。

總結(jié):

先在自己身上找肩豁,找到即返回。

自己身上找不到,則沿著原型鏈向上查找清钥,找到即返回琼锋。

如果一直到原型鏈的末端還沒有找到,則返回?undefined祟昭。

4.3實(shí)例對(duì)象讀寫原型對(duì)象成員

讀嚷瓶病:

先在自己身上找,找到即返回篡悟。

自己身上找不到谜叹,則沿著原型鏈向上查找,找到即返回搬葬。

如果一直到原型鏈的末端還沒有找到荷腊,則返回?undefined。

值類型成員寫入(實(shí)例對(duì)象.值類型成員 = xx):

當(dāng)實(shí)例期望重寫原型對(duì)象中的某個(gè)普通數(shù)據(jù)成員時(shí)實(shí)際上會(huì)把該成員添加到自己身上急凰。

也就是說該行為實(shí)際上會(huì)屏蔽掉對(duì)原型對(duì)象成員的訪問女仰。

引用類型成員寫入(實(shí)例對(duì)象.引用類型成員 = xx):同上。

復(fù)雜類型修改(實(shí)例對(duì)象.成員.xx = xx):

同樣會(huì)先在自己身上找該成員抡锈,如果自己身上找到則直接修改疾忍。

如果自己身上找不到,則沿著原型鏈繼續(xù)查找床三,如果找到則修改一罩。

如果一直到原型鏈的末端還沒有找到該成員,則報(bào)錯(cuò)(實(shí)例對(duì)象.undefined.xx = xx)勿璃。

4.4更簡(jiǎn)單的原型語(yǔ)法

我們注意到擒抛,前面例子中每添加一個(gè)屬性和方法就要敲一遍?Person.prototype?。?為減少不必要的輸入补疑,更常見的做法是用一個(gè)包含所有屬性和方法的對(duì)象字面量來重寫整個(gè)原型對(duì)象:

functionPerson(name, age){

this.name = name

this.age = age

}

?

Person.prototype = {

type:'學(xué)生',

sayHello:function(){

console.log('我叫'+this.name +'歧沪,我今年'+this.age +'歲了')

? }

}

在該示例中,我們將?Person.prototype?重置到了一個(gè)新的對(duì)象莲组。 這樣做的好處就是為?Person.prototype?添加成員簡(jiǎn)單了诊胞,但是也會(huì)帶來一個(gè)問題,那就是原型對(duì)象丟失了?constructor?成員锹杈。

所以撵孤,我們?yōu)榱吮3?constructor?的指向正確,建議的寫法是

functionPerson(name, age){

this.name = name

this.age = age

}

Person.prototype = {

constructor: Person,// => 手動(dòng)將 constructor 指向正確的構(gòu)造函數(shù)

type:'學(xué)生',

sayHello:function(){

console.log('我叫'+this.name +'竭望,我今年'+this.age +'歲了')

? }

}

4.5原生對(duì)象的原型

所有函數(shù)都有 prototype 屬性對(duì)象邪码。

Object.prototype

Function.prototype

Array.prototype

String.prototype

Number.prototype

Date.prototype

...

為數(shù)組對(duì)象和字符串對(duì)象擴(kuò)展原型方法:

//為內(nèi)置對(duì)象添加原型方法

//我們?cè)谙到y(tǒng)的對(duì)象的原型中添加方法,相當(dāng)于在改變?cè)创a

//我希望字符串中有一個(gè)倒序字符串的方法

String.prototype.myReverse =function(){

for(vari =this.length -1; i >=0; i--) {

console.log(this[i]);

}

};

varstr ="abcdefg";

str.myReverse();

//為Array內(nèi)置對(duì)象的原型對(duì)象中添加方法

Array.prototype.mySort =function(){

for(vari =0; i

for(varj =0; j

if(this[j]

vartemp =this[j];

this[j] =this[j +1];

this[j +1] = temp;

}//end if

}// end for

}//end for

};

vararr = [100,3,56,78,23,10];

arr.mySort();

console.log(arr);

String.prototype.sayHi =function(){

console.log(this+"哈哈,我又變帥了");

};

//字符串就有了打招呼的方法

varstr2 ="小楊";

str2.sayHi();

4.6原型對(duì)象的一些問題

共享數(shù)組

共享對(duì)象

如果真的希望可以被實(shí)例對(duì)象之間共享和修改這些共享數(shù)據(jù)那就不是問題。但是如果不希望實(shí)例之間共享和修改這些共享數(shù)據(jù)則會(huì)出現(xiàn)問題咬清。一個(gè)更好的建議是闭专,最好不要讓實(shí)例之間互相共享數(shù)組或者對(duì)象成員奴潘,一旦修改的話會(huì)導(dǎo)致數(shù)據(jù)的走向很不明確而且難以維護(hù)。

原型對(duì)象使用建議:

私有成員(一般就是非函數(shù)成員)放到構(gòu)造函數(shù)中影钉。

共享成員(一般就是函數(shù))放到原型對(duì)象中画髓。

如果重置了?prototype?記得修正?constructor?的指向。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者

  • 序言:七十年代末平委,一起剝皮案震驚了整個(gè)濱河市奈虾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌廉赔,老刑警劉巖肉微,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異昂勉,居然都是意外死亡浪册,警方通過查閱死者的電腦和手機(jī)扫腺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門岗照,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人笆环,你說我怎么就攤上這事攒至。” “怎么了躁劣?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵迫吐,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我账忘,道長(zhǎng)志膀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任鳖擒,我火速辦了婚禮溉浙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蒋荚。我一直安慰自己戳稽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布期升。 她就那樣靜靜地躺著惊奇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪播赁。 梳的紋絲不亂的頭發(fā)上颂郎,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音容为,去河邊找鬼乓序。 笑死诞吱,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的竭缝。 我是一名探鬼主播房维,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼抬纸!你這毒婦竟也來了咙俩?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤湿故,失蹤者是張志新(化名)和其女友劉穎阿趁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坛猪,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡脖阵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了墅茉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片命黔。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖就斤,靈堂內(nèi)的尸體忽然破棺而出悍募,到底是詐尸還是另有隱情,我是刑警寧澤洋机,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布坠宴,位于F島的核電站,受9級(jí)特大地震影響绷旗,放射性物質(zhì)發(fā)生泄漏喜鼓。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一衔肢、第九天 我趴在偏房一處隱蔽的房頂上張望庄岖。 院中可真熱鬧,春花似錦膀懈、人聲如沸顿锰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)硼控。三九已至,卻和暖如春胳赌,著一層夾襖步出監(jiān)牢的瞬間牢撼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工疑苫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留熏版,地道東北人纷责。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像撼短,于是被迫代替她去往敵國(guó)和親再膳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

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