最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

js中的面向?qū)ο笕腴T

 更新時間:2017年03月06日 14:57:32   作者:陳水水  
本文主要介紹了js中的面向?qū)ο蟮南嚓P(guān)知識,具有很好的參考價值。下面跟著小編一起來看下吧

什么是對象

我們先來看高程三中是如何對對象進(jìn)行定義的

"無序?qū)傩缘募希鋵傩钥梢园ɑ局?、對象或者函?shù)",對象是一組沒有特定順序的的值。對象的沒個屬性或方法都有一個俄名字,每個名字都映射到一個值。

簡單來理解對象就是由屬性和方法來組成的

面向?qū)ο蟮奶攸c

封裝

對于一些功能相同或者相似的代碼,我們可以放到一個函數(shù)中去,多次用到此功能時,我們只需要調(diào)用即可,無需多次重寫。

在這里我們可以理解為創(chuàng)造對象的幾種模式:單例模式,工廠模式,構(gòu)造函數(shù)模式,原型模式等。

繼承

子類可以繼承父類的屬性和方法

多態(tài)(重載和重寫)

  • 重載:嚴(yán)格意義上說js中沒有重載的功能,不過我們可以通過判斷函數(shù)的參數(shù)的不同來實現(xiàn)不同的功能來模擬重載。
  • 重寫:子類可以改寫父類的屬性和方法

javascript中的封裝

單例模式

小王在一個小公司,就自己一個前端,所以他寫js都是這樣的

var a = 1;
function getNum(){
 return 1;
}

后來公司又招了個前端小明,于是變成他們2個一起寫同一個js了。一天小王發(fā)現(xiàn)自己寫的getNum方法出問題了,原來是小華寫的js中也有個getNum的函數(shù),代碼合并后把他的覆蓋掉了,于是便找小華理論去,經(jīng)過一番妥協(xié)后,兩人都把自己的代碼改了改

var xiaoming = {
 num:1,
 getNum:function(){
 return 1;
 }
}
var xiaohua = {
 num:2,
 getNum: function(){
 return 2;
 }
}

這就是我們所謂的單例模式(命名空間)

我們把描述同一個事物的方法或者屬性放到同一個對象里,不同事物之間的方法或者屬性名相同相互也不會發(fā)生沖突。

單例模式的優(yōu)劣

1.使用單例模式,我們可以實現(xiàn)簡單的模塊化開發(fā)

var utils = {
getCss:function(){
 //code
},
getByClass:function(){
 //code
},
setCss:function(){
 //code
}
}

我們可以把自己寫好的工具方法放到一個單獨的js文件中,然后直接引入即可。

2.避免了全局變量名的沖突

需要注意的是,我們在引入各個模塊的時候,需要注意引入的順序,引入順序是按照各模塊之間的相互依賴進(jìn)行前后排列的;

3.缺點:

  • 單例模式只是一定程度上避免了變量名的沖突,但并不能徹底解決此問題,而且在不同的對象下,我們可能會有很多功能相同的代碼,最終造成大量的冗余代碼。
  • 單例模式讓每個對象有了自己獨立的命名空間,但是并不能批量生產(chǎn)的問題,每一個新的對象都要重新寫一份一模一樣的代碼。
var person1 = {
 name:'小明',
 age:24,
 showName:function(){
  console.log('我的名字是:'+this.name)
 }
};
var person1 = {
 name:'小華',
 age:25,
 showName:function(){
  console.log('我的名字是:'+this.name)
 }
};

工廠模式

1.工廠模式其實就是把需要一個個的編寫的對象,放在一個函數(shù)中統(tǒng)一的進(jìn)行創(chuàng)建,說白了就是普通函數(shù)的封裝。

2.工廠模式總共3步驟:

1)引進(jìn)原材料 --- 創(chuàng)建一個空對象

2)加工原材料 --- 加工對象:給對象添加屬性和方法;

3)輸出產(chǎn)品 --- 返回對象:return 對象;

function CreatePerson(name,age){
 var obj={};//1.創(chuàng)建一個空對象
 //2.加工對象
 obj.name=name;
 obj.age=age;
 obj.showName=function(){
  console.log('我的名字是:'+this.name)
 };
 return obj;//3.輸出對象;
}
var person1 = CreatePerson('小明',23)
var person2 = CreatePerson('小華',23)
person1.showName(); //我的名字是:小明
person2.showName(); //我的名字是:小華

