日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

JavaScript Object.defineProperty()方法详解

發(fā)布時間:2023/12/20 javascript 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JavaScript Object.defineProperty()方法详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Object.defineProperty() 方法直接在一個對象上定義一個新屬性,或者修改一個已經(jīng)存在的屬性,并返回這個對象。因此,又稱為屬性攔截器。在前端中,webpack以及vue的原理都應(yīng)用了這個方法。

語法

Object.defineProperty(obj, prop, descriptor)

參數(shù)

  • obj ?需要定義屬性的對象。
  • prop ?需要定義或者修改的屬性名。
  • descriptor ?需要定義或者修改的屬性的描述符。

描述

該方法允許精確添加或者修改對象的屬性。一般情況下,我們?yōu)閷ο筇砑訉傩允峭ㄟ^賦值來創(chuàng)建并顯示在屬性枚舉中(for...in或者Object.keys方法),但這種添加的屬性值可以被改變,也可以被刪除。而使用Object.defineProperty()則允許改變這些額外細(xì)節(jié)的默認(rèn)設(shè)置。比如,默認(rèn)情況下使用Object.defineProperty()增加的屬性是不可改變的。

對象里目前存在的屬性描述符有兩種主要形式:

數(shù)據(jù)描述符和存取描述符

數(shù)據(jù)描述符是一個擁有可寫或者不可寫的屬性。存取描述符是由一對setter-getter函數(shù)功能來描述的屬性。描述符必須是兩種形式之一,不能同時是兩種。

數(shù)據(jù)描述符合存取符均具有以下可選鍵值:

  • configurable ?僅當(dāng)該屬性為true時,該屬性才能夠被改變,也能被刪除。默認(rèn)為false。
  • enumerable ? 僅當(dāng)該屬性為true時,該屬性才能出現(xiàn)在對象的枚舉屬性中。默認(rèn)為false。
  • value ?該屬性對應(yīng)的值。可以是任何有效的Javascript值,包括數(shù)值、對象和函數(shù)等。默認(rèn)值為underfined。
  • writable ?僅當(dāng)該屬性為true時,該屬性才能被賦值被改變。默認(rèn)為false。
  • get ?一個屬性提供的getter方法。如果沒有g(shù)etter則為undefined。該方法返回值作為對象屬性的賦值。默認(rèn)為undefined。
  • set??一個屬性提供的setter方法。如果沒有setter則為undefined。該方法將接受唯一參數(shù),并將該參數(shù)的新值分配給該屬性。默認(rèn)為undefined。
// 使用 __proto__ Object.defineProperty(obj, "key", {__proto__: null, // 沒有繼承的屬性value: "static" // 沒有 enumerable// 沒有 configurable// 沒有 writable// 作為默認(rèn)值 });// 顯式 Object.defineProperty(obj, "key", {enumerable: false,configurable: false,writable: false,value: "static" });// 循環(huán)使用同一對象 function withValue(value) {var d = withValue.d || (withValue.d = {enumerable: false,writable: false,configurable: false,value: null});d.value = value;return d; } // ... 并且 ... Object.defineProperty(obj, "key", withValue("static"));// 如果 freeze 可用, 防止代碼添加或刪除對象原型的屬性 // (value, get, set, enumerable, writable, configurable) (Object.freeze||Object)(Object.prototype);

創(chuàng)建屬性

如果對象中不存在指定的屬性,Object.defineProperty()就創(chuàng)建這個屬性。當(dāng)描述符中省略某些字段時,這些字段將使用它們的默認(rèn)值。擁有布爾值的字段的默認(rèn)值都是false。value,get和set字段的默認(rèn)值為undefined。定義屬性時如果沒有g(shù)et/set/value/writable,那它將被歸為數(shù)據(jù)類描述。

var o = {}; // 創(chuàng)建一個新對象// Example of an object property added with defineProperty with a data property descriptor Object.defineProperty(o, "a", {value : 37,writable : true,enumerable : true,configurable : true}); // 對象o擁有了屬性a,值為37// Example of an object property added with defineProperty with an accessor property descriptor var bValue; Object.defineProperty(o, "b", {get : function(){ return bValue; },set : function(newValue){ bValue = newValue; },enumerable : true,configurable : true}); o.b = 38; // 對象o擁有了屬性b,值為38// The value of o.b is now always identical to bValue, unless o.b is redefined// 數(shù)據(jù)描述符和存取描述符不能混合使用 Object.defineProperty(o, "conflict", { value: 0x9f91102, get: function() { return 0xdeadbeef; } }); // throws a TypeError: value appears only in data descriptors, get appears only in accessor descriptors

