js對象可擴展性和屬性的四個特性(上)


js對象可擴展性和屬性的四個特性(上)


一、前言

  • 再次花時間回顧一下基礎,畢竟要想樓建的好,地基就要牢固,嘻嘻!

  • 在開始之前需要具備對prototype、__proto__、constructor有一定得了解,可以看看我之前寫的一篇文章=>通道

  • 之前的用戶管理系統已經差不多了,順便加了個socket聊天的,但是由於做java后台的哪個朋友節奏跟不上來,所以即時聊天的后台就是node+socket-io寫的,由於用戶列表也涉及比較多的用戶隱私問題,所以我設置了頁面權限和接口權限,然后下面開放的幾個賬號就只能看到幾個頁面而已,哈哈。=>通道

  • 體驗賬號1:賬號:“123456”。密碼:“123456”

  • 體驗賬號2:賬號:“123123”。密碼:“123123”


二、目錄

  • 對象屬性的四個特性
  • 對象的可擴展性
  • 刪除屬性
  • 檢測屬性
  • 枚舉屬性
  • 屬性的getter和setter

三、對象屬性的四個特性

1、定義

1.1、什么是數據屬性?

數據屬性就是我們平常看到的對象普通屬性。

數據屬性的特性為以下四種:

值(value)
可寫性(writable)
可枚舉性(enumerable)
可配置性(configurable)

1.2、什么是存儲器屬性?

存儲器屬性是由getter和setter定義的屬性

存儲器屬性特性為以下四種:

讀取(get)
寫入(set)
可枚舉性(enumerable)
可配置性(configurable)

2、方法

2.1、獲取某個對象特定屬性的屬性描述

Object.getOwnPropertyDescriptor()
        const log = console.log;
        //返回數據數據的描述
        let aa = {
            x: 1
        };
        log(Object.getOwnPropertyDescriptor(aa, 'x'))
            //返回存儲器屬性的描述
        let bb = {
            get y() {
                return 2;
            },
        }
        log(Object.getOwnPropertyDescriptor(bb, 'y'))
            //對於一個不存在的屬性或者繼承屬性返回undefined
        log(Object.getOwnPropertyDescriptor({}, 'x'))
        log(Object.getOwnPropertyDescriptor({}, 'toString'))

2.2、讓新建屬性具有某種特性

Object.defineProperty()

說明:

  • defineProperty不能修改繼承屬性
  • defineProperty不必包含所有四個屬性,對於已有的屬性來說,未指定的特性不做修改,只對指定特性進行修改。
  • 對於新創建的屬性來說默認是false或者undefined。
  • 當configurable設置為false,就不能再設置為true了,因為不可配置也不能配置自己
  • 當configurable設置為true,writable設置為false時,是可以通過配置特性更改value值的
  • 當configurable設置為false時,writable可以從true設置為false,當時不能從false設置為true
        const log = console.log;
        var aa = {
            y: 22
        };
        //添加一個x屬性為不可寫、不可枚舉、可配置
        Object.defineProperty(aa, 'x', {
            value: 1,
            writable: false,
            enumerable: false,
            configurable: true
        })
        log(aa.x);
        aa.x = 2; //嘗試修改這個屬性會失敗,但是不會報錯,在嚴格模式下會報錯
        log(aa.x)
        for (let i in aa) {
            //不可枚舉數據屬性x,但是y可以枚舉
            console.log(i)
        }
        //因為這個x屬性依然是可以配置的,所以可以通過配置的方式對值進行修改
        Object.defineProperty(aa, 'x', {
            value: 3,
        })
        log(aa.x);
        //將數據屬性設置為存儲器屬性
        Object.defineProperty(aa, 'x', {
            get: function() {
                return 4;
            },
        })
        log(aa.x)

2.3、同時修改多個屬性的特性

Object.defineProperties()
        const log = console.log;
        var aa = {};
        Object.defineProperties(aa, {
            x: {value: 1,writable: false,enumerable: true,configurable: false},
            y: {value: 2,writable: false,enumerable: true,configurable: false},
            z: {
                get:function(){
                    return 3
                },
                enumerable: false,
                configurable: false
            }
        })
        for(let i in aa){
            log(i,'---',aa[i])
        }
        log('z','---',aa.z)


四、對象的可擴展性

1、定義

1.1、什么是可擴展性?

對象可擴展性是指是否可以給該對象添加新的屬性

2、方法

2.1、將對象設置為不可擴展

Object.preventExtensions()

說明:

  • 對象一旦設置不為不可擴展就不能轉換為可擴展了
  • Object.preventExtensions只會影響對象本身的可擴展性,所以依然還是可以給對象原型添加屬性。
        const log = console.log;
        var aa = {};
        Object.preventExtensions(aa);
        aa.x = 1;
        log(aa.x)

2.2、檢測對象是否是可擴展的

Object.isExtensible()
        //在《javascript權威指南》第六版中6.8.3節介紹可擴展性的時候,將isExtensible寫為esExtensible了。
        const log = console.log;
        var aa = {};
        var bb = {};
        Object.preventExtensions(aa);
        log(Object.isExtensible(aa))
        log(Object.isExtensible(bb))

2.3、將對象封閉(sealed)

Object.seal()

說明:

  • Object.seal不僅可以設置對象的可擴展性,還可以設置對象的所有自有屬性的可配置性
  • 將對象設置為不可擴展並且不可配置,也就是說不能給這個對象添加新屬性,而且已有的屬性不能刪除或者配置。
  • 不過這些屬性可寫特性依然是可以配置的
        const log = console.log;
        var aa = {
            y: 2
        };
        Object.seal(aa);
        aa.x = 1;
        log(aa.x);
        log(Object.getOwnPropertyDescriptor(aa, 'y'))
        Object.defineProperty(aa, 'y', {
            writable: false,
        })
        log(Object.getOwnPropertyDescriptor(aa, 'y'))

2.4、檢測對象是否被封閉

Object.isSealed()
        const log = console.log;
        var aa = {};
        var bb = {};
        Object.seal(aa);
        log(Object.isSealed(aa));
        log(Object.isSealed(bb))

2.5、將對象凍結(freeze)

Object.freeze()

說明:

  • freeze不僅僅可以將對象設置為不可擴展和所有屬性為不可配置,並且會將所有對象屬性設置為只讀。
  • 如果存取器屬性具有setter方法,則不會受到影響,仍然可以通過此方法給屬性賦值。
        const log = console.log;
        var aa = {
            x: 1
        };
        Object.freeze(aa);
        log(Object.getOwnPropertyDescriptor(aa, 'x'))

2.6、檢測對象是否配凍結

Object.isFreeze()
        const log = console.log;
        var aa = {};
        var bb = {};
        Object.freeze(aa);
        log(Object.isFrozen(aa));
        log(Object.isFrozen(bb));


免責聲明!

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



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