工廠模式的優(yōu)缺點

既然叫工廠模式,它就和我們周圍的工廠一樣,我們只需要把原材料放進(jìn)去,就能得到我們需要的產(chǎn)品了。

工廠模式也解決了單例模式的批量生產(chǎn)的問題,避免了單例模式中的大量冗余代碼,進(jìn)行系統(tǒng)的封裝,提高代碼的重復(fù)利用率

不過工廠模式跟我們js內(nèi)置類的調(diào)用方法不同

構(gòu)造函數(shù)模式

  • 可以創(chuàng)建一個自定義的類,并且可以new出實例
  • 構(gòu)造函數(shù)做的就是類和實例打交道。
 //構(gòu)造函數(shù):首字母大寫(約定俗成);
 function CreatePerson(name,age){ //創(chuàng)建一個自定義的類
 //構(gòu)造函數(shù)中的this,都是new出來的實例
 //構(gòu)造函數(shù)中存放的都是私有的屬性和方法;
 this.name=name;
 this.age=age;
 this.showName=function(){
  console.log('我的名字是:'+this.name)
 }
 }
 //實例1
 var person1 = new CreatePerson('小明',25)
 //實例2
 var person2 = new CreatePerson('小華',24)

這里說一下工廠模式和構(gòu)造函數(shù)模式的區(qū)別:

1. 在調(diào)用的時候不同:

工廠模式:調(diào)用的時候,只是普通函數(shù)的調(diào)用createPerson();

構(gòu)造函數(shù)模式:new CreatePerson();

2. 在函數(shù)體內(nèi)不同:

工廠模式有三步:1)創(chuàng)建對象 2)加工對象 3)返回對象;

構(gòu)造函數(shù)模式只有1步: 只有加工對象; 因為系統(tǒng)默認(rèn)會為其創(chuàng)建對象和返回對象;

3. 構(gòu)造函數(shù)默認(rèn)給我們返回了一個對象,如果我們非要自己手動返回的話:

    (1)手動返回的是字符串類型:對以前實例上的屬性和方法沒有影響;

    (2)手動返回的是引用數(shù)據(jù)類型:以前實例身上的屬性和方法就被覆蓋了;實例無法調(diào)用屬性和方法;

構(gòu)造函數(shù)的方法都是私有方法,每個實例調(diào)用的都是自己私有的方法,同樣也會有許多重復(fù)的代碼。

我們可以使用原型模式來解決每個實例中都有相同方法的函數(shù)的問題

原型模式

 function CreatePerson(name,age){ 
 this.name=name;
 this.age=age;
 }
 // 我們把公有的方法放到函數(shù)的原型鏈上
 CreatePerson.prototype.showName = function(){
  console.log('我的名字是:'+this.name)
 } 
 var person1 = new CreatePerson('小明',25) 
 var person2 = new CreatePerson('小華',24)
 person1.showName() //小明

###### 原型模式的關(guān)鍵:

1)每個函數(shù)數(shù)據(jù)類型(普通函數(shù),類)上,都有一個屬性,叫prototype。

2)prototype這個對象上,天生自帶一個屬性,叫constructor:指向當(dāng)前這個類;

3)每個對象數(shù)據(jù)類型(普通對象,prototype,實例)上都有一個屬性,

   叫做__proto__:指向當(dāng)前實例所屬類的原型;

這3句話理解了,下邊的東西就可以不用看了 //手動滑稽

通過例子我們來看這幾句話是什么意思

 function CreatePerson(name,age){
 this.name=name;
 this.age=age
}
CreatePerson.prototype.showName=function(){
  console.log('我的名字是:'+this.name)
}
var person1 = new CreatePerson('小明',25);
console.dir(person1)

在chrome瀏覽器控制臺中顯示

從圖中可以看出,person1這個對象上有name和age兩個屬性,person1的__proto__指向了它的構(gòu)造函數(shù)(CreatePerson)的prototype上,而且還有一個showName的方法。

并且它們中有一條鏈關(guān)聯(lián)著: person1.__proto__ === CreatePerson.prototype

接著來看

function Foo(){
 this.a=1;
}
Foo.prototype.a=2;
Foo.prototype.b=3;
var f1 = new Foo; //沒有參數(shù)的話括號可以省略
console.log(f1.a) //1
console.log(f1.b) // 3