修改屬性

如果屬性已經(jīng)存在,Object.defineProperty()將嘗試根據(jù)描述符的值以及對象當(dāng)前的配置來修改這個屬性。如果描述的configurable特性為false,那么除了writable外,其他特性都不能被修改,并且數(shù)據(jù)和存取描述符也不能相互切磋。

如果configurable為false,則其writable特性也只能為false。

如果嘗試修改該值時,那么將會出現(xiàn)TypeError。

Writable屬性

當(dāng)屬性特性writable設(shè)置為false時,表示non-writable,屬性將不能被修改。修改一個non-writable的屬性不會改變屬性的值,同時也不會報出異常。

var o = {}; // 創(chuàng)建一個新對象Object.defineProperty(o, "a", { value : 37,writable : false });console.log(o.a); // 打印 37 o.a = 25; // 沒有錯誤拋出(在嚴(yán)格模式下會拋出,即使之前已經(jīng)有相同的值) console.log(o.a); // 打印 37, 賦值不起作用。

Enumerable 特性

屬性特性enumerable定義了對象的屬性是否可以在for...in循環(huán)和Object.keys()中枚舉。

var o = {}; Object.defineProperty(o, "a", { value : 1, enumerable:true }); Object.defineProperty(o, "b", { value : 2, enumerable:false }); Object.defineProperty(o, "c", { value : 3 }); // enumerable defaults to false o.d = 4; // 如果使用直接賦值的方式創(chuàng)建對象的屬性,則這個屬性的enumerable為truefor (var i in o) { console.log(i); } // 打印 'a' 和 'd' (in undefined order)Object.keys(o); // ["a", "d"]o.propertyIsEnumerable('a'); // true o.propertyIsEnumerable('b'); // false o.propertyIsEnumerable('c'); // false

Configurable特性

configurable特性表示對象的屬性是否可以被刪除,以及除writable特性外的其他特性是否可以被修改。

var o = {}; Object.defineProperty(o, "a", { get : function(){return 1;}, configurable : false } );// throws a TypeError Object.defineProperty(o, "a", {configurable : true}); // throws a TypeError Object.defineProperty(o, "a", {enumerable : true}); // throws a TypeError (set was undefined previously) Object.defineProperty(o, "a", {set : function(){}}); // throws a TypeError (even though the new get does exactly the same thing) Object.defineProperty(o, "a", {get : function(){return 1;}}); // throws a TypeError Object.defineProperty(o, "a", {value : 12});console.log(o.a); // logs 1 delete o.a; // Nothing happens console.log(o.a); // logs 1

添加多個屬性和默認(rèn)值

考慮特性被賦予的默認(rèn)特性值非常重要,通常,使用點運算符和Object.defineProperty()為對象的屬性賦值時,數(shù)據(jù)描述符中的屬性默認(rèn)值是不同的,如下所示。

var o = {};o.a = 1; // 等同于 : Object.defineProperty(o, "a", {value : 1,writable : true,configurable : true,enumerable : true });// 另一方面, Object.defineProperty(o, "a", { value : 1 }); // 等同于 : Object.defineProperty(o, "a", {value : 1,writable : false,configurable : false,enumerable : false });

Setters 和Getters

下面的例子說明了如何實現(xiàn)自我存檔的對象。當(dāng)temperature屬性設(shè)置為1時,archive數(shù)組會得到一個log。

function Archiver() {var temperature = null;var archive = [];Object.defineProperty(this, 'temperature', {get: function() {console.log('get!');return temperature;},set: function(value) {temperature = value;archive.push({ val: temperature });}});this.getArchive = function() { return archive; }; }var arc = new Archiver(); arc.temperature; // 'get!' arc.temperature = 11; arc.temperature = 13; arc.getArchive(); // [{ val: 11 }, { val: 13 }] var pattern = {get: function () {return 'I alway return this string,whatever you have assigned';},set: function () {this.myname = 'this is my name string';} };function TestDefineSetAndGet() {Object.defineProperty(this, 'myproperty', pattern); }var instance = new TestDefineSetAndGet(); instance.myproperty = 'test';// 'I alway return this string,whatever you have assigned' console.log(instance.myproperty); // 'this is my name string' console.log(instance.myname);

ps: 本文轉(zhuǎn)自jiangxiaobo博客

轉(zhuǎn)載于:https://www.cnblogs.com/astonesh/p/8386476.html

總結(jié)

以上是生活随笔為你收集整理的JavaScript Object.defineProperty()方法详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。