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

不用構(gòu)造函數(shù)(Constructor)new關(guān)鍵字也能實現(xiàn)JavaScript的面向?qū)ο?/h1>
 更新時間:2013年01月11日 09:10:41   作者:  
JavaScript中的對象模型(object model)并不廣為人知,我們再設(shè)想:假設(shè)JavaScript沒有構(gòu)造函數(shù)或者沒有new關(guān)鍵字會怎樣?事情又會變成什么樣的呢?讓我們推到以前的重來,感興趣的朋友可以詳細了解下
JavaScript中的對象模型(object model)并不廣為人知。我曾寫過一篇關(guān)于他們的博客。之所以不被人所熟知,原因之一就是JavaScript是這些被人廣泛使用的語言中唯一一個通過原型(prototype)來實現(xiàn)繼承的。但是,我認為另一個原因就是這種對象模型非常復(fù)雜,難于解釋。它為什么這么復(fù)雜并且又令人困惑呢?那是因為JavaScript試圖去隱藏它傳統(tǒng)的面向?qū)ο蟮奶匦浴罱K導(dǎo)致了它的雙重人格(譯者注:作者意思是JavaScript既有面向過程的特征,又有面向?qū)ο蟮奶卣鳎?

我認為正是由于JavaScript對象模型的難以理解和使用,才出現(xiàn)了一些像CoffeeScript,Dart和TypeScript這些通過編譯可以生成JS代碼的語言。

JavaScript的前輩們和那些頑固派相信JavaScript有更好的對象模型,并且為其將被大家所遺忘感到惋惜。即使JavaScript的專家Nicholas Zakas也歡迎在ECMAScript 6中加入的新的class語法——只不過是對原型風(fēng)格(prototypal style)的語法做了一些修飾。換句話說,傳統(tǒng)的OOP贏了。

一個大膽的設(shè)想
但是,讓我們以玩笑的方式做一個設(shè)想:我們假想穿越到過去,那時候傳統(tǒng)的面向?qū)ο蟮某绦蛟O(shè)計還沒有像現(xiàn)在這樣被大家廣泛的接受,相反的,基于原型的繼承模型得到了大家的廣泛接受。這樣的話會發(fā)生什么?我們最終又會得到些什么樣的設(shè)計模式呢?

我們再設(shè)想:假設(shè)JavaScript沒有構(gòu)造函數(shù)或者沒有new關(guān)鍵字會怎樣?事情又會變成什么樣的呢?讓我們推到以前的重來。:)

首先,第一件事情,在JavaScript中,我們可以使用對象字面量的來創(chuàng)建一個新對象。如下所示:
復(fù)制代碼 代碼如下:

var felix = {
name: 'Felix',
greet: function(){
console.log('Hello, I am ' + this.name + '.');
}
};

接下來,假設(shè)我們想要將greet函數(shù)一般化,將其提取出來,放到一個一般的位置,這樣一來,我們就可以創(chuàng)建多個對象來共享同一個greet方法。該怎么實現(xiàn)呢?
我們有好幾種選擇,先以mixin開始吧。

1、混入(對象擴張)Mixin(Augmentation)
在JavaScript語言中,混入屬性非常簡單。你只需要將混入對象的屬性復(fù)制到要混入的對象中去即可。我們將使用一個“augment”函數(shù)來實現(xiàn)它,看代碼就明白了:
復(fù)制代碼 代碼如下:

var Dude = {
greet: function(){
console.log('Hello, I am ' + this.name + '.')
}
};
var felix = { name: 'Felix' };
augment(felix, Dude);//將Dude中的屬性復(fù)制一份到felix中,即混入(mixin)

在上面的代碼中,augment函數(shù)將Dude對象的屬性混入到了felix當(dāng)中。在很多的JS庫中,augment函數(shù)被叫做extend。我不喜歡用extend,因為一些語言用extend表示繼承,以至于是我很困惑。我更喜歡用“augment”表示,因為實際上這種做法并不是繼承,并且語法augment(felix, Dude)已經(jīng)很清楚的表明你是用Dude中的屬性對felix進行了擴充,而不是繼承。

也許你早就猜到了augment的代碼實現(xiàn)了,沒錯,非常簡單。如下所示:
復(fù)制代碼 代碼如下:

function augment(obj, properties){
for (var key in properties){
obj[key] = properties[key];
}
}

