js對象—類型和屬性特性


前言

  權威指南中摘要的,工作中用不到的,重要的js基礎。

三類對象兩類屬性

  內置對象(native object) 是由ECMScript規范定義的對象或者類。例如:函數,數組,日期,正則...

  宿主對象(host object) 是由js編譯器所嵌入的宿主環境(web瀏覽器)所定義的。比如客戶端js中表示網頁結構的HTMLElement對象就是宿主環境創建的對象。宿主環境定義的對象可以直接使用的話,我們也可以把它們當做內置對象。

  自定義對象(user-defined object) 由運行中的js創建的對象。

  自有屬性(own property) 直接在對象當中定義的屬性,區別於繼承屬性。

  繼承屬性(inherited property) 在對象原型中定義的屬性。

屬性描述符對象

  ES5中定義了一個屬性描述符對象(property descriptor)。這個對象屬性和他們所描述的屬性特性是同名的。

  value:屬性的值值。

  writable:可寫性,是否可以設置值。

  enumerable:可枚舉性,遍歷對象時該屬性會不會出現。

  configurable:可配置性。

作為屬性特性的存取器

  對象屬性是由名字和值跟一組屬性特性構成的,屬性值可以用一個或兩個方法進行替代,這兩個方法就是getter和setter定義的屬性特性。由getter和setter定義的屬性叫做“存取器屬性”。

  存取器屬性的特點:

    1,當程序查詢存取器屬性值時,js調用getter方法。這個方法返回的就是屬性存取表單式的值。

    2,當程序設置存取器屬性值是,js調用setter方法。這個方法將賦值表達式右邊的計算結果,傳入setter。

    3,存取器屬性不具有可寫性,如果同時具有getter和setter方法那它就是一個讀寫屬性。也可以只擁有其中一個,來作為只讀或者只寫屬性。

  定義存取器屬性

var o = { // 普通的數據屬性
    data:null; // 存取器屬性
 set ODate(value){ this.data = value; // 處理復制表達式右側計算結果(value)的屬性設置表達式
 }, get ODate(){ return this.data; // 屬性返回表達式
 } } // 設置data,獲取data
o.OData = {id:0}; o.OData; =>{id:0}

 

獲取自有屬性的屬性描述符對象Object.getOwnPropertyDescriptor()

// 當我們為對象創建屬性時如果沒有指定屬性描述符,那就都是默認的 可枚舉,可配置,可讀寫,
var
obj = { name:"小花" } console.log(Object.getOwnPropertyDescriptor(obj,"name"));
 {value: "小花", writable: true, enumerable: true, configurable: true}

定義屬性描述符對象Object.defineProperty(obj,attributeName,PropertyDescriptor)

// 定義cat的name屬性為不可枚舉(此后使用for in 遍歷對象屬性時,name不會出現),value為小花
var cat = {}; Object.defineProrerty(cat , "name",{ value:"小花", enumerable:false })

同時定義或修改對象的多個屬性及其描述符Object.defineProperties()

// 參數一是目標對象,參數二是屬性為鍵描述符為值的對象
var cat = Object.defineProperties({},{ name:{value:"小花"}, age:{value:6}, // 值為大菊,不可寫
    type:{value:"大菊",writable:false}, // 存取器特性替代屬性值value,不可枚舉
 date:{ get:function(){return [this.name,this.age]}, enumerable:false } })

使用屬性描述符實現jq中$.extend方法的部分功能:

  1,給根對象Object的原型拓展一個extend方法。

  2,接收要復制的目標對象,將他的屬性和屬性特性復制到調用對象。

  3,復制規則:存在同名屬性時保留原有屬性,復制目標對象上的一切可枚舉自有屬性。

Object.defineproperty(Object.prototype,"extend",{ enumerable:false, value:function(o){ // 得到O對象的所有自有屬性名稱列表
        var proNames = Object.getOwnPropertyNames(o); // 排除已存在屬性
        for(var i = 0; i < proNames.length; i++){ if(proNames[i] in this) continue; // 獲取該屬性的屬性描述符對象
            var desc = Object.getOwnpropertyDescriptor(o,proName[i]); // 將屬性copy到調用對象
            Object.defineProperty(this,proName[i],desc); } } })

小結:

  》三類對象:內置對象,宿主對象,自定義對象。

  》兩類屬性:自有屬性,繼承屬性。

  》存取器屬性:區別於數據屬性,屬性名稱就是getter、setter方法名稱。

  》屬性每個屬性都擁有屬性描述符對象,不顯示定義屬性的描述符對象時,他們默認都是可讀寫,可枚舉,可配置的。

  》ES5提供了兩個API用來定義或修改屬性及其描述符:

    獲取指定對象指定屬性的屬性描述符對象:Object.getOwnPropertyDescriptor()

    同時定義多個屬性及其描述符:Object.defineProperties() 

    定義單個屬性及其描述符:Object.defineProperty(obj,attributeName,PropertyDescriptor)

  》js中的普通對象能夠從根對象上繼承到它提供的屬性方法。我們基於這個特性為根對象創建了一個extend方法可以用來復制其他對象上的自有可枚舉屬性。

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM