好家伙,本篇為《JS高級程式設計》第八章“物件、類與面向物件編程”學習筆記
1.關于物件
ECMA-262將物件定義為一組屬性的無序集合,嚴格來說,這意味著物件就是一組沒有特定順序的值,
物件的每個屬性或方法都由一個名稱來標識,這個名稱映射到一個值,正因為如此(以及其他還未討論的原因),可以把
ECMAScript的物件想象成一張散串列,其中的內容就是一組名/值對,值可以是資料或者函式,
簡單使用一下
let object =new Object();
object.name ="panghu";
object.age ="20";
object.job ="student";
object.getName = function(){
console.log(this.name)
};
看圖:

也可以這樣寫,在這種字面量中,等號變為了冒號,分號變為了逗號
(顯然第二種更美觀,直接)
let object = {
name: "panghu",
age: "20",
job: "student",
getName() {
console.log(this.name)
}
}
object.getName();
看圖:

2.屬性型別
ECMA-262使用一些內部特性來描述屬性的特征,這些特性是由為JavaScript實作引擎的規范定義的,
因此,開發者不能在JavaScript中直接訪問這些特性,
為了將某個特性標識為內部特性,規范會用兩個中括號把特性的名稱括起來,比如[[Enumerable]],
屬性分兩種,資料屬性和訪問器屬性,
2.1.1.資料屬性
資料屬性包含一個保存資料值的位置,值會從這個位置讀取,也會寫入到這個位置,
資料屬性有4個特性描述它們的行為,
(是否可以修改"資料屬性",是否可遍歷,值是否可修改,值 就是這個四個)
□[[Configurable]]:表示屬性是否可以通過delete 洗掉并重新定義,是否可以修改它的特性,以及是否可以把它改為訪問器屬性,
默認情況下,所有直接定義在物件上的屬性的這個特性都是true,如前面的例子所示,
□[[Enumerable]]:表示屬性是否可以通過for-in回圈回傳,
默認情況下,所有直接定義在物件上的屬性的這個特性都是true,如前面的例子所示,
□[[writable]]:表示屬性的值是否可以被修改,
默認情況下,所有直接定義在物件上的屬性的這個特性都是true,如前面的例子所示,
□[[Value]]:包含屬性實際的值,這就是前面提到的那個讀取和寫入屬性值的位置,
這個特性的默認值為undefined,
2.1.2.object.defineProperty()方法
使用object.defineProperty()方法修改屬性的默認特性
這個方法接收3個引數:要給其添加屬性的物件、屬性的名稱和一個描述符物件,
示例:
let person ={};
Object.defineProperty(person,"name",{
configurable:false,
value:"panghu"
})
console.log(person.name);
Object.defineProperty(person,"name",{
configurable:false,
value:"xiaofu"
})
console.log(person.name);
此處,將configurable屬性改為false后,不可再修改資料屬性,
(writable屬性同理,writable改為false后,不可再修改"值"的屬性)

(過河拆橋了屬于是)
2.2.訪問器屬性
訪問器屬性不包含資料值,(就像它的名字一樣,他是用來訪問的)
相反,它們包含一個獲取(getter)函式和一個設定(setter)函式,不過這兩個函式不是必需的,
在讀取訪問器屬性時,會呼叫獲取函式,這個函式的責任就是回傳一個有效的值,
在寫入訪問器屬性時,會呼叫設定函式并傳入新值,這個函式必須決定對資料做出什么修改,訪問器屬性有4個特性描述它們的行為,
(聯系著上面那個一起記就好了)
□[[configurable]]:表示屬性是否可以通過delete 洗掉并重新定義,是否可以修改它的特性,以及是否可以把它改為資料屬性,
默認情況下,所有直接定義在物件上的屬性的這個特性都是true,
□[[Enumerable]]:表示屬性是否可以通過for-in回圈回傳,
默認情況下,所有直接定義在物件上的屬性的這個特性都是true,
□[[Get]]:獲取函式,在讀取屬性時呼叫,默認值為undefined,
□[[set]]:設定函式,在寫入屬性時呼叫,默認值為undefined,
訪問器屬性是不能直接定義的,必須使用Object.defineProperty(),
書本中的原例:
let book = {
year_: 2017,
edition: 1
}
Object.defineProperty(book, "year", {
get() {
return this.year_;
},
set(newValue) {
if (newValue > 2017) {
//此時this指向book
this.year_ = newValue;
this.edition += newValue - 2017;
}
}
});
book.year = 2018;
console.log(book.edition);

