欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在JavaScript中實(shí)現(xiàn)類(lèi)的方式探討

 更新時(shí)間:2013年08月28日 15:03:02   作者:  
在 javascript 中有很多方式來(lái)創(chuàng)建對(duì)象,所以創(chuàng)建對(duì)象的方式使用起來(lái)非常靈活,到底哪一種方式是最恰當(dāng)呢?下面為大家講講
在 javascript 中有很多方式來(lái)創(chuàng)建對(duì)象,所以創(chuàng)建對(duì)象的方式使用起來(lái)非常靈活。那么,到底哪一種方式是最恰當(dāng)?shù)膶?duì)象創(chuàng)建方式呢?構(gòu)造模式,原型模式還是對(duì)象原意模式(Object literal)呢?

但這些模式具體是怎么回事呢?

在開(kāi)始講解之前,讓我們先清楚地介紹一下關(guān)于 javascript 基本知識(shí)。

有沒(méi)有可能在 javascript 中實(shí)現(xiàn)面向?qū)ο缶幊痰姆绞侥兀?

答案是可能的,javascript 是可以創(chuàng)建對(duì)象的!這種對(duì)象可以包含數(shù)據(jù)及能夠操作數(shù)據(jù)的方法,甚至可以包含其他對(duì)象。它沒(méi)有類(lèi)但擁有構(gòu)造函數(shù);它沒(méi)有類(lèi)繼承機(jī)制,但是可以通過(guò)原型(prototype)實(shí)現(xiàn)繼承。

現(xiàn)在看起來(lái),我們已經(jīng)了解了在 javascript 中創(chuàng)建對(duì)象及實(shí)現(xiàn)基于對(duì)象編程時(shí)所必須的組成部分。

我們都知道 javascript 擁有私有變量。一個(gè)通過(guò)“var”關(guān)鍵字定義的變量,只能在函數(shù)體中被訪問(wèn),而不能在函數(shù)外被訪問(wèn)。那么,如果我們不通過(guò)使用“var”關(guān)鍵字來(lái)定義變量會(huì)怎樣呢?我們現(xiàn)在不對(duì)這個(gè)問(wèn)題進(jìn)行深入探討,可能是通過(guò)“this”進(jìn)行訪問(wèn)的,我會(huì)在另外的時(shí)間來(lái)詳細(xì)講述這個(gè)問(wèn)題。

現(xiàn)在回到之前的問(wèn)題。到底哪一種方式是最恰當(dāng)?shù)膶?duì)象創(chuàng)建方式呢?
讓我們用已經(jīng)知曉的知識(shí),通過(guò)創(chuàng)建Person的對(duì)象是來(lái)試驗(yàn)一下。
復(fù)制代碼 代碼如下:

var Person = {
firstName : 'John',
lastName : 'Cody',
fullName : '',
message : '',

createFullName : function () {
fullName = this.firstName + ' ' + this.lastName;
},

changeMessage : function (msg) {
this.message = msg;
},

getMessage : function () {
this.createFullName();
return this.message + ' ' + fullName;
}
}

Person.firstName = 'Eli';
Person.lastName = 'Flowers'
Person.changeMessage('welcome');
var message = Person.getMessage(); // welcome Eli Flowers
alert(message);

這是對(duì)象原意模式(literal pattern)。這非常接近我們常創(chuàng)建對(duì)象的方式。如果你不需要關(guān)心私有/包裝的成員,并且你知道不將創(chuàng)建這個(gè)對(duì)象的實(shí)例。那么,這種方式將會(huì)很適合你。公有的成員可以做所有私有成員的事情,不是嗎?但是,這不是一個(gè)類(lèi),而是一個(gè)對(duì)象而已,不能被創(chuàng)建實(shí)例并且不能被繼承。

讓我們嘗試下其他的方面:
復(fù)制代碼 代碼如下:

var Person = {
firstName : 'John',
lastName : 'Cody',
fullName : '',
message : '',

createFullName : function () {
fullName = this.firstName + ' ' + this.lastName;
},

changeMessage : function (msg) {
this.message = msg;
},

getMessage : function () {
this.createFullName();
return this.message + ' ' + fullName;
}
}

Person.firstName = 'Eli';
Person.lastName = 'Flowers'
Person.changeMessage('welcome');
var message = Person.getMessage(); // welcome Eli Flowers
alert(message);

這是一種構(gòu)造模式的實(shí)例(Constructor Pattern)。那么,這是類(lèi)還是對(duì)象呢?應(yīng)該 兩種都算是吧。我們能夠在當(dāng)請(qǐng)求時(shí)把它當(dāng)做對(duì)象Person來(lái)使用。它畢竟也只是一個(gè)函數(shù)而已。然而,它可以通過(guò)使用“new”關(guān)鍵字來(lái)實(shí)現(xiàn)創(chuàng)建新的實(shí)例功能。

