JavaScript封裝

Javascript是一種基于對象(object-based)的語言灌诅,你遇到的所有東西幾乎都是對象。但是,它又不是一種真正的面向?qū)ο缶幊蹋∣OP)語言照棋,因為它的語法中沒有class(類)。

那么武翎,如果我們要把"屬性"(property)和"方法"(method)烈炭,封裝成一個對象,甚至要從原型對象生成一個實例對象宝恶,我們應(yīng)該怎么做呢符隙?

一趴捅、生成實例對象的原始模式

假定我們把貓看成一個對象,它有"名字"和"顏色"兩個屬性膏执。

var Cat = {
    name : '',
    color : ''
}

現(xiàn)在驻售,我們需要根據(jù)這個原型對象的規(guī)格(schema),生成兩個實例對象更米。

var cat1 = {};    // 創(chuàng)建一個空對象
    cat1.name = "大毛";    // 按照原型對象的屬性賦值
    cat1.color = "黃色";
var cat2 = {};
    cat2.name = "二毛";
    cat2.color = "黑色";

好了欺栗,這就是最簡單的封裝了,把兩個屬性封裝在一個對象里面征峦。但是迟几,這樣的寫法有兩個缺點,一是如果多生成幾個實例栏笆,寫起來就非常麻煩类腮;二是實例與原型之間,沒有任何辦法蛉加,可以看出有什么聯(lián)系蚜枢。

二、 原始模式的改進

我們可以寫一個函數(shù)针饥,解決代碼重復(fù)的問題厂抽。

> function Cat(name,color) {
    return {
        name:name,
        color:color
    }
}

然后生成實例對象,就等于是在調(diào)用函數(shù):

var cat1 = Cat("大毛","黃色");
var cat2 = Cat("二毛","黑色");

這種方法的問題依然是丁眼,cat1cat2之間沒有內(nèi)在的聯(lián)系筷凤,不能反映出它們是同一個原型對象的實例。

三苞七、 構(gòu)造函數(shù)模式

為了解決從原型對象生成實例的問題藐守,Javascript提供了一個構(gòu)造函數(shù)(Constructor)模式。

所謂"構(gòu)造函數(shù)"蹂风,其實就是一個普通函數(shù)卢厂,但是內(nèi)部使用了this變量。對構(gòu)造函數(shù)使用new運算符惠啄,就能生成實例慎恒,并且this變量會綁定在實例對象上。

比如礁阁,貓的原型對象現(xiàn)在可以這樣寫巧号,

function Cat(name,color){
    this.name=name;
    this.color=color;
}

我們現(xiàn)在就可以生成實例對象了。

var cat1 = new Cat("大毛","黃色");
var cat2 = new Cat("二毛","黑色");
alert(cat1.name);    // 大毛
alert(cat1.color);    // 黃色

這時cat1cat2會自動含有一個constructor屬性姥闭,指向它們的構(gòu)造函數(shù)丹鸿。

alert(cat1.constructor == Cat);    //true
alert(cat2.constructor == Cat);    //true

Javascript還提供了一個instanceof運算符,驗證原型對象與實例對象之間的關(guān)系棚品。

alert(cat1 instanceof Cat);    //true
alert(cat2 instanceof Cat);    //true
四靠欢、構(gòu)造函數(shù)模式的問題

構(gòu)造函數(shù)方法很好用廊敌,但是存在一個浪費內(nèi)存的問題。

請看门怪,我們現(xiàn)在為Cat對象添加一個不變的屬性type(種類)骡澈,再添加一個方法eat(吃)音婶。那么猎塞,原型對象Cat就變成了下面這樣:

function Cat(name,color){
    this.name = name;
    this.color = color;
    this.type = "貓科動物";
    this.eat = function(){alert("吃老鼠");};
}

還是采用同樣的方法甚带,生成實例:

var cat1 = new Cat("大毛","黃色");
var cat2 = new Cat ("二毛","黑色");
alert(cat1.type);    // 貓科動物
cat1.eat();    // 吃老鼠

表面上好像沒什么問題缓熟,但是實際上這樣做,有一個很大的弊端蹋辅。那就是對于每一個實例對象送丰,type屬性和eat()方法都是一模一樣的內(nèi)容怒详,每一次生成一個實例酿傍,都必須為重復(fù)的內(nèi)容烙懦,多占用一些內(nèi)存。這樣既不環(huán)保赤炒,也缺乏效率氯析。

alert(cat1.eat == cat2.eat);    //false

能不能讓type屬性和eat()方法在內(nèi)存中只生成一次,然后所有實例都指向那個內(nèi)存地址呢莺褒?回答是可以的掩缓。

五、 Prototype模式

Javascript規(guī)定癣朗,每一個構(gòu)造函數(shù)都有一個prototype屬性拾因,指向另一個對象旺罢。這個對象的所有屬性和方法旷余,都會被構(gòu)造函數(shù)的實例繼承。

