面向?qū)ο?/h2>

javascript在ES6之前是沒(méi)有辦法定義一個(gè)類的,使用構(gòu)造函數(shù)模擬類的概念 ,class

? ES6已經(jīng)有類? class

什么是面向?qū)ο?

面向?qū)ο缶褪悄7氯祟惖男袨槿プ鲆恍┦虑?/p>

使用js得到一個(gè)對(duì)象有幾種方式

? ? ? ? ? ? 第一種得到對(duì)象的方式

var ?p=new object();

? ? ? ? ? ? ?第二種得到對(duì)象的方式

json 簡(jiǎn)單一種javascript對(duì)象

使用工廠模式的方案來(lái)解決代碼的冗余的問(wèn)題

//第一種方式

var person = new Object();

person.age = 18;

person.name = "小紅";

person.say = function() {

//必須加this,指向person對(duì)象所定義的屬性

alert("我的名字是:"+this.name+",我今年"+this.age+"歲了");

}

person.say();

使用這種定義的方式,雖然可以定義一個(gè)對(duì)象,但是因?yàn)闆](méi)有類的約束,所以無(wú)法實(shí)現(xiàn)

對(duì)象的重復(fù)使用,如存在 10 個(gè)人,就要定義 10 個(gè) person,太過(guò)于麻煩了,在操作過(guò)程中存

在問(wèn)題

使用 json? 得到

