JavaScript面向?qū)ο蟮某绦蛟O(shè)計(jì)——理解對(duì)象

面向?qū)ο螅∣bject-Oriented郑兴,OO)的語言有一個(gè)標(biāo)志廊营,那就是它們都有類的概念,而通過類可以創(chuàng)建任意多個(gè)具有相同屬性和方法的對(duì)象欲间。ECMAScript中沒有類的概念贮懈,因此它對(duì)對(duì)象也與基于類的語言中的對(duì)象有所不同匀泊。
ECMA-262把對(duì)象定義為:“無序?qū)傩缘募希鋵傩钥梢园局刀淠恪?duì)象或者函數(shù)各聘。”這就相當(dāng)于說對(duì)象是一組沒有特定順序的值抡医。對(duì)象的每個(gè)屬性或方法都有一個(gè)名字躲因,每個(gè)名字都映射到一個(gè)值。忌傻〈舐觯可以不ECMAScript的對(duì)象想象成散列表:就是一組名值對(duì),其中值可以是數(shù)據(jù)或函數(shù)水孩。

理解對(duì)象

創(chuàng)建自定義對(duì)象:

方法一:創(chuàng)建一個(gè)Object實(shí)例

var person = new Object();
person.name ="Icey";
person.age = 25;
person.job = "Softerware Engineer";

person.sayName = function () {
    alert(this.name);
}

方法二:對(duì)象字面量創(chuàng)建對(duì)象

var person = {
    name:"Icey",
    age:25,
    job:"Softerware Engineer",

    sayName:function () {
        alert(this.name);
    }
};
1. 屬性類型

