亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

在JavaScript中實現(xiàn)類的方式探討

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

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

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

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

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

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

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

現(xiàn)在回到之前的問題。到底哪一種方式是最恰當(dāng)?shù)膶ο髣?chuàng)建方式呢?
讓我們用已經(jīng)知曉的知識,通過創(chuàng)建Person的對象是來試驗一下。
復(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);

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

讓我們嘗試下其他的方面:
復(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)造模式的實例(Constructor Pattern)。那么,這是類還是對象呢?應(yīng)該 兩種都算是吧。我們能夠在當(dāng)請求時把它當(dāng)做對象Person來使用。它畢竟也只是一個函數(shù)而已。然而,它可以通過使用“new”關(guān)鍵字來實現(xiàn)創(chuàng)建新的實例功能。

在使用這種方式時,我們需要時刻記住如下要點:

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

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

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

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

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

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

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

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

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

讓我們再稍微修改下試試吧。
復(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);

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

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

這正是原型模式(Prototype)的優(yōu)勢所在。在所有實例中,所有東西都是被創(chuàng)建成一個原型,并且能夠相互分享。我們僅僅需要做的就是依據(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);

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

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

這樣將會使得綁定原型操作只會在第一個實例被創(chuàng)建時執(zhí)行,并且在那之后所有其他的實例都將只會進行檢查操作。不幸的是,這樣還是不能解決我們在上面例子中提到的問題,因為我們只有重新再來一次創(chuàng)建的函數(shù)用于生成一個閉包來達到這個類的效果。這樣的話,至少我們減少了一部分內(nèi)存的使用。

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

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

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

另一個其他編程者使用的技術(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);

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

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

最后,祝編程愉快!

譯后感

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

相關(guān)文章

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

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

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

    利用JavaScript為句子加標題的3種方法示例

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

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

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

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

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

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

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

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

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

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

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

    Web打印解決方案之普通報表打印功能

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

    javascript 模擬點擊廣告

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

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

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

最新評論