var person = {

name : "小雷",

age : 18,

say : function() {

alert("我的名字是:"+this.name+",我今年"+this.age+"歲了");


封裝--Javascript? 的 原型(prototype )

function Person() {

}

//使用原型來(lái)給對(duì)象賦值

//這樣就講一個(gè)對(duì)象的屬性和方法放在了該對(duì)象的原型中

//外界是無(wú)法訪問(wèn)到這樣數(shù)據(jù)的

Person.prototype.name = "劉帥哥";

Person.prototype.age = 18;

Person.prototype.say = function() {

alert("我的名字是:"+this.name+",我今年"+this.age+"歲了");

}

var p1 = new Person();

p1.say();//正常訪問(wèn)了

say();//報(bào)錯(cuò)了

原型是 js 中非常特殊一個(gè)對(duì)象,當(dāng)一個(gè)函數(shù)創(chuàng)建之后,會(huì)隨之就產(chǎn)生一個(gè)原型對(duì)象,當(dāng)

通過(guò)這個(gè)函數(shù)的構(gòu)造函數(shù)創(chuàng)建了一個(gè)具體的對(duì)象之后,在這個(gè)具體的對(duì)象中就會(huì)有一個(gè)屬性

指向原型。這就是原型的概念


常見(jiàn)的 原型檢測(cè)方式

可以通過(guò)如下的方式檢測(cè)p1是不是指向Person的原型對(duì)象

alert(Person.prototype.isPrototypeOf(p1))

//檢測(cè)p1的構(gòu)造器是否指向Person對(duì)象

alert(p1.constructor == Person)

//檢測(cè)某個(gè)屬性是不是自己內(nèi)存中的

alert(p1.hasOwnProperty("name"));

alert(p2.hasOwnProperty("name"))

同樣我們可以使用 delete 語(yǔ)句來(lái)刪除我們賦予對(duì)象的自己屬性(注意:原型中的是無(wú)法

刪除的),如

//可以使用delete語(yǔ)句刪除對(duì)象中自己的屬性,那么就會(huì)找到原型中的值

delete p2.name;

p2.say();

alert(p2.hasOwnProperty("name"));

檢測(cè)在某個(gè)對(duì)象自己或者對(duì)應(yīng)的原型中是否存在某個(gè)屬性。

alert("name" in p1);//true

delete p2.name;//雖然刪除了自己的name屬性,但是原型中有

alert("name" in p2);//true

//原型和自己中都沒(méi)有sex屬性

alert("sex" in p1);//false

那么問(wèn)題來(lái)了?如果檢測(cè)只在原型中,不在自己中的屬性呢?(提問(wèn))

//我們可以自己寫代碼來(lái)測(cè)試屬性不在自己,在原型中

function hasPrototypeProperty(obj,prop) {

if (!obj.hasOwnProperty(prop)) {

if (prop in obj) {

return true;

}

}

return false;

}

alert(hasPrototypeProperty(p1,"name"));

alert(hasPrototypeProperty(p2,"name"));


原型 重寫

在上面的寫法中,我們已經(jīng)解決了大量的問(wèn)題,使用原型。但是如果我們的對(duì)象中存在

大量的屬性或者方法的時(shí)候,使用上面的方式,感覺(jué)要寫大量的【對(duì)象.prototype.屬性名 】

這樣的代碼,感覺(jué)不是很好,那么我們可以使用 json 的方式來(lái)寫:

function Person() {

}

Person.prototype = {

name : "劉帥哥",

age : 18,

say : function() {

alert("我的名字是:"+this.name+",我今年"+this.age+"歲了");

}

}

var p1 = new Person();

p1.say()

var p2 = new Person();

p2.name = "張三";

p2.age = 20;

p2.say();

但是這種寫法,我們是將該對(duì)象的原型覆蓋(注意:這兩種寫法不一樣的,第一種是擴(kuò)

充,第二種是覆蓋),就會(huì)出現(xiàn)如下的問(wèn)題:

function Person() {

}

Person.prototype = {

constructor:Person,//手動(dòng)指向Person

name : "劉帥哥",

age : 18,

say : function() {

alert("我的名字是:"+this.name+",我今年"+this.age+"歲了");

}

}

var p1 = new Person();

p1.say()

var p2 = new Person();

p2.name = "張三";

p2.age = 20;

p2.say();

//此時(shí)p1的構(gòu)造器不在指向Person,而是指向了Object

//因?yàn)槲覀兏采w了Person的原型,所以如果constructor比較重要的話,

//我們可以手動(dòng)指向

alert(p1.constructor == Person)

此時(shí)就沒(méi)有問(wèn)題了。但是原型重寫會(huì)給我們帶來(lái)一些非常有趣的現(xiàn)象。下面我們來(lái)研究

研究。

function Person() {

}

var p1 = new Person();

Person.prototype.sayHello = function() {

alert("我的名字是:"+this.name+",我今年"+this.age+"歲了");

}

// p1.sayHello();

Person.prototype = {

constructor:Person,//手動(dòng)指向Person

name : "劉帥哥",

age : 18,

say : function() {

alert("我的名字是:"+this.name+",我今年"+this.age+"歲了");

}

}

var p2 = new Person();

p2.name = "張三";

p2.age = 20;

p1.sayHello();//此時(shí)找不到name和age,但是代碼正確

p2.say();//正確

p1.say();//錯(cuò)誤,因?yàn)樵椭貙懥?/p>

p2.sayHello();//錯(cuò)誤

繼承-- 原型創(chuàng)建對(duì)象

在面向?qū)ο蟮恼Z(yǔ)言中,存在了三大特性—封裝、繼承、多態(tài)。我們前面一直說(shuō) javascript

是面向?qū)ο蟮恼Z(yǔ)言,那么它應(yīng)該也有面向?qū)ο笳Z(yǔ)言這些特性,上面我們看來(lái)封裝,那么下面

我們來(lái)研究繼承。

繼承,望名而知意,就是我們現(xiàn)實(shí)社會(huì)中的子孫后代繼承了父輩的財(cái)富,我們一直在說(shuō),

面向?qū)ο蟮恼Z(yǔ)言就是在模擬現(xiàn)實(shí)世界,通過(guò)模擬現(xiàn)實(shí)世界來(lái)編程,那么在 javascript 中,如

何理解繼承,如何實(shí)現(xiàn)繼承呢?

實(shí)現(xiàn)繼承

//定義一個(gè)父類

function Parent() {

this.pv = "parent";

}

Parent.prototype.showParent = function() {

alert(this.pv);

}

//定義一個(gè)子類

function Son() {

this.sv = "Son";

}

//使用原型鏈來(lái)實(shí)現(xiàn)繼承

Son.prototype = new Parent();

Son.prototype.showSon = function() {

alert(this.sv);

}