這意味著扁达,我們可以把那些不變的屬性和方法正卧,直接定義在prototype對象上。

function Cat(name,color){
    this.name = name;
    this.color = color;
}
Cat.prototype.type = "貓科動物";
Cat.prototype.eat = function(){alert("吃老鼠")};

然后跪解,生成實例炉旷。

var cat1 = new Cat("大毛","黃色");
var cat2 = new Cat("二毛","黑色");
alert(cat1.type);    // 貓科動物
cat1.eat();    // 吃老鼠

這時所有實例的type屬性和eat()方法,其實都是同一個內(nèi)存地址叉讥,指向prototype對象窘行,因此就提高了運行效率。

alert(cat1.eat == cat2.eat);    //true
六图仓、 Prototype模式的驗證方法

為了配合prototype屬性罐盔,Javascript定義了一些輔助方法,幫助我們使用它救崔。惶看,

6.1 isPrototypeOf()

這個方法用來判斷捏顺,某個proptotype對象和某個實例之間的關(guān)系。

alert(Cat.prototype.isPrototypeOf(cat1));    //true
alert(Cat.prototype.isPrototypeOf(cat2));    //true

6.2 hasOwnProperty()

每個實例對象都有一個hasOwnProperty()方法纬黎,用來判斷某一個屬性到底是本地屬性幅骄,還是繼承自prototype對象的屬性。

alert(cat1.hasOwnProperty("name"));    // true
alert(cat1.hasOwnProperty("type"));    // false

6.3 in運算符

in運算符可以用來判斷本今,某個實例是否含有某個屬性拆座,不管是不是本地屬性。

alert("name" in cat1);    // true
alert("type" in cat1);    // true

in運算符還可以用來遍歷某個對象的所有屬性冠息。

for(var prop in cat1) { alert("cat1["+prop+"]="+cat1[prop]); }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末懂拾,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子铐达,更是在濱河造成了極大的恐慌岖赋,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瓮孙,死亡現(xiàn)場離奇詭異唐断,居然都是意外死亡,警方通過查閱死者的電腦和手機杭抠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門脸甘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人偏灿,你說我怎么就攤上這事丹诀。” “怎么了翁垂?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵铆遭,是天一觀的道長。 經(jīng)常有香客問我沿猜,道長枚荣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任啼肩,我火速辦了婚禮橄妆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘祈坠。我一直安慰自己害碾,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布赦拘。 她就那樣靜靜地躺著慌随,像睡著了一般。 火紅的嫁衣襯著肌膚如雪另绩。 梳的紋絲不亂的頭發(fā)上儒陨,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天花嘶,我揣著相機與錄音,去河邊找鬼蹦漠。 笑死椭员,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的笛园。 我是一名探鬼主播隘击,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼研铆!你這毒婦竟也來了埋同?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤棵红,失蹤者是張志新(化名)和其女友劉穎凶赁,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體逆甜,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡虱肄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了交煞。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咏窿。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖素征,靈堂內(nèi)的尸體忽然破棺而出集嵌,到底是詐尸還是另有隱情,我是刑警寧澤御毅,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布根欧,位于F島的核電站,受9級特大地震影響亚享,放射性物質(zhì)發(fā)生泄漏咽块。R本人自食惡果不足惜绘面,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一欺税、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧揭璃,春花似錦晚凿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至情组,卻和暖如春燥筷,著一層夾襖步出監(jiān)牢的瞬間箩祥,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工肆氓, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留袍祖,地道東北人。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓谢揪,卻偏偏與公主長得像蕉陋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拨扶,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 第3章 基本概念 3.1 語法 3.2 關(guān)鍵字和保留字 3.3 變量 3.4 數(shù)據(jù)類型 5種簡單數(shù)據(jù)類型:Unde...
    RickCole閱讀 5,104評論 0 21
  • ??面向?qū)ο螅∣bject-Oriented患民,OO)的語言有一個標志缩举,那就是它們都有類的概念,而通過類可以創(chuàng)建任意...
    霜天曉閱讀 2,098評論 0 6
  • 一匹颤、生成實例對象的原始模式 二蚁孔、工廠模式 三、構(gòu)造函數(shù)模式 所謂"構(gòu)造函數(shù)"惋嚎,其實就是一個普通函數(shù)杠氢,但是內(nèi)部使用了...
    CoderLF閱讀 149評論 0 0
  • 早期的博客3 創(chuàng)建對象的方法: object構(gòu)造函數(shù)和對象字面量方法 工廠模式 自定義構(gòu)造函數(shù)模式 原型模式 組合...
    索伯列夫閱讀 448評論 0 1
  • 快到小區(qū)門口了,小老弟打個電話來叫帶包煙另伍。走進便利店鼻百,看著貨架上的煙,一時竟茫然了摆尝,小哥問要什么煙温艇,目光從第一層掃...
    曲悅秋華閱讀 238評論 0 0