2、對象克?。–loning)
mixin的一個替代的辦法就是先克隆Dude對象,然后再給克隆的對象設(shè)置name屬性。如下所示:
復(fù)制代碼 代碼如下:

var Dude = {
greet: function(){
console.log('Hello, I am ' + this.name + '.');
}
}
var felix = clone(Dude);//克隆Dude對象
felix.name = 'Felix';

這兩種方法之間的唯一不同就是添加屬性的順序。如果你想覆寫克隆的對象中的某些方法,你可以考慮使用這種手法。
復(fù)制代碼 代碼如下:

var felix = clone(Dude);
felix.name = 'Felix';
felix.greet = function(){
console.log('Yo dawg!');
};//覆寫greet方法

如果想要調(diào)用父類的方法也很簡單——使用apply函數(shù)即可,如下所示
復(fù)制代碼 代碼如下:

felix.greet = function(){
Dude.greet.apply(this);
this.greetingCount++;
}

這比原型風(fēng)格的代碼要好很多,因為你不必去使用構(gòu)造函數(shù)的.prototype屬性——我們不會使用任何構(gòu)造函數(shù)。
以下是clone函數(shù)的實現(xiàn):
復(fù)制代碼 代碼如下:

function clone(obj){
var retval = {};//創(chuàng)建一個空對象
augment(retval, obj);//復(fù)制屬性
return retval;
}

3、繼承(Inheritance)
最后,就是繼承了。在我看來,繼承被高估了,但是繼承在“實例對象”之間共享屬性方面確實要比對象擴張有一些優(yōu)勢。讓我們編寫一個inherit函數(shù),這個函數(shù)接收一個對象作為參數(shù),并且返回一個繼承自該對象的新對象。
復(fù)制代碼 代碼如下:

var felix = inherit(Dude);
felix.name = 'Felix';

使用繼承,你可以創(chuàng)建多個繼承自同一個對象的子對象,這些子對象可以實時的繼承父對象的屬性。如下面的代碼所示,
復(fù)制代碼 代碼如下:

var garfield = inherit(Dude);//garfield繼承自Dude
Dude.walk = function(){//給Dude添加新的方法walk
console.log('Step, step');
};
garfield.walk(); // prints "Step, step"
felix.walk(); // also prints "Step, step"

在inherit函數(shù)中使用了基于原型對象的繼承
復(fù)制代碼 代碼如下:

function inherit(proto){
if (Object.create){
// 使用ES5中的Object.create方法
return Object.create(proto);
}else if({}.__proto__){
//使用非標(biāo)準(zhǔn)屬性__proto__
var ret = {};
ret.__proto__ = proto;
return ret;
}else{
//如果兩種都不支持,使用構(gòu)造函數(shù)繼承
var f = function(){};
f.prototype = proto;
return new f();
}
}

上面的代碼看起來不怎么好,那是因為我們使用了特性監(jiān)測來判斷到底使用3種方式中的哪一種。

但是,怎么使用構(gòu)造方法呢(也就是,初始化方法)?你該怎么在實例對象之間共享初始化代碼呢?在一些情況下,如果你只需要為對象設(shè)置一些屬性,這時候,初始化函數(shù)不是必須的,就像我們上面的例子中那樣。但是如果你有更多的初始化代碼呢,你也許會制定一個約定,例如:使用一個叫initialize的初始化方法。我們假設(shè)在Dude中定義了一個叫initialize的方法,如下
復(fù)制代碼 代碼如下:

var Dude = {
initialize: function(){
this.greetingCount = 0;
},
greet: function(){
console.log('Hello, I am ' + this.name + '.');
this.greetingCount++;
}
}

然后,你可以這樣來初始化對象
復(fù)制代碼 代碼如下:

var felix = clone(Dude);
felix.name = 'Felix';
felix.initialize();或者也可以
var felix = { name: 'Felix' };
felix.name = 'Felix';
augment(felix, Dude);
felix.initialize();還可以
var felix = inherit(Dude);
felix.name = 'Felix';
felix.initialize();結(jié)語

我表示通過上面定義的三個函數(shù)——augment,clone和inherit,你可以對JavaScript中的對象做任何你想做的事,而不必使用構(gòu)造函數(shù)和new關(guān)鍵字。我認為這三個函數(shù)所體現(xiàn)的語義更簡單并且更接近于JavaScript底層的對象系統(tǒng)。(完)^_^