在使用這種方式時(shí),我們需要時(shí)刻記住如下要點(diǎn):

1. 無(wú)論什么時(shí)候這個(gè)函數(shù)被調(diào)用時(shí),它擁有一個(gè)特別的變量叫做“this”并且可以在全局范圍內(nèi)使用。全局范圍依賴于這個(gè)函數(shù)自身的作用范圍。

2. 無(wú)論什么時(shí)候通過(guò)“new”關(guān)鍵字創(chuàng)建這個(gè)函數(shù)的實(shí)例,“this”變量指向這個(gè)函數(shù)本身,并且這個(gè)“new”操作將會(huì)影響到函數(shù)體中的代碼被執(zhí)行。這也正是構(gòu)造模式。

3. 任何附加到“this”變量下的變量都會(huì)成為公有屬性并且任何通過(guò)“var”關(guān)鍵字定義的變量都將是屬于私有屬性。

4. 一個(gè)附加到“this”下的函數(shù)叫做特權(quán)函數(shù),它可以訪問(wèn)所有的私有變量以及被附加到“this”下的函數(shù)及變量。

5. 私有函數(shù)可以訪問(wèn)到其他私有變量及私有函數(shù)。

6. 私有函數(shù)不能直接訪問(wèn)被附加到“this”變量和函數(shù)。我們可以通過(guò)創(chuàng)建一個(gè)私有變量“_that”并且將它賦值為“this”的方式實(shí)現(xiàn)。

7. 任何私有變量及函數(shù)對(duì)于其他私有函數(shù)及其他被附加到“this”的函數(shù)是可用的。這完全是可能的再javascript的作用范圍下。

8. 一個(gè)變量:不是通過(guò)“var”關(guān)鍵字,也不是附加到“this”變量上以獲得全局作用范圍的。例如,對(duì)于一個(gè)自定義函數(shù)的作用范圍。需要再一次地了解作用域及集群的知識(shí)。

這已經(jīng)實(shí)現(xiàn)了我們想要的大部分要求了,但是,有時(shí)候“this”和“that”這兩個(gè)入口變量很容易造成給人們帶來(lái)疑惑。尤其對(duì)于那些一直堅(jiān)持要求純粹私有的人來(lái)說(shuō),更容易迷惑。

讓我們?cè)偕晕⑿薷南略囋嚢伞?
復(fù)制代碼 代碼如下:

var Person = function () {

//private
var firstName = 'John';
var lastName = 'Cody';
var fullName = '';
var message = '';


var createFullName = function () {
fullName = firstName + ' ' + lastName;
}

//public setters
var setMessage = function (msg) {
message = msg;
}

var setFirstName = function (fName) {
firstName = fName;
}

var setLastName = function (lName) {
lastName = lName;
}

var getMessage = function () {
createFullName();
return message + ' ' + fullName;
}

//functions exposed public
return {
setFirstName: setFirstName,
setLastName: setLastName,
setMessage: setMessage,
getMessage: getMessage
};

};

var person1 = new Person();
person1.setFirstName('Eli');
person1.setLastName('Flowers');
person1.setMessage('welcome');
var message = person1.getMessage(); // welcome Eli Flowers
alert(message);

這是一個(gè)顯示模式(Revealing Pattern)。非常感謝 Christian Heilmann。使用這種模式的方式就是把請(qǐng)求的"getters" 和 "setters" 當(dāng)作屬性使用。我們很多都是從傳統(tǒng)的Java編程中找到這樣的身影并且很明顯地知道實(shí)現(xiàn)它其實(shí)并不復(fù)雜。這同樣是一種類(lèi)似于當(dāng)類(lèi)繼承自一個(gè)接口的情況。

這種模式大部分方面都實(shí)現(xiàn)得很好,僅僅只有一個(gè)很微小的問(wèn)題。每一次當(dāng)一個(gè)類(lèi)的實(shí)例被創(chuàng)建時(shí)。這個(gè)新創(chuàng)建的對(duì)象獲得了一份變量和函數(shù)的拷貝?,F(xiàn)在,拷貝變量是沒(méi)有問(wèn)題的,我們希望對(duì)于每一個(gè)對(duì)象的數(shù)據(jù)都是屬于對(duì)象自身的,那么,成員函數(shù)呢?他們僅僅是操作數(shù)據(jù)而已。那么,為什么需要拷貝他們呢?

