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

詳解JavaScript中的屬性和特性

 更新時(shí)間:2016年12月08日 15:59:24   作者:918之初  
本文對JavaScript中對象的本質(zhì)、對象與類的關(guān)系、對象與引用類型的關(guān)系;對象屬性如何進(jìn)行分類;屬性中特性進(jìn)行介紹。感興趣的朋友可以看下

JavaScript中屬性和特性是完全不同的兩個(gè)概念,這里我將根據(jù)自己所學(xué),來深入理解JavaScript中的屬性和特性。

主要內(nèi)容如下:

  • 理解JavaScript中對象的本質(zhì)、對象與類的關(guān)系、對象與引用類型的關(guān)系
  • 對象屬性如何進(jìn)行分類
  • 屬性中特性的理解 

第一部分:理解JavaScript中對象的本質(zhì)、對象與類的關(guān)系、對象與引用類型的關(guān)系

對象的本質(zhì):ECMA-262把對象定義為:無序?qū)傩缘募?,其屬性可以包含基本值、對象或者函?shù)。即對象是一組沒有特定順序的值,對象的每個(gè)屬性或方法都有一個(gè)名字,而這個(gè)名字都映射到一個(gè)值。故對象的本質(zhì)是一個(gè)散列表:其中是一組名值對,值可以是數(shù)據(jù)或函數(shù)。

對象和類的關(guān)系:在JavaScript中,對象和類沒有任何關(guān)系。這是因?yàn)镋CMAScript中根本就沒有類的概念,它的對象與其他基于類的語言中的對象是不同的。

對象和引用類型的關(guān)系:對象和引用類型并不是等價(jià)的,因?yàn)槊總€(gè)對象都是基于一個(gè)引用類型創(chuàng)建的。

第二部分:對象屬性如何進(jìn)行分類

由構(gòu)造函數(shù)或?qū)ο笞置媪糠椒▌?chuàng)建的對象中具有屬性和方法(只要提到屬性和方法,它們一定是屬于對象的;只要提到對象,它一定是具有屬性和方法的(自定義除外)),其中屬性又可分為數(shù)據(jù)屬性和訪問器屬性,他們的區(qū)別如下:

數(shù)據(jù)屬性一般用于存儲數(shù)據(jù)數(shù)值,訪問器屬性不包含數(shù)據(jù)值

訪問器屬性多用于get/set操作

第三部分:屬性中特性的理解

ECMAScript為了描述對象屬性(property)的各種特征,定義了特性(attribute)這個(gè)概念。也就是說特性不同于屬性,特性是為了描述屬性的。下面,我將分別講解:

  • 數(shù)據(jù)屬性及其特性
  • 訪問器屬性及其特性
  • 如何利用Object.defineProperties()方法定義多個(gè)特性
  • 如何利用Object.getOwnPropertyDescripter()方法讀取屬性的描述符以讀取屬性的特性

1.數(shù)據(jù)屬性及其特性

剛剛我們說過,數(shù)據(jù)屬性是用于存儲數(shù)據(jù)數(shù)值的,因此數(shù)據(jù)屬性具有一個(gè)數(shù)據(jù)值的位置,在這個(gè)位置可以讀取和寫入值。數(shù)據(jù)屬性有4個(gè)描述其行為的特性,由于ECMAScript規(guī)定:在JavaScript中不能直接訪問屬性的特性(注意:不是不能訪問),所以我們把它放在兩組方括號中。如下:

  • [[Configurable]]:默認(rèn)值為true,a、表示能否通過delete刪除屬性從而重新定義屬性 b、能否修改屬性的特性 c、能夠把屬性由數(shù)據(jù)屬性修改為訪問器屬性
  • [[Enumerable]]:默認(rèn)值為true,表示能否通過for-in循環(huán)返回該屬性(所以:如果為false,那么for-in循環(huán)沒法枚舉它所在的屬性)
  • [[Writable]]:默認(rèn)值為true,表示能否修改屬性的值,這是與[[Configurable]]不同之處。
  • [[Value]]:默認(rèn)值為undefined,這個(gè)值即為屬性的屬性值,我們可以在這個(gè)位置上讀取屬性值,也可以在這個(gè)位置上寫入屬性值。
  • 注意:上述的默認(rèn)是指通過構(gòu)造函數(shù)或?qū)ο笞置媪縿?chuàng)建的對象所自身擁有的屬性,而不是下面要介紹的Object.defineProperty()方法