ECMA-262定義這些特性是為了實(shí)現(xiàn)JavaScript引擎用的镰矿,因此在JavaScript中不能直接訪問它們。為了表示特性是內(nèi)部值俘种,該規(guī)范把它們放在兩對(duì)方括號(hào)中秤标,如[[Enumerable]]。
ECMAScript中有兩種屬性:數(shù)據(jù)屬性和訪問器屬性宙刘。

  • 1.數(shù)據(jù)屬性
    數(shù)據(jù)屬性包含一個(gè)數(shù)據(jù)值的位置苍姜。在這個(gè)位置可以讀取和寫入值。數(shù)據(jù)屬性有4個(gè)描述其行為的特性悬包。
  • [[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性衙猪,能否修改屬性的特性,或者能否把屬性修改為訪問其屬性布近。這個(gè)特性的默認(rèn)值為true垫释。
  • [[Enumerable]]:表示能否通過for-in循環(huán)返回屬性。直接在對(duì)象上定義的屬性吊输,默認(rèn)值為true饶号。
  • [[Writable]]:表示能否修改屬性的值。直接在對(duì)象上定義的屬性季蚂,默認(rèn)值為true茫船。
  • [[Value]]:包含這個(gè)屬性的數(shù)據(jù)值。讀取屬性的時(shí)候扭屁,從這個(gè)位置讀算谈,寫入屬性的時(shí)候,把值保存在這個(gè)位置料滥。這個(gè)特性的默認(rèn)值為undefined然眼。

像前面例子中那樣直接在對(duì)象上定義的屬性,它們的[[Configurable]]葵腹、[[Enumerable]]和[[Writable]]特性都設(shè)置為true,而[[Value]]特性被設(shè)置為指定的值高每。

var person = {
    name : "Icey"
};

這里創(chuàng)建了一個(gè)名為name的屬性屿岂,為它指定的值是"Icey"。[[Value]]特性將被設(shè)置為"Icey",對(duì)這個(gè)值的任何修改都將反映到這個(gè)位置鲸匿。
要修改屬性默認(rèn)的特性爷怀,必須使用ECMAScript的Object.defineProperty()方法。這個(gè)方法接三個(gè)參數(shù):屬性所在的對(duì)象带欢、屬性的名字和一個(gè)描述符對(duì)象运授。描述符對(duì)象的屬性必須是:configurable、enumerable乔煞、writable和value吁朦。設(shè)置其中的一或多個(gè)值,可以修改對(duì)應(yīng)的特性值渡贾。

var person = {};
Object.defineProperty(person,"name",{
    wriable:false,
    value:"Icey"
});
alert(person.name); //"Icey"
person.name = "Root";
alert(person.name); //"Icey"

在非嚴(yán)格模式下逗宜,賦值操作將被忽略,在嚴(yán)格模式下剥啤,賦值操作將會(huì)拋出錯(cuò)誤锦溪。

var person = {};
Object.defineProperty(person,"name",{
    configurable:false,
    value:"Icey"
});
alert(person.name); //"Icey"
delete person.name;
alert(person.name); //"Icey"

一旦把屬性定義為不可配置的,就不能再把它變回可配置了府怯。

var person = {};
Object.defineProperty(person,"name",{
    configurable:false,
    value:"Icey"
});
//拋出錯(cuò)誤
Object.defineProperty(person,"name",{
    configurable:true,
    value:"Icey"
});

在調(diào)用Object.defineProperty()方法創(chuàng)建一個(gè)新的屬性時(shí)刻诊,如果不指定,configurable牺丙、enumerable和writable特性的默認(rèn)值都是false则涯。如果調(diào)用Object.defineProperty()方法只是修改一定義的屬性的特性,則無次限制冲簿。

  • 2.訪問器屬性
    訪問器屬性不包含數(shù)據(jù)值粟判;它們包含一對(duì)gettersetter函數(shù)(這兩個(gè)函數(shù)都不識(shí)必須的)。
    在讀取訪問其屬性時(shí)峦剔,會(huì)調(diào)用getter函數(shù)档礁,這個(gè)函數(shù)負(fù)責(zé)返回有效的值;
    在寫入訪問其屬性時(shí)吝沫,會(huì)調(diào)用setter函數(shù)并傳入新值呻澜,這個(gè)函數(shù)負(fù)責(zé)決定如何處理數(shù)據(jù)。
    訪問器屬性有如下4個(gè)特性:
  • [[Configurable]]:表示能否通過delete刪除屬性從而重新定義屬性惨险,能否修改屬性的特性羹幸,或者能否把屬性修改為訪問其屬性。這個(gè)特性的默認(rèn)值為true辫愉。
  • [[Enumerable]]:表示能否通過for-in循環(huán)返回屬性栅受。直接在對(duì)象上定義的屬性,默認(rèn)值為true。
  • [[Get]]:在讀取屬性時(shí)調(diào)用的函數(shù)屏镊,默認(rèn)值undefined依疼。
  • [[Set]]:在讀取屬性時(shí)調(diào)用的函數(shù),默認(rèn)值undefined闸衫。

訪問器屬性不能直接定義涛贯,必須用Object.defineProperty()定義。

var book = {
    _year:2017,
    edition:1
};
Object.defineProperty(book,"year",{
    get:function () {
        return this._year;
    },
    set:function (newValue) {
        if(newValue>2017){
            this._year = newValue;
            this.edition += newValue - 2017;
        }
    }
});

book.year = 2018;
alert(book.edition); //2

_year前面的下劃線是一種常用的記號(hào)蔚出,由于表示只能通過對(duì)象方法訪問的屬性。
把year修改成2018虫腋,會(huì)導(dǎo)致_year變成2018骄酗,edition變成2。使用訪問器屬性常見的方式悦冀,即設(shè)置一個(gè)屬性的值會(huì)導(dǎo)致其它屬性發(fā)生變化趋翻。

2. 定義多個(gè)屬性

Object.defineProperties()方法可以通過描述符一次定義多個(gè)屬性。這個(gè)方法接收兩個(gè)對(duì)象參數(shù):第一個(gè)對(duì)象是要添加和修改其屬性的對(duì)象盒蟆,第二個(gè)對(duì)象的屬性與第一個(gè)對(duì)象中要添加和修改的屬性一一對(duì)應(yīng)踏烙。

var book = {};
Object.defineProperties(book,{
    _year:{
        writable:true,
        value:2004
    },
    edition:{
        writable:true,
        value:1
    },
    year:{
        get:function () {
            return this._year;
        },
        set:function (newValue) {
        if(newValue>2017){
            this._year = newValue;
            this.edition += newValue - 2004;
        }
    }
    }
});

book對(duì)象定義了兩個(gè)數(shù)據(jù)屬性和一個(gè)訪問器屬性。

3. 讀取屬性的特性

Object.getOwnPropertyDescriptor()方法可以取得給定屬性的描述符历等。這個(gè)方法接收兩個(gè)參數(shù):屬性所在的對(duì)象和要讀取其描述符的屬性名稱讨惩。返回值是一個(gè)對(duì)象。

var descriptor = Object.getOwnPropertyDescriptor(book,"_year");
alert(descriptor.value); //2004
alert(descriptor.configurable); //false
alert(typeof descriptor.get); //"undefined"

var descriptor = Object.getOwnPropertyDescriptor(book,"year");
alert(descriptor.value);//undefined
alert(descriptor.enumerable); //false
alert(typeof descriptor.get);//"function"
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末寒屯,一起剝皮案震驚了整個(gè)濱河市荐捻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌寡夹,老刑警劉巖处面,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異菩掏,居然都是意外死亡魂角,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門智绸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來野揪,“玉大人,你說我怎么就攤上這事传于〈烟簦” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵沼溜,是天一觀的道長(zhǎng)平挑。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么通熄? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任唆涝,我火速辦了婚禮,結(jié)果婚禮上唇辨,老公的妹妹穿的比我還像新娘廊酣。我一直安慰自己,他們只是感情好赏枚,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布亡驰。 她就那樣靜靜地躺著,像睡著了一般饿幅。 火紅的嫁衣襯著肌膚如雪凡辱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天栗恩,我揣著相機(jī)與錄音透乾,去河邊找鬼。 笑死磕秤,一個(gè)胖子當(dāng)著我的面吹牛乳乌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播市咆,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼汉操,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了床绪?” 一聲冷哼從身側(cè)響起客情,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎癞己,沒想到半個(gè)月后膀斋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痹雅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年仰担,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绩社。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡摔蓝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愉耙,到底是詐尸還是另有隱情贮尉,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布朴沿,位于F島的核電站猜谚,受9級(jí)特大地震影響败砂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜魏铅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一昌犹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧览芳,春花似錦惩阶、人聲如沸喇闸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至屯仗,卻和暖如春搞坝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背魁袜。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留敦第,地道東北人峰弹。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像芜果,于是被迫代替她去往敵國(guó)和親鞠呈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

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