摘要:描述符對象就是上面提到的個描述其行為的特性和。真是奇怪讀取屬性的特征使用的方法,可以取得給定屬性的描述符。接收兩個參數所在的對象和要讀取其描述符的屬性名稱。
對象的基本概念
面向對象(Object-Oriented,OO),的語言最大的特征就是它們都有類的概念,通過類可以創建任意多個具有相同屬性和方法的對象。
創建自定義對象最簡單的方式就是創建一個Object 的實例,然后再給他添加屬性和方法。如:
var math = new Object(); math.π = function pi(){ return Math.PI; }; document.write(math.π());
這里借用了Math.PI,最后的結果是無論調用的是math.π還是Math.PI都會返回圓周率的值。其中,前者就是我們自己自定義的對象。又如:
var person = new Object(); person.name = "Oliver"; person.age = 18; person.job = "Software Engineer"; person.sayName = function(){ alert(this.name); };
上面這個對象可以用下面的結構化圖像解釋清楚:
Object => person |-name |-age |-job |-sayName() |-this.name
這里面person 是對象,又是Object 的實例,其中他有三個屬性和一個方法,這個方法用于顯示this.name,會被解析為person.name。
上面的例子又可以用字面量的語法寫成這樣:
var person = { name: "Oliver", age: 18, job: "Software Engineer", sayName: function(){ alert(this.name); } };屬性類型
根據ECMA-262 第五版,ECMAScript 中有兩種屬性(內部值):數據屬性和訪問器屬性。為了表示特性的內部值,該規范把它們放在了兩對方括號中,如[[Enumerable]]。
數據屬性數據屬性有4 個描述其行為的特性:
[[Configurable]]:表示能否通過delete 刪除屬性;
[[Enumerable]]:表示能否通過for-in 循環返回屬性;
[[Writable]]:表示能否修改屬性的值;
[[Valu]]:包含這個屬性的數據值;
其中,前三個默認都是true,最后一個默認為undefined。
如何修改數據屬性默認的特性呢?這就要用到ECMAScript 5 的Object.defineProperty()方法。這個方法接收三個參數:屬性所在的對象,屬性的名字和一個描述符對象。描述符對象就是上面提到的4 個描述其行為的特性:configurable、enumerable、writable 和value。
修改方式如下:
var person = {}; Object.defineProperty(person, "name", { writable: false, value: "Oliver" }); console.log(person.name); //Oliver person.name = "Niko"; console.log(person.name); //Niko
又如:
var person = { name: "Troy", age: 18 }; Object.defineProperty(person, "name", { writable: false, value: "Oliver", enumerable: false }); for (x in person){ console.log(x); //age }
如:
var person = { name: "Troy", age: 18 }; Object.defineProperty(person, "name", { value: "Oliver", configurable: false }); delete person.name; console.log(person.name) //Oliver
要注意的是,一旦把屬性定義為不可配置的,就不能再把它變回可配置的了。
不要在IE8 中使用Object.defineProperty()方法。
訪問器屬性該屬性不包含數據值,只有一對getter 和setter 函數(兩者為可選);4個 特性如下:
[[Configurable]]
[[Enumerable]]
[[Get]]:在讀取屬性時調用的函數;默認undefined;
[[Set]]:在寫入屬性時調用的函數;默認undefined;
同樣,必須使用Object.defindProperty()來定義。如:
var book = { _year: 2004, edition: 1 }; Object.defineProperty(book, "year", { get: function(){ return this._year; }, set: function(newValue){ if(newValue > 2004){ this._year = newValue; this.edition += newValue - 2004; } } }); book.year = 2006; console.log(book.edition);
兩個默認的屬性:_year 和edition。year 前面的下劃線是一種常用的記號,用于表示只能通過對象方法訪問的屬性。
對于上面的下劃線不太明白的,可以參考下面一種寫法:
var book = { year: 2004, edition: 1 }; Object.defineProperty(book, "setYear", { get: function(){ return this.year; }, set: function(newValue){ if(newValue > 2004){ this.year = newValue; this.edition += newValue - 2004; } } }); book.setYear = 2007; console.log(book.edition); console.log(book.year)
兩者功能相同,實際上該方法是給book 對象又設置了另一個屬性即第一段代碼中的_year 和第二段代碼中的setYear。
另外,一般在這個方法之前,要創建訪問器屬性,一般都是使用兩個非標準的方法:__defineGetter__()和__defineSetter__()。如:
var book = { name: "hello" }; book.__defineGetter__("name",function(){ return "world"; }); document.write(book.name);定義多個屬性
ECMAScript 5 又定義了一個Object.defineProperties()方法。利用這個方法可以通過描述符一次定義多個屬性。如:
var book = {}; Object.defineProperties(book, { _year:{ value: 2004, writable: true }, edition:{ value: 1, writable: true }, year:{ get: function(){ return this._year; }, set: function(newValue){ if(newValue > 2004){ this._year = newValue; this.edition += newValue - 2004; } } } }); book.year = 2006; console.log(book.year + " " + book.edition);
還真是奇葩,不知是否瀏覽器的問題,數據屬性還是要加上為true 的writable 訪問器屬性才能起作用。不是默認為true 么。真是奇怪
讀取屬性的特征使用ECMAScript 5 的Object.getOwnPropertyDescriptor()方法,可以取得給定屬性的描述符。接收兩個參數:所在的對象和要讀取其描述符的屬性名稱。如:
var cars = {}; Object.defineProperties(cars, { name: { value: "Benz", writable: false }, _color: { value: "White", writable: true }, price: { value: 300000, writable: true }, color: { get: function(){ return this._color; }, set: function(newValue){ if(newValue == "Black"){ this._color = "Black"; this.price = 280000 }else if(newValue == "White"){ this._color = "White"; this.price = 300000 } } } }); function selectColors(colorValue){ cars.color = colorValue; document.write(cars.name + ": " + cars.color + "款 " + "(" + cars.price + "元人民幣" + ")"); } selectColors("Black"); //Benz: Black款 (280000元人民幣) selectColors("White"); //Benz: White款 (300000元人民幣) var descriptor = Object.getOwnPropertyDescriptor(cars, "name"); document.write(descriptor.value + descriptor.writable + descriptor.configurable + descriptor.enumerable); //Benzfalsefalsefalse var descriptor2 = Object.getOwnPropertyDescriptor(cars, "color"); document.write(descriptor2.get + descriptor2.set + descriptor2.configurable + descriptor2.enumerable + descriptor2.value); //function () { return this._color; }function (newValue) { if(newValue == "Black"){ this._color = "Black"; this.price = 280000 }else if(newValue == "White"){ this._color = "White"; this.price = 300000 } }falsefalseundefined
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86238.html
摘要:如繼承了這里就不必寫該方法的主要優勢就是可以在子類型構造函數中向超類型構造函數傳遞參數。以上原型式繼承通常只是想讓一個對象與另一個對象保持類似的情況下,原型式繼承是完全可以勝任的。 繼承 繼承分為接口繼承和實現繼承;接口繼承只繼承方法簽名,實現繼承則繼承實際的方法;由于函數沒有簽名,所以ECMAScript 中沒有接口繼承,只能依靠原型鏈來實現實現繼承。 原型鏈 基本思想是利用原型鏈讓...
摘要:不必在構造函數中定義對象實例的信息。其次,按照一切事物皆對象的這餓極本的面向對象的法則來說,類本身并不是一個對象,然而原型方式的構造函數和原型本身也是個對象。第二個問題就是在創建子類型的實例時,不能向超類型的構造函數中傳遞參數。 前言 對象(Object)應該算是js中最為重要的部分,也是js中非常難懂晦澀的一部分。更是面試以及框架設計中各出沒。寫這篇文章,主要參考與JavaScrip...
摘要:個人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現在已經一年的時間了,由于工作比較忙,更新緩慢,后面還是會繼更新,現將已經寫好的文章整理一個目錄,方便更多的小伙伴去學習。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個人前端文章整理 從最開始萌生寫文章的想法,到著手...
摘要:所以,可以創建自定義的構造函數,從而定義自定義對象類型的屬性和方法。如對于構造函數原型屬性以及實例之間的關系,參見高級程序設計一書中第章節。穩妥構造函數模式穩妥對象,指的是沒有公共屬性,且其方法也不引用的對象如 創建對象 Object 構造函數或對象字面量都可以用來創建單個對象。但這個方法的缺點非常明顯:同一個接口創建很可耐多對象會產生大量的重復代碼。為了解決這個問題,人們開始使用工廠...
閱讀 671·2023-04-25 18:59
閱讀 1211·2021-09-22 16:00
閱讀 1889·2021-09-22 15:42
閱讀 3594·2021-09-22 15:27
閱讀 1246·2019-08-30 15:54
閱讀 1104·2019-08-30 11:16
閱讀 2445·2019-08-29 16:24
閱讀 820·2019-08-29 12:14