這些特性都具有默認(rèn)值,但是如果這些默認(rèn)值不是我們想要的,該怎么辦呢?當(dāng)然就是修改啦!我們可以通過Object.defineProperty()方法來修改屬性默認(rèn)的特性。英文difineProperty即為定義屬性的意思。這個(gè)方法接收三個(gè)參數(shù):屬性所在的對象、屬性的名字和一個(gè)描述符對象。其中第三個(gè)參數(shù)描述符對象是對象字面量的方法創(chuàng)建的,里面的屬性和屬性值實(shí)際上保存的是要修改的特性和特性值。

下面通過幾個(gè)例子來深入理解。

a

var person={};
Object.defineProperty(person,"name",{
  writable:false,
  value:"zhuzhenwei"
});
console.log(person.name);//zhuzhenwei
person.name="heting";
console.log(person.name);//zhuzhenwei 

這里我用對象字面量的方法創(chuàng)建了一個(gè)對象,但是沒有同時(shí)創(chuàng)建方法和屬性。而是利用了Object.defineProperty()方法來創(chuàng)建了屬性和修改了默認(rèn)值。這里將writable設(shè)置為false,于是后面我試圖修改person.name時(shí),是無效的。

b

var person={};
Object.defineProperty(person,"name",{
  value:"zhuzhenwei"
});
console.log(person.name);//zhuzhenwei
person.name="heting";
console.log(person.name);//zhuzhenwei

注意看這個(gè)例子,這個(gè)例子中我刪去了writable:false,為什么還是不能修改呢?這是因?yàn)橹拔以诮榻B特性時(shí),前三個(gè)默認(rèn)為ture,是在創(chuàng)建對象并創(chuàng)建屬性的情況下得到的。對于通過調(diào)用Object.defineProperty()方法創(chuàng)建的屬性,其前三個(gè)特性的默認(rèn)值均為false,這里需要注意。

c

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

這里我們將新建的屬性name的特性設(shè)置為了configurable:false;因此下面刪除屬性的操作是無效的。根據(jù)b,可知configurable,默認(rèn)就是false,即使去掉也不可修改。

d

var person={};
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
  configurable:true
});
console.log(person.name);//zhuzhenwei
delete person.name;
console.log(person.name);//undefined  

在這里我將默認(rèn)的configurable的值由默認(rèn)的false修改為了true,于是變成了可配置的,那么最后就成功刪除了。

e

var person={};
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
  configurable:false
});
console.log(person.name);//zhuzhenwei
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
  configurable:true
});
console.log(person.name);//Uncaught TypeError: Cannot redefine property: name(…)

如果之前已經(jīng)設(shè)置成為了false,那么后面再改成true也是徒勞的,即:一旦把屬性設(shè)置成為不可配置的,就不能再把它變回可配置了。

f

console.log(person.name);//Uncaught TypeError: Cannot redefine property: name(…)
var person={};
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
});
console.log(person.name);//zhuzhenwei
Object.defineProperty(person,"name",{
  value:"zhuzhenwei",
  configurable:true
});
console.log(person.name);//Uncaught TypeError: Cannot redefine property: name(…)

這里可以說明,即使前一步我們不管默認(rèn)的configurable:false,后面得到的仍是不可配置。于是,可以得出結(jié)論,為了可配置,必須在第一次調(diào)用Object.defineProperty()函數(shù)時(shí)就將默認(rèn)的值修改為true。

2.訪問器屬性及其特性  

之前提到,訪問器屬性不包含數(shù)據(jù)值,他們包含一對getter函數(shù)和setter函數(shù)(這兩個(gè)函數(shù)不是必須的)。在讀取訪問器屬性時(shí),會(huì)調(diào)用getter函數(shù),這個(gè)函數(shù)負(fù)責(zé)返回有效的值;在寫入訪問器屬性是,會(huì)調(diào)用setter函數(shù)并傳入新值,這個(gè)函數(shù)負(fù)責(zé)決定如何處理數(shù)據(jù)。同樣,由于不能通過JavaScript來直接訪問得到訪問器屬性的特性,所以下面列出的特性將由[[]]括起來以作區(qū)分。

  • [[Configurable]]:默認(rèn)值為true,a、表示能否通過delete刪除屬性從而重新定義屬性 b、能否修改屬性的特性 c、能夠把屬性由訪問器屬性修改為數(shù)據(jù)屬性
  • [[Enumerable]]:默認(rèn)值為true,表示能否通過for-in循環(huán)返回該屬性(所以:如果為false,那么for-in循環(huán)沒法枚舉它所在的屬性)
  • [[Get]]:在讀取屬性時(shí)調(diào)用的函數(shù)。默認(rèn)值為undefined  關(guān)鍵:特性可以是一個(gè)函數(shù)
  • [[Set]]:  在寫入屬性時(shí)調(diào)用的函數(shù)。默認(rèn)值為undefined 關(guān)鍵:特性可以是一個(gè)函數(shù) 由于get和set函數(shù)也屬于屬性的特性,那么他們就有可能(說有可能是因?yàn)檫@兩個(gè)函數(shù)也不是必須的)出現(xiàn)在Object.defineproperty的第三個(gè)參數(shù)描述符對象的屬性中。

