前言
基於類別的物件:我們都知道物件導向的語言中有一個明顯的標誌,就是都有類別的概念,透過類別這個類似模板的東西我們可以創造許多個具有相同的屬性和方法的物件。然而在ECMAScript中並沒有類別的概念,自然它與基於類別的語言中的物件也會有所不同。
js中的物件: 無序 的屬性的集合,屬性可以包含基本值、物件、函數。即js中的物件是一組沒有特定順序的值,物件的每個屬性或方法都有一個自己的名字,而每個名字都與一個值相對應。
理解物件
建立物件的方式
1 建立一個物件的最簡單的方式是建立一個Object實例,之後為其新增屬性和方法。
例如
var person = new Object(); person.name='谦龙'; person.sex='男'; person.sayNameAndSex=function(){ console.log(this.name,this.sex) } person.sayNameAndSex(); // 谦龙 男
2 使用物件字面量數
例如
var person={ name:'谦龙', sex:'男', sayNameAndSex:function(){ console.log(this.name,this.sex) } } person.sayNameAndSex(); // 谦龙 男
屬性的型別
ECMAScript有兩種資料屬性:資料屬性和存取器屬性。
資料屬性
資料屬性包含一個資料值的位置。在這個位置可以讀取和寫入值。共有四個描述其行為的特性。
1.[[Configurable]]:表示能否透過delete刪除屬性從而重新定義屬性...預設值為true
2.[[Enumerable]]:表示能否透過for in 迴圈回傳屬性...預設為true
3.[[Writable]]:表示能否修改屬性的值...預設為true
4.[[Value]]:表示這個屬性的值.預設為undefined
要修改屬性預設的特性,必須使用ES5的Object.defineProperty()方法,而該方法接收三個參數:屬性所在的物件、屬性的名稱、還有一個描述屬性特性的物件(configurable、enumerable 、writable、value),設定其中的一個或多個值可以修改對應的特性
DEMO
var person={}; Object.defineProperty(person,'name',{ configurable:false,//表示不允许通过delete删除属性 writable:false,//表示不允许重写 ennumerable:false,//表示不允许通过for in遍历 value:'谦龙'//设置该对象中属性的值 }) person.name='谦龙2';//尝试重新设置 结果不生效 delete person.name;//尝试删除 结果不生效 for(var attr in person){ console.log(person[attr]);// false } console.log(person.name);//谦龙
注意:將 configurable 設為false後 不允許再修改為true,另外在呼叫Object.defineProperty()方法的時候,configurable、ennumerable、writable預設值為false。
訪問器屬性
存取器屬性不包含資料值,它們包含一對getter、setter函數(但是這兩個函數並不是必須的)在讀取存取器屬性的時候,會呼叫getter函數,這個函數是負責傳回有效的值,在寫入存取器屬性的時候會呼叫setter函數並傳入新值,這個函數負責如何處理資料。
訪問器屬性具有以下的特性
[[configurable]] 表示能否透過delete來刪除屬性從而定義新的屬性
[[enumerable]] 表示能否透過for in迴圈來遍歷回傳屬性
[[get]] 在讀取屬性時候呼叫的函數,預設為undefined
[[set]] 在寫入函數的時候呼叫的函數,預設的值為undefined
注意:存取器屬性不能直接定義,必須透過Object.defineProterty()定義
DEMO
var book={ _year:2015, //这里的下划线是常见的记号,表示只能通过对象的方法才能访问的属性 edition:1 } Object.defineProperty(book,'year',{ get:function(){ return this._year; //即默认通过 book.year获取值的时候 返回的是 boot._year的值 }, set: function (value) {//在对 boot.year设置值的时候 默认调用的方法 对数据进行处理 var _year=this._year; if(value > _year){ this._year=value; this.edition+=value-_year; } } }) book.year = 2016; console.log(book.year,book.edition); // 2016 2
定義多個屬性
我們可以透過ES5中的Object.defineProperties()方法來為物件新增多個屬性,該方法接受兩個物件參數,第一個參數是要新增和修改其屬性的對象,第二個物件的屬性和第一個物件中要新增和修改的屬性一一對應。
DEMO
var book={}; Object.defineProperties(book,{ _year:{ value:2015, writable:true //注意这里设置成true 才可以 "写" 默认是false }, edition:{ value:1, writable:true //注意这里设置成true 才可以 "写" 默认是false }, year:{ get:function(){ return this._year; }, set: function (value) { var _year=this._year; if(value > _year){ this._year=value; this.edition+=value-_year; } } } }) book.year=2016; console.log(book.year,book.edition); // 2016 2
讀取物件屬性的特性
使用ES5中的Object.getOwnPropertyDescriptor()方法,可以去的給定的屬性的描述符。
此方法接收兩個參數:屬性所在的物件和要讀取描述符的屬性名稱。傳回的是一個對象,如果是資料屬性,則傳回的屬性有 configurable,enumerable,writable,value.如果是存取器屬性則傳回的屬性有 configurable,enumerable,get,set
DEMO
var book={}; Object.defineProperties(book,{ _year:{ value:2015, writable:true }, edition:{ value:1, writable:true }, year:{ get:function(){ return this._year; }, set: function (value) { var _year=this._year; if(value > _year){ this._year=value; this.edition+=value-_year; } } } }) //对象遍历函数 function showAllProperties(obj){ for(var attr in obj){ console.log(attr+':'+obj[attr]); } } var descriptor= Object.getOwnPropertyDescriptor(book,'_year');//数据属性 var descriptor2= Object.getOwnPropertyDescriptor(book,'year');//访问器属性 showAllProperties(descriptor); console.log('============================'); showAllProperties(descriptor2);
以上關於初步了解javascript物件導向的全部內容就介紹到這裡,以下將給大家介紹深入淺析js物件導向之詳解常見建立物件的幾種方式,有興趣的朋友繼續關注哦。