這正是原型模式(Prototype)的優(yōu)勢(shì)所在。在所有實(shí)例中,所有東西都是被創(chuàng)建成一個(gè)原型,并且能夠相互分享。我們僅僅需要做的就是依據(jù)原型創(chuàng)建共有函數(shù)。
復(fù)制代碼 代碼如下:

var Person = function () {

//private
var welcomeMessage = 'welcome';
var fullName = '';
var firstName = '';
var lastName = "";
var createFullName = function () {
Person.prototype.setFirstName('asdsad');
fullName = firstName + ' ' + lastName;
};

//constructor
var Person = function () { }; //will be created evrytime

//public
Person.prototype = {
getFullName: function () {
createFullName();
return welcomeMessage + ' ' + fullName;
},
setFirstName: function (fName) {
firstName = fName;
},
setLastName: function (lName) {
lastName = lName;
},
ChangeMessage: function (mesg) {
welcomeMessage = mesg;
}
}

return new Person(); // Person; //new Person();
};


var person1 = new Person();
person1.setFirstName ('Eli');
person1.setLastName('Flowers');
person1.ChangeMessage('welcome');
var message = person1.getFullName(); // welcome asdsad Flowers
alert(message);

原型模式存在的一個(gè)問(wèn)題是它不能訪問(wèn)私有變量及私有函數(shù),正因?yàn)檫@個(gè)問(wèn)題,我們才會(huì)介紹閉包以及始終組織好創(chuàng)建類(lèi)中存在的代碼以使得它在全局范圍內(nèi)不會(huì)變得很混亂。所有都是屬于 Person 類(lèi)的作用范圍內(nèi)。

另外一個(gè)問(wèn)題是每一次實(shí)例被創(chuàng)建時(shí),全部的代碼都被執(zhí)行一遍,包括原型的綁定。對(duì)于我們中的一部分人來(lái)說(shuō),這僅僅只是一個(gè)效率問(wèn)題。處理好這個(gè)問(wèn)題的一種方式是僅僅在期望共有函數(shù)不可用的情況下綁定這個(gè)原型。

這樣將會(huì)使得綁定原型操作只會(huì)在第一個(gè)實(shí)例被創(chuàng)建時(shí)執(zhí)行,并且在那之后所有其他的實(shí)例都將只會(huì)進(jìn)行檢查操作。不幸的是,這樣還是不能解決我們?cè)谏厦胬又刑岬降膯?wèn)題,因?yàn)槲覀冎挥兄匦略賮?lái)一次創(chuàng)建的函數(shù)用于生成一個(gè)閉包來(lái)達(dá)到這個(gè)類(lèi)的效果。這樣的話,至少我們減少了一部分內(nèi)存的使用。

等等,還有另外一個(gè)問(wèn)題是私有函數(shù)不能直接訪問(wèn)原型函數(shù)。

為什么你們一定得需要私有函數(shù)和私有變量呢?我知道你一定是想實(shí)現(xiàn)類(lèi)的封裝性,想確保類(lèi)中的屬性或者內(nèi)部的數(shù)據(jù)不會(huì)被突然地修改了或者被內(nèi)部的其他程序所修改,或者任何其他的操作……

你應(yīng)該記住你是不能將 javascript 代碼編譯成二進(jìn)制的,對(duì)于這種情況,你在一定程度上很惱火吧,這樣代碼始終都是可用的。所以,如果任何人想攪亂代碼的話,不管你真正實(shí)現(xiàn)私有或者沒(méi)有實(shí)現(xiàn)私有,不管你將代碼給團(tuán)隊(duì)中的其他成員或者賣(mài)出去,他們都可以攪亂代碼。實(shí)現(xiàn)私有化可能有那么一點(diǎn)點(diǎn)幫助吧。

另一個(gè)其他編程者使用的技術(shù)是使用約定命名,使用下劃線 “_”給所有你想設(shè)成私有任何的東西加上前綴以規(guī)定它成為私有。
復(fù)制代碼 代碼如下:

(function () {
var Person = function () {
this._fullName = '';
this.welcomeMessage = '';
this.firstName = '';
this.lastName = "";
_that = this;

this._createFullName = function () {
this.ChangeMessage('Namaste');
this._fullName = this.firstName + ' ' + this.lastName;
};
}

//Shared Functions for Code optimization
Person.prototype = {
constructor: Person,
getFullName: function () {
this._createFullName();
return this.welcomeMessage + ' ' + this._fullName;
},
ChangeMessage: function (mesg) {
this.welcomeMessage = mesg;
}
}

this.Person = Person;
})();