注意:1.相對于數(shù)據(jù)屬性,我們發(fā)現(xiàn)訪問器屬性中沒有writable特性和value特性。這是因?yàn)樵L問器屬性不包含數(shù)據(jù)值,那么我們怎么當(dāng)然就不可修改屬性的值(用不到writable特性),更不用考慮value了。

   2.訪問器屬性不能直接定義,必須是用Object.defineProperty()來定義。(通過這個(gè)規(guī)定我們就能準(zhǔn)確地判斷出訪問器屬性和數(shù)據(jù)屬性了)

通過下面這個(gè)例子來深入理解:

var book={
  _year:2004,
  edition:1
};
Object.defineProperty(book,"year",{
  get:function(){<br>            return this._year;
  },
  set:function(newValue){
    if(newValue>2004){
      this._year=newValue;
      this.edition+=newValue-2004;
    }
  }
});
book.year=2005;
console.log(book.edition);//2

幾個(gè)需要深入理解的地方:

  • 訪問器屬性不能直接定義,必須使用Object.defineProperty()來定義,且該屬性具有set和ger特性,于是可以判斷,_year和edition是數(shù)據(jù)屬性,而year是訪問器屬性。
  • 我們看到_year這個(gè)數(shù)據(jù)屬性前面是以_(下劃線)開頭的,這個(gè)一種常用的記號,用于表示只能通過對象方法訪問的屬性。從上面的例子中可以看到get相當(dāng)于描述符對象的一個(gè)方法,而_year正是在這個(gè)對象方法訪問的屬性。而edition既可以通過對象方法訪問,也可以由對象直接訪問。
  • book.year表示正在讀取訪問器屬性,這時(shí)會(huì)調(diào)用get函數(shù),并返回了2004這個(gè)有效的值。
  • book.year=2005表示寫入訪問器屬性,這時(shí)會(huì)調(diào)用set函數(shù)并傳入新值,即將2005傳給newValue,這個(gè)函數(shù)決定如何處理數(shù)據(jù)。
  • 這時(shí)使用訪問器屬性的常見方法-即設(shè)置一個(gè)屬性的值會(huì)導(dǎo)致其他屬性發(fā)生變化。

3.如何利用Object.defineProperties()方法定義多個(gè)特性

顯然,一個(gè)對象不可能只具有一個(gè)屬性,因此,定義多個(gè)屬性的可能性很大,于是JavaScript提供了Object.defineProperties()方法解決這個(gè)問題。這個(gè)方法接收兩個(gè)參數(shù),第一個(gè)是要定義屬性所在的對象,第二個(gè)是一個(gè)對象字面量方法創(chuàng)建的對象,對象的屬性名即為要定義的特姓名,對象的屬性值又是一個(gè)對象,這個(gè)對象里的屬性名和屬性值分別是特性名和特性值(這里不是很好理解,看例子即可)。

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

4.如何利用Object.getOwnPropertyDescripter()方法讀取屬性的描述符以讀取屬性的特性

  我們可以使用Object.getOwnPropertyDescripter()方法來取得給定屬性的描述符。getOwnPropertyDescripter即為取得自身屬性描述符的意思。這個(gè)方法接收兩個(gè)參數(shù):屬性所在的對象要要讀取其描述符的屬性名稱。返回一個(gè)對象。

  對于訪問器屬性而言,這個(gè)對象的屬性有configurable、enumerable、get和set;

  對于數(shù)據(jù)屬性而言,這個(gè)對象的屬性有configurable、enumerable、writable和value。

