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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

不会Object.defineProperty你就out了

發(fā)布時間:2023/12/20 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 不会Object.defineProperty你就out了 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
http://imweb.io/topic/56d40adc0848801a4ba198ce ? Object.defineProperty?,顧名思義,為對象定義屬性。在js中我們可以通過下面這幾種方法定義屬性 // (1) define someOne property name someOne.name = 'cover'; //or use (2) someOne['name'] = 'cover'; // or use (3) defineProperty Object.defineProperty(someOne, 'name', {value : 'cover' })

從上面看,貌似使用Object.defineProperty很麻煩,那為啥存在這樣的方法呢?

帶著疑問,我們來看下 Object.defineProperty的定義。


what is Object.defineProperty

The Object.defineProperty() method defines a new property directly on an object, or modifies an exisiting property on an object, and returns the object.

從上面得知,我們可以通過Object.defineProperty這個方法,直接在一個對象上定義一個新的屬性,或者是修改已存在的屬性。最終這個方法會返回該對象。

語法

Object.defineProperty(object, propertyname, descriptor)

參數(shù)

  • object?必需。 要在其上添加或修改屬性的對象。 這可能是一個本機 JavaScript對象(即用戶定義的對象或內(nèi)置對象)或 DOM 對象。propertyname?必需。 一個包含屬性名稱的字符串。descriptor?必需。 屬性描述符。 它可以針對數(shù)據(jù)屬性或訪問器屬性。
屬性的狀態(tài)設(shè)置

其中descriptor的參數(shù)值得我們關(guān)注下,該屬性可設(shè)置的值有:

  • 【value】 屬性的值,默認(rèn)為 undefined。【writable】 該屬性是否可寫,如果設(shè)置成 false,則任何對該屬性改寫的操作都無效(但不會報錯),對于像前面例子中直接在對象上定義的屬性,這個屬性該特性默認(rèn)值為為 true。
var someOne = { }; Object.defineProperty(someOne, "name", {value:"coverguo" , //由于設(shè)定了writable屬性為false 導(dǎo)致這個量不可以修改writable: false }); console.log(someOne.name); // 輸出 coverguo someOne.name = "linkzhu"; console.log(someOne.name); // 輸出coverguo
  • 【configurable]】如果為false,則任何嘗試刪除目標(biāo)屬性或修改屬性以下特性(writable, configurable, enumerable)的行為將被無效化,對于像前面例子中直接在對象上定義的屬性,這個屬性該特性默認(rèn)值為為 true。 。
var someOne = { }; Object.defineProperty(someOne, "name", {value:"coverguo" ,configurable: false }); delete someOne.name; console.log(someOne.name);// 輸出 coverguo someOne.name = "linkzhu"; console.log(someOne.name); // 輸出coverguo
  • 【enumerable】 是否能在for-in循環(huán)中遍歷出來或在Object.keys中列舉出來。對于像前面例子中直接在對象上定義的屬性,這個屬性該特性默認(rèn)值為為 true。

注意?在調(diào)用Object.defineProperty()方法時,如果不指定, configurable, enumerable, writable特性的默認(rèn)值都是false,這跟之前所 說的對于像前面例子中直接在對象上定義的屬性,這個特性默認(rèn)值為為 true。并不沖突,如下代碼所示:

//調(diào)用Object.defineProperty()方法時,如果不指定 var someOne = { }; someOne.name = 'coverguo'; console.log(Object.getOwnPropertyDescriptor(someOne, 'name')); //輸出 Object {value: "coverguo", writable: true, enumerable: true, configurable: true}//直接在對象上定義的屬性,這個特性默認(rèn)值為為 true var otherOne = {}; Object.defineProperty(otherOne, "name", {value:"coverguo" }); console.log(Object.getOwnPropertyDescriptor(otherOne, 'name')); //輸出 Object {value: "coverguo", writable: false, enumerable: false, configurable: false}
  • 【get】一旦目標(biāo)對象訪問該屬性,就會調(diào)用這個方法,并返回結(jié)果。默認(rèn)為 undefined。【set】 一旦目標(biāo)對象設(shè)置該屬性,就會調(diào)用這個方法。默認(rèn)為 undefined。

從上面,可以得知,我們可以通過使用Object.defineProperty,來定義和控制一些特殊的屬性,如屬性是否可讀,屬性是否可枚舉,甚至修改屬性的修改器(setter)和獲取器(getter)

那什么場景和地方適合使用到特殊的屬性呢?


實際運用

在一些框架,如vue、express、qjs等,經(jīng)常會看到對Object.defineProperty的使用。那這些框架是如何使用呢?

MVVM中數(shù)據(jù)‘雙向綁定’實現(xiàn)

如vue,qjs等大部分mvvm框架(angular用的是臟處理)都是通過Object.defineProperty來實現(xiàn)數(shù)據(jù)綁定的 為了更詳細的說明,我將在下一篇文章跟大家講解下。下面篇幅先不展開。(別扔磚。。。)

優(yōu)化對象獲取和修改屬性方式

這個優(yōu)化對象獲取和修改屬性方式,是什么意思呢? 過去我們在設(shè)置dom節(jié)點transform時是這樣的。

//加入有一個目標(biāo)節(jié)點, 我們想設(shè)置其位移時是這樣的 var targetDom = document.getElementById('target'); var transformText = 'translateX(' + 10 + 'px)'; targetDom.style.webkitTransform = transformText; targetDom.style.transform = transformText;

通過上面,可以看到如果頁面是需要許多動畫時,我們這樣編寫transform屬性是十分蛋疼的。(┬_┬)

但如果通過Object.defineProperty, 我們則可以

//這里只是簡單設(shè)置下translateX的屬性,其他如scale等屬性可自己去嘗試Object.defineProperty(dom, 'translateX', { set: function(value) {var transformText = 'translateX(' + value + 'px)';dom.style.webkitTransform = transformText;dom.style.transform = transformText; } //這樣再后面調(diào)用的時候, 十分簡單 dom.translateX = 10; dom.translateX = -10; //甚至可以拓展設(shè)置如scale, originX, translateZ,等各個屬性,達到下面的效果 dom.scale = 1.5; //放大1.5倍 dom.originX = 5; //設(shè)置中心點X }

上面只是個簡單的版本,并不是最合理的寫法,但主要是為了說明具體的意圖和方法

有興趣了解更多可以看下面這個庫:https://github.com/AlloyTeam/AlloyTouch/blob/master/transform.js

增加屬性獲取和修改時的信息

如在Express4.0中,該版本去除了一些舊版本的中間件,為了讓用戶能夠更好地發(fā)現(xiàn),其有下面這段代碼,通過修改get屬性方法,讓用戶調(diào)用廢棄屬性時拋錯并帶上自定義的錯誤信息。

['json','urlencoded','bodyParser','compress','cookieSession','session','logger','cookieParser','favicon','responseTime','errorHandler','timeout','methodOverride','vhost','csrf','directory','limit','multipart','staticCache', ].forEach(function (name) {Object.defineProperty(exports, name, {get: function () {throw new Error('Most middleware (like ' + name + ') is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.');},configurable: true}); });

其他如設(shè)置常量等用途。。。


兼容

?

最后注意下,Object.defineProperty是ES5的屬性,大部分場景使用是沒問題的, 但在一些場景如IE8以下是使用不到的哈。

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

總結(jié)

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

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