以這個為例,當(dāng)我們查找f1.a時,因為f1中有這個屬性,所以我們得出 f1.a=1;當(dāng)我們查找f1.b時,f1中沒有這個屬性,我們便順著f1.__proto__這條鏈去它的構(gòu)造器的prototype上找,所以我們得出了 f1.b = 3;

接著來說,F(xiàn)oo.prototype是個對象,那么它的__proto__指向哪里呢

還記的剛剛說的那句

每個對象數(shù)據(jù)類型(普通對象,prototype,實例)上都有一個屬性,叫做__proto__:指向當(dāng)前實例所屬類的原型

此外,我們應(yīng)該知道

每一個對象都是function Object這個構(gòu)造函數(shù)的實例

所以我們可以接著還原這個原型圖

等等,圖上貌似多了個個Object.prototype.__proto__ 指向了null,這是什么鬼?

我們這么來理解,Object.prototype是個對象,那么它的__proto__指向了它的構(gòu)造函數(shù)的prototype上,最后發(fā)現(xiàn)了還是指向它自身,這樣轉(zhuǎn)了個圈貌似是無意義的,于是便指向了null還沒完,我們發(fā)現(xiàn)對象都是函數(shù)(構(gòu)造器)創(chuàng)造出來的,那么函數(shù)是誰創(chuàng)造的呢?石頭里蹦出來的么?

在js中,function都是由function Function這個構(gòu)造器創(chuàng)造的,每一個函數(shù)都是Function的實例

現(xiàn)在基本上我們就能得出了完整的原型圖了

是不是有點亂?根據(jù)我們剛剛講的是能把這個圖理順的,這里需要注意下,F(xiàn)unction.__proto__是指向它的prototype的

多說一點,判斷數(shù)據(jù)類型的方法時,我們知道有個instanceof的方法

比如

A instanceof B

instanceof判斷的規(guī)則就是:

沿著A的__proto__這條線查找的同時沿著B的prototype這條線來找,如果兩條線能找到同一個引用(對象),那么就返回true。如果找到終點還未重合,則返回false。

再來看我們之前的那個例子

function Foo(){
 this.a=1;
}
Foo.prototype.a=2;
Foo.prototype.b=3;
var f1 = new Foo; //沒有參數(shù)的話括號可以省略
console.log(f1.a) //1
console.log(f1.b) // 3

當(dāng)我們查找f1.a時,因為f1中有這個屬性,所以我們得出 f1.a=1;

當(dāng)我們查找f1.b時,f1中沒有這個屬性,我們便順著f1.__proto__這條鏈去它的構(gòu)造器的prototype上找,所以我們得出了 f1.b = 3;

當(dāng)我們查找一個對象的屬性時,先在這個對象的私有空間內(nèi)查找,如果沒找到,就順著對象的__proto__這條鏈去它的構(gòu)造器的ptototype上查找,如果還沒找到,接著沿__proto__向上查找,直到找到Object.prototype還沒有的話,這個值就為undefined,這就是所謂的原型鏈

列舉下網(wǎng)頁中的一些相關(guān)的原型鏈

有興趣的同學(xué)可自行通過瀏覽器控制臺看看我們常用的方法都是在哪個類上定義的,比如getElementsByTagName,addEventListener等等

繼承

在這里就主要說一下組合繼承(call + 原型鏈)

function Father(){
 this.xxx= 80;
 this.yyy= 100;
 this.drink = function(){}
}
Father.prototype.zzz= function(){}
var father = new Father;
function Son(){
 this.aaa = 120;
 this.singing = function(){}
 Father.call(this);
}
Son.prototype = new Father;
Son.prototype.constructor = Son;
var son = new Son
console.dir(son)

這么寫有個不好的地方就是:子類私有的屬性中有父類私有的屬性,子類公有的屬性中也有父類私有的屬性;

根據(jù)我們前邊的知識,我們可以這么來改寫

function Father(){
 this.xxx= 80;
 this.yyy= 100;
 this.drink = function(){}
}
Father.prototype.zzz= function(){}
var father = new Father;
function Son(){
 this.aaa = 120;
 this.singing = function(){}
 Father.call(this); //利用call繼承了父類的私有屬性
}
Son.prototype.__proto__ = Father.prototype
var son = new Son
console.dir(son)

最后來一張思維導(dǎo)圖

圖片如果放大也看不清的話 下載地址

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!

