1. 程式人生 > >js物件可擴充套件性和屬性的四個特性(上)

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));

相關推薦

no