這是訪問器屬性的典型使用場景,即設定一個屬性值會導致一些其他變化發生,
3.定義多個屬性
我們使用Object.defineProperty()去修改某個物件的屬性(資料屬性或訪問器屬性),
那么,按照JS一貫的尿性,定義多個屬性大概使用"它的復數"方法 (這個改復數我會,去y加ies)
Object.defineProperties()方法:
let person = {};
Object.defineProperties(person, {
name_: {
value: "panghu"
},
age: {
value: "20"
},
name: {
getName() {
return this.name_;
},
}
})
console.log(person);

4.讀取屬性的特性
使用 Object.getOwnPropertyDescriptor()方法可以取得指定屬性的屬性描述符,
這個方法接收兩個引數::屬性所在的物件和要取得其描述符的屬性名,
回傳值是一個物件,對于訪問器屬性包含configurable、enumerable、get和 set屬性,
對于資料屬性包含 configurable,enumerable.writable和value屬性,
(這個變復數我會,直接加s)
ECMAScript 2017 新增了 Object.getOwnPropertyDescriptors()靜態方法,
這個方法實際上會在每個自有屬性上呼叫object.getOwnPropertyDescriptor()并在一個新物件中回傳它們,
兩個方法放同一個例子了:
let person = {};
Object.defineProperties(person, {
name_: {
value: "panghu"
},
age: {
value: "20"
},
name: {
get:function() {
return this.name_;
},
set:function(name){
this.name=name;
}
}
})
let descriptor_1 = Object.getOwnPropertyDescriptor(person,"name");
let descriptor_2 = Object.getOwnPropertyDescriptors(person);
console.log(descriptor_1);
console.log(descriptor_2);

5.合并物件
JavaScript 開發者經常覺得“合并”(merge)兩個物件很有用,
更具體地說,就是把源物件所有的本地屬性一起復制到目標物件上,
有時候這種操作也被稱為“混人”(mixin),因為目標物件通過混入源物件的屬性得到了增強,
ECMAScript6專門為合并物件提供了object.assign()方法,
這個方法接收一個目標物件和一個或多個源物件作為引數,
然后將每個源物件中可列舉(object.propertyIsEnumerable()回傳 true)和自有(Object.hasownProperty()回傳true)屬性復制到目標物件,
以字串和符號為鍵的屬性會被復制,
對每個符合條件的屬性,這個方法會使用源物件上的[[Get]]取得屬性的值,然后使用目標物件上的[[Set]]設定屬性的值,
let book, person ,result;
book ={};
person ={ id:'999'};
result = Object.assign(book,person);
console.log(result);
console.log(book);

6.增強的物件語法
6.1.屬性值的簡寫
兩者等價
let name = "panghu";
let person ={
name:name
};
console.log(person);
簡寫:
let name = "panghu";
let person ={
name:name
};
console.log(person);

6.2.可計算屬性
在引入可計算屬性之前,如果想使用變數的值作為屬性,
那么必須先宣告物件,然后使用中括號語法來添加屬性,
換句話說,不能在物件字面量中直接動態命名屬性,
有了可計算屬性,就可以在物件字面量中完成動態屬性賦值,
中括號包圍的物件屬性鍵告訴運行時將其作為JavaScript運算式而不是字串來求值
示例如下:
const name_key ="panghu";
let person ={
[name_key]: "xiaofu",
}
console.log(person);

6.3.簡寫方法名
let person ={
name:"panghu",
getName: function(){
return this.name
}
}
person.getName();
let person ={
name:"panghu",
getName(){
return this.name
}
}
person.getName();

7.物件解構
ECMAScript6新增了物件解構語法,可以在一條陳述句中使用嵌套資料實作一個或多個賦值操作,
簡單地說,物件解構就是使用與物件匹配的結構來實作物件屬性賦值,
(簡單的說,就是拆開來用)
let person = {
name: "panghu",
age: "20",
};
let {
name: personName,
age: personAge
} = person;
console.log(personName);
console.log(personAge);
//簡寫版本
let {
name,
age
} = person;
console.log(name);
console.log(age);

注意:undefined和null不能被解構
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/540410.html
標籤:其他