var s1 = new Son();

s1.showParent();

s1.showSon();

但是使用原型鏈實(shí)現(xiàn)繼承要注意以下一些問(wèn)題:

1、 不要在設(shè)定了原型鏈之后,再原型重寫

2、 一定要在原型鏈賦值之后才能添加或者覆蓋方法

注意:javascript 中存在重寫,但是沒(méi)有重載

原型 鏈繼承的缺陷

原型鏈繼承存在的缺陷就是:

1、 無(wú)法從子類中調(diào)用父類的構(gòu)造函數(shù),這樣就沒(méi)有辦法把子類中屬性賦值給父類。

2、 父類中屬性是在子類的原型中的,這違背了我們前面所講的封裝的理念(屬性在對(duì)

象中,方法在原型中),會(huì)出現(xiàn)前面值的混淆問(wèn)題。

所以我們一般都不會(huì)使用單純的原型鏈來(lái)實(shí)現(xiàn)繼承。

基于 偽裝實(shí)現(xiàn)繼承

在前面我們學(xué)習(xí)了 call 和 apply 方法,這兩個(gè)方法我們知道可以使用:函數(shù)名.call(上下

文,參數(shù)列表),或:者函數(shù)名.apply(上下文,參數(shù)數(shù)組)的方式來(lái)調(diào)用函數(shù),這樣我們可以通過(guò)

第一個(gè)參數(shù)上下文來(lái)改變調(diào)用函數(shù)的對(duì)象,那么基于這兩個(gè)方法,我們可以實(shí)現(xiàn)一個(gè)基于偽

裝的繼承。

//定義一個(gè)父類

function Parent() {

this.pv = "parent";

}

//定義一個(gè)子類

function Son() {

this.sv = "Son";

Parent.call(this);//注意:此時(shí)的this指的是Son的對(duì)象

//那么就是Son對(duì)象調(diào)用Parent函數(shù)

}

var s1 = new Son();

alert(s1.pv);

在子類中的 this 指的就是子類實(shí)例化后的對(duì)象本身,當(dāng)我們?cè)谧宇愔惺褂?call 方法調(diào)用

父類后,就相當(dāng)于將父類的構(gòu)造方法綁定到了子類的對(duì)象身上,這樣就偽裝了子類可以使用

父類的構(gòu)造方法,完成了繼承。

偽裝 的缺陷

基于偽裝的繼承解決了基于原型鏈的問(wèn)題,但不是說(shuō)它就十分完美,它也存在了問(wèn)題,

如下:

由于使用偽造的方式繼承,子類的原型不會(huì)指向父類,所以父類中寫在原型中的方法不

會(huì)被子類繼承,所以子類調(diào)用不到父類的方法。

解決的辦法就是將父類的方法放到子類中來(lái),但是這樣的又違背了封裝的理念。

ECMAScript6— 面向 對(duì)象

ECMAScript6 是下一代 Javascript 標(biāo)準(zhǔn),這個(gè)標(biāo)準(zhǔn)將在 2015 年 6 月得到批準(zhǔn)。ES6 是

Javascript 的一個(gè)重大的更新,并且是自 2009 年發(fā)布 ES5 以來(lái)的第一次更新。 它將會(huì)在主

要的 Javascript 引擎實(shí)現(xiàn)以下新的特性

class? 關(guān)鍵字

ES6 在面向?qū)ο笫褂昧诵绿匦院驼Z(yǔ)法來(lái)實(shí)現(xiàn),啟用之前的保留字 class 來(lái)申明類,因此

在 ES6 之后,JavaScript 就有了類的定義和實(shí)現(xiàn):

雖然 ES6 的 Class 本質(zhì)上還是語(yǔ)法糖,但這么設(shè)計(jì)有它的目的,首先這樣的書寫形式是

的 JavaScript 的面向?qū)ο蟮膶懛ň秃?Java(一門后端面向?qū)ο蟮恼Z(yǔ)言)看起來(lái)很是類似了。其

次了簡(jiǎn)化了寫法,還讓我們之前將代碼書寫在構(gòu)造函數(shù)外面的那種方法不存在了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容