var book={};
Object.defineProperties(book,{
  _year:{
    value:2004
  },
  edition:{
    value:1
  },
  year:{
    get:function(){
      return this._year;
    },
    set:function(){
      if(newValue>2004){
        this._year=newValue;
        this.edition+=newValue-2004;
      }
    }
  }
});
var descriptor=Object.getOwnPropertyDescriptor(book,"_year");
console.log(descriptor.value);//2004
console.log(descriptor.configurable);//false 因?yàn)橥ㄟ^Object.defineProperties()方法創(chuàng)建的屬性的特性configurable enumerable都是false
console.log(typeof descriptor.get);//undefined 注意:這是數(shù)據(jù)屬性,是不具有g(shù)et特性的
var descriptor=Object.getOwnPropertyDescriptor(book,"year");
console.log(descriptor.value);//undefined
console.log(descriptor.enumerable);//false
console.log(typeof descriptor.get);//function get雖然是屬性的一個(gè)特性,但是它也是函數(shù)。

以上就是本文的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

  • js處理json以及字符串的比較等常用操作

    js處理json以及字符串的比較等常用操作

    js處理json格式的插入、修改、刪除,以及字符串的比較等常用操作,下面有五個(gè)示例,感興趣的朋友可以學(xué)習(xí)下
    2013-09-09
  • JavaScript中的閉包(Closure)詳細(xì)介紹

    JavaScript中的閉包(Closure)詳細(xì)介紹

    這篇文章主要介紹了JavaScript中的閉包(Closure)詳細(xì)介紹,函數(shù)調(diào)用對象與變量的作用域鏈、什么是閉包等內(nèi)容,并給出了實(shí)例,需要的朋友可以參考下
    2014-12-12
  • Javascript 拖拽的一些高級的應(yīng)用(逐行分析代碼,讓你輕松了拖拽的原理)

    Javascript 拖拽的一些高級的應(yīng)用(逐行分析代碼,讓你輕松了拖拽的原理)

    這篇文章主要介紹了Javascript 拖拽的一些高級的應(yīng)用(逐行分析代碼,讓你輕松了拖拽的原理),需要的朋友可以參考下
    2015-01-01
  • TypeScript中interface和type的區(qū)別詳解

    TypeScript中interface和type的區(qū)別詳解

    本文主要介紹了TypeScript中interface和type的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 原生js簡單實(shí)現(xiàn)放大鏡特效

    原生js簡單實(shí)現(xiàn)放大鏡特效

    這篇文章主要為大家詳細(xì)介紹了原生js簡單實(shí)現(xiàn)放大鏡特效,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • JavaScript編制留言簿程序代碼

    JavaScript編制留言簿程序代碼

    也許你有一個(gè)很酷的主頁,很希望與人分享。同時(shí),你希望訪問你主頁的人能對你的主頁提供一些意見和建議,或者你對某個(gè)主題感興趣,而希望客人也許能給你一幫助,這就要用到留言簿。留言簿使得你能與每一個(gè)訪問你主頁的人交換信息。
    2008-09-09
  • 詳解JavaScript數(shù)據(jù)類型和判斷方法

    詳解JavaScript數(shù)據(jù)類型和判斷方法

    這篇文章主要介紹了JavaScript數(shù)據(jù)類型和判斷方法的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)JavaScript,感興趣的朋友可以了解下
    2020-09-09
  • JS中如何判斷傳過來的JSON數(shù)據(jù)中是否存在某字段

    JS中如何判斷傳過來的JSON數(shù)據(jù)中是否存在某字段

    這篇文章主要介紹了JS中如何判斷傳過來的JSON數(shù)據(jù)中是否存在某字段,需要的朋友可以參考下
    2014-08-08
  • CSS圖片響應(yīng)式 垂直水平居中

    CSS圖片響應(yīng)式 垂直水平居中

    這篇文章主要為大家介紹CSS圖片響應(yīng)式 垂直水平居中,在最近的項(xiàng)目中經(jīng)常遇到這樣的需求,于是把相關(guān)內(nèi)容整理一下,分享給大家,需要的朋友可以來參考下
    2015-08-08
  • js實(shí)現(xiàn)文字跑馬燈效果

    js實(shí)現(xiàn)文字跑馬燈效果

    本文主要介紹了js實(shí)現(xiàn)文字超過顯示寬度每間隔1s自動(dòng)向左滾動(dòng)顯示的跑馬燈效果,具有很好的參考價(jià)值,下面跟著小編一起來看下吧
    2017-02-02

最新評論