相關(guān)文章

  • JavaScript原生編寫《飛機大戰(zhàn)坦克》游戲完整實例

    JavaScript原生編寫《飛機大戰(zhàn)坦克》游戲完整實例

    飛機大戰(zhàn)坦克是一款小游戲,相信很多朋友都有玩過,由于最近在深入學(xué)習(xí)Javascript,所以想著用利用Javascript來實現(xiàn)這個游戲,下面這篇文章主要介紹了如何利用JavaScript原生編寫《飛機大戰(zhàn)坦克》游戲,需要的朋友可以參考下
    2017-01-01
  • 如何實現(xiàn)修改密碼時密碼框顯示保存到cookie的密碼

    如何實現(xiàn)修改密碼時密碼框顯示保存到cookie的密碼

    修改密碼時密碼框顯示保存到cookie的密碼,只要在input框中加入AUTOCOMPLETE="OFF" 即可,感興趣的朋友可以了解下
    2013-12-12
  • JavaScript防抖與節(jié)流的實現(xiàn)與注意事項

    JavaScript防抖與節(jié)流的實現(xiàn)與注意事項

    防抖和節(jié)流嚴(yán)格算起來應(yīng)該屬于性能優(yōu)化的知識,但實際上遇到的頻率相當(dāng)高,處理不當(dāng)或者放任不管就容易引起瀏覽器卡死,下面這篇文章主要給大家介紹了關(guān)于JavaScript防抖與節(jié)流的實現(xiàn)與注意事項,需要的朋友可以參考下
    2022-03-03
  • 小程序?qū)崿F(xiàn)列表多個批量倒計時

    小程序?qū)崿F(xiàn)列表多個批量倒計時

    這篇文章主要為大家詳細介紹了小程序?qū)崿F(xiàn)列表多個批量倒計時,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • JavaScript中forEach和map詳細講解

    JavaScript中forEach和map詳細講解

    foreach和map都是JavaScript中數(shù)組的常用方法,它們都可以對數(shù)組中的每個元素執(zhí)行一個函數(shù),但是它們有一些區(qū)別,下面這篇文章主要給大家介紹了關(guān)于JavaScript中forEach和map詳細講解的相關(guān)資料,需要的朋友可以參考下
    2023-11-11
  • JavaScript性能優(yōu)化之小知識總結(jié)

    JavaScript性能優(yōu)化之小知識總結(jié)

    JavaScript的性能問題不容小覷,這就需要我們開發(fā)人員在編寫JavaScript程序時多注意一些細節(jié),本文給大家介紹javascript性能優(yōu)化之小知識總結(jié),需要的朋友可以參考下
    2015-11-11
  • uniapp獲取手機通知權(quán)限實現(xiàn)demo

    uniapp獲取手機通知權(quán)限實現(xiàn)demo

    這篇文章主要為大家介紹了uniapp獲取手機通知權(quán)限實現(xiàn)demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • javascript中HTMLDOM操作詳解

    javascript中HTMLDOM操作詳解

    這篇文章主要介紹了javascript中HTMLDOM操作詳解,需要的朋友可以參考下
    2014-12-12
  • 利用JavaScript實現(xiàn)繪制2023新年煙花的示例代碼

    利用JavaScript實現(xiàn)繪制2023新年煙花的示例代碼

    大家過年好!新春佳節(jié),在這個充滿喜悅的日子里,愿新年的鐘聲帶給你一份希望和期待。在這喜慶的日子里,小編和大家分享一個煙花代碼,希望大家能夠喜歡
    2023-01-01
  • 微信小程序?qū)崿F(xiàn)人臉檢測功能

    微信小程序?qū)崿F(xiàn)人臉檢測功能

    這篇文章主要為大家詳細介紹了微信小程序?qū)崿F(xiàn)人臉檢測功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05

最新評論

SHOW| 休宁县| 建始县| 石门县| 永德县| 双鸭山市| 蒙自县| 江孜县| 香河县| 克山县| 德州市| 文登市| 获嘉县| 昌平区| 泸州市| 开封市| 临夏市| 凤冈县| 吉安县| 响水县| 白山市| 商南县| 增城市| 临安市| 大埔区| 山西省| 渝北区| 苏州市| 宜良县| 颍上县| 尼勒克县| 马龙县| 象山县| 天柱县| 湖口县| 米泉市| 安义县| 简阳市| 深泽县| 浦北县| 娱乐|