var person1 = new Person();
person1.firstName = 'Eli';
person1.lastName = 'Flowers';
person1.ChangeMessage('Welcome');
var message = person1.getFullName(); // Namaste Eli Flowers
alert(message);

我不是說(shuō)你不應(yīng)該考慮 “private” 或者類(lèi)似的知識(shí)。你是代碼的設(shè)計(jì)者,所以你將知道怎么來(lái)管理并且知道怎么做才是最好的。根據(jù)你的需求,你可以使用任何一種設(shè)計(jì)模式或者多個(gè)設(shè)計(jì)模式組合一起使用。

無(wú)論你決定采用哪種設(shè)計(jì)模式,始終記住做盡量少的事情,不要在全局作用范圍內(nèi)實(shí)現(xiàn)閉包,盡量減少內(nèi)存泄露,以及優(yōu)化代碼,并且組織好代碼。所以,盡量多了解些作用域,閉包以及 “this” 的表現(xiàn)行為。

最后,祝編程愉快!

譯后感

經(jīng)常使用 javascript,對(duì)于它的印象一直都是直接拷貝過(guò)來(lái)就可以用的。最近使用 extjs,它的類(lèi)框架非常好用。從這樣文章也明白在 javascript 中實(shí)現(xiàn)類(lèi)的各種方式,以及在文章最后討論了類(lèi)中私有成員的實(shí)現(xiàn)情況。

相關(guān)文章

  • javascript生成隨機(jī)數(shù)的方法

    javascript生成隨機(jī)數(shù)的方法

    這篇文章主要介紹了javascript生成隨機(jī)數(shù)的方法,需要的朋友可以參考下
    2014-05-05
  • 利用JavaScript為句子加標(biāo)題的3種方法示例

    利用JavaScript為句子加標(biāo)題的3種方法示例

    這篇文章主要給大家介紹了關(guān)于如何利用JavaScript為句子加標(biāo)題的3種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • JavaScript this指向相關(guān)原理及實(shí)例解析

    JavaScript this指向相關(guān)原理及實(shí)例解析

    這篇文章主要介紹了JavaScript this指向相關(guān)原理及實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 微信小程序?qū)崿F(xiàn)循環(huán)嵌套數(shù)據(jù)選擇

    微信小程序?qū)崿F(xiàn)循環(huán)嵌套數(shù)據(jù)選擇

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)循環(huán)嵌套數(shù)據(jù)選擇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 微信小程序?qū)崿F(xiàn)收藏與取消收藏切換圖片功能

    微信小程序?qū)崿F(xiàn)收藏與取消收藏切換圖片功能

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)收藏與取消收藏切換圖片功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-08-08
  • 微信小程序開(kāi)發(fā)之組件設(shè)計(jì)規(guī)范

    微信小程序開(kāi)發(fā)之組件設(shè)計(jì)規(guī)范

    這篇文章主要給大家介紹了關(guān)于微信小程序開(kāi)發(fā)之組件設(shè)計(jì)規(guī)范的相關(guān)資料,對(duì)剛?cè)腴T(mén)學(xué)習(xí)微信小程序的同學(xué)們還是挺有幫助的,需要的朋友可以參考下
    2021-05-05
  • 使用Fuse.js實(shí)現(xiàn)高效的模糊搜索功能

    使用Fuse.js實(shí)現(xiàn)高效的模糊搜索功能

    在現(xiàn)代?Web?應(yīng)用程序中,實(shí)現(xiàn)高效的搜索功能是至關(guān)重要的,Fuse.js?是一個(gè)強(qiáng)大的?JavaScript?庫(kù),它提供了靈活的模糊搜索和文本匹配功能,使您能夠輕松實(shí)現(xiàn)出色的搜索體驗(yàn),文中代碼示例講解的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • Web打印解決方案之普通報(bào)表打印功能

    Web打印解決方案之普通報(bào)表打印功能

    這篇文章主要介紹了Web打印解決方案之普通報(bào)表打印功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-08-08
  • javascript 模擬點(diǎn)擊廣告

    javascript 模擬點(diǎn)擊廣告

    我們不管js或iframe怎么調(diào)用的,模擬點(diǎn)擊就意味著打開(kāi)廣告鏈接,廣告商就以為用戶點(diǎn)擊了他的廣告,所以我們只要保證點(diǎn)擊了一個(gè)鏈接但沒(méi)有跳出頁(yè)面的結(jié)果就行了,是嗎?
    2010-01-01
  • 微信小程序?qū)崿F(xiàn)星級(jí)評(píng)分

    微信小程序?qū)崿F(xiàn)星級(jí)評(píng)分

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)星級(jí)評(píng)分,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11

最新評(píng)論