相關(guān)文章

  • gulp-uglify 與gulp.watch()配合使用時報錯(重復(fù)壓縮問題)

    gulp-uglify 與gulp.watch()配合使用時報錯(重復(fù)壓縮問題)

    gulp是基于Nodejs的自動任務(wù)運行器,gulp 和 grunt 非常類似,但相比于 grunt 的頻繁 IO 操作,gulp 的流操作,能更快地更便捷地完成構(gòu)建工作。今天在學(xué)習(xí)gulp時遇到當(dāng)用gulp.watch來監(jiān)聽js文件的變動時出現(xiàn)重復(fù)壓縮問題,下面小編給大家解答下
    2016-08-08
  • bootstrap模態(tài)框?qū)崿F(xiàn)拖拽效果

    bootstrap模態(tài)框?qū)崿F(xiàn)拖拽效果

    這篇文章主要為大家詳細(xì)介紹了bootstrap模態(tài)框?qū)崿F(xiàn)拖拽效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 前端如何寫一個大文件上傳組件詳細(xì)步驟

    前端如何寫一個大文件上傳組件詳細(xì)步驟

    在現(xiàn)代Web應(yīng)用中,大文件上傳是一個常見的需求,尤其是在云存儲、社交媒體和協(xié)作平臺等領(lǐng)域,這篇文章主要介紹了前端如何寫一個大文件上傳組件詳細(xì)步驟,需要的朋友可以參考下
    2025-04-04
  • bootstrap table列和表頭對不齊的解決方法

    bootstrap table列和表頭對不齊的解決方法

    這篇文章主要為大家詳細(xì)介紹了bootstrap table列和表頭對不齊的解決方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • javascript遞歸函數(shù)定義和用法示例分析

    javascript遞歸函數(shù)定義和用法示例分析

    這篇文章主要介紹了javascript遞歸函數(shù)定義和用法示例分析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • JS跳轉(zhuǎn)手機(jī)站url的若干注意事項

    JS跳轉(zhuǎn)手機(jī)站url的若干注意事項

    去年年底開發(fā)了一個手機(jī)站平臺,遇到了很多坎,今天小編給大家分享下使用JS跳轉(zhuǎn)手機(jī)站url的若干注意事項,需要的朋友參考下吧
    2017-10-10
  • 簡單談?wù)凧S中的正則表達(dá)式

    簡單談?wù)凧S中的正則表達(dá)式

    下面小編就為大家?guī)硪黄唵握務(wù)凧S中的正則表達(dá)式。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • JavaScript 語法集錦 腳本之家基礎(chǔ)推薦

    JavaScript 語法集錦 腳本之家基礎(chǔ)推薦

    JavaScript語法集錦是對javascript常用函數(shù)的一些小結(jié),比較實用,建議收藏,方便查找需要的資料。
    2009-11-11
  • JavaScript 數(shù)組中插入元素的實例方法

    JavaScript 數(shù)組中插入元素的實例方法

    這篇文章主要介紹了如何在 JavaScript 數(shù)組中插入元素,在本文中,我們學(xué)習(xí)了使用?splice()?方法將元素添加到數(shù)組的開始、末尾或任何位置的各種方法,需要的朋友可以參考下
    2023-09-09
  • JavaScript閉包的深度剖析與實際應(yīng)用小結(jié)

    JavaScript閉包的深度剖析與實際應(yīng)用小結(jié)

    本文詳細(xì)探討了JavaScript閉包的概念、作用、原理及優(yōu)缺點,閉包允許函數(shù)訪問其詞法作用域中的變量,即使外部函數(shù)已執(zhí)行,閉包有助于解決全局變量污染問題,提供私有變量和方法,但也會導(dǎo)致內(nèi)存占用和內(nèi)存泄露,通過示例,展示了閉包的實現(xiàn)和應(yīng)用場景,感興趣的朋友一起看看吧
    2025-01-01

最新評論

张家口市| 岳阳市| 东宁县| 扶绥县| 合肥市| 塔城市| 长治市| 康保县| 六枝特区| 九龙坡区| 赤水市| 资中县| 安多县| 汉沽区| 临西县| 济南市| 吉首市| 竹北市| 天长市| 洛宁县| 红原县| 临夏市| 白玉县| 眉山市| 怀化市| 嫩江县| 乌鲁木齐市| 台东市| 太和县| 禄丰县| 齐河县| 博白县| 青龙| 滨海县| 合阳县| 通河县| 扶沟县| 达孜县| 苍南县| 诸暨市| 青岛市|