目錄
- 1. 概述
- 2. Reflect對象靜態方法
- 2.1 Reflect.get()
- 2.2 Reflect.set()
- 2.3 Reflect.has()
- 2.4 Reflect.deleteProperty()
- 2.5 Reflect.construct()
- 2.6 Reflect.getPrototypeOf()
- 2.7 Reflect.setPrototypeOf()
- 2.8 Reflect.apply()
- 2.9 Reflect.defineProperty()
- 2.10 Reflect.getOwnPropertyDescriptor()
- 2.11 Reflect.isExtensible ()
- 2.12 Reflect.preventExtensions()
- 2.13 Reflect.ownKeys ()
- 3 參考鏈接
1. 概述
Reflect
對象與Proxy
對象一樣,也是 ES6 爲了操作對象而提供的新 API。
Reflect
不是一個函數對象,它是不可構造的,而且Reflect
的所有屬性和方法都是靜態的。
Reflect
對象的設計目的有這樣幾個:
- 將
Object
對象的一些明顯屬於語言內部的方法,放到Reflect
對象上 - 修改某些
Object
方法的返回結果,讓其變得更合理 - 讓
Object
操作都變成函數行爲 Reflect
對象的方法與Proxy
對象的方法一一對應,只要是Proxy
對象的方法,就能在Reflect
對象上找到對應的方法。能夠讓Proxy
對象調用對應的Reflect
方法,完成默認行爲,作爲修改行爲的基礎。
var person = {
name: "jidi"
}
var proxy = new Proxy(person, {
set(target, property, value, receiver) {
return Reflect.set(target, property, value, receiver);
}
})
person; // {name: "jidi"}
proxy.name = 1;
person; // {name: 1}
上面代碼中,代理攔截對person
對象屬性的寫入行爲,使用Reflect.set
方法確保能夠正常寫入屬性。
2. Reflect對象靜態方法
Reflect
對象一共有 13 個靜態方法,它們都是跟Proxy
對象攔截操作是一一對應的。
Reflect.apply(target, thisArg, argumentsList)
Reflect.construct(target, argumentsList)
Reflect.get(target, property, receiver)
Reflect.set(target, property, value, receiver)
Reflect.defineProperty(target, property, descriptor)
Reflect.deleteProperty(target, property)
Reflect.has(target, property)
Reflect.ownKeys(target)
Reflect.isExtensible(target)
Reflect.preventExtensions(target)
Reflect.getOwnPropertyDescriptor(target, property)
Reflect.getPrototypeOf(target)
Reflect.setPrototypeOf(target, prototype)
2.1 Reflect.get()
Reflect.get
方法可以從一個對象中取屬性值。就如同屬性訪問器,但卻是通過函數調用來實現。
語法
Reflect.get(target, property[, receiver])
參數
以下是傳遞給get
方法的參數:
- target:目標對象
- property:屬性名
- receiver:如果
target
對象中指定了getter
,receiver
則爲getter
調用時的this
值
返回值
返回目標對象對應屬性的值。如果該屬性不存在,返回undefined
。
約束
如果目標值(target
)類型不是Object
,拋出一個 TypeError
。
示例一
var person = {
name: "jidi",
age: 22
}
Reflect.get(person, "name"); // "jidi"
Reflect.get(person, "sex"); // undefined
示例二
var perosn = {
name: "jidi",
age: 22,
get info() { // 定義getter
return this.name + this.age;
}
}
var receiver = {
name: "基地",
age: 23
}
Reflect.get(person, "info", receiver); // "基地23"
上面代碼演示了第三個參數receiver
的使用。
示例三
Reflect.get(true, 'toString'); // Uncaught TypeError: Reflect.get called on non-object at Object.get
上面代碼演示了違反約束的情況。
2.2 Reflect.set()
Reflect.set
方法允許給對象屬性賦值並且是以函數的方式。
語法
Reflect.set(target, property, value[, receiver]);
參數
以下是傳遞給set
方法的參數:
- target:設置屬性的目標對象
- property:設置的屬性的名稱
- value:設置的值
- receiver:如果遇到
setter
,receiver
則爲setter
調用時的this
值。
返回值
返回一個布爾值,表示屬性是否設置成功。
約束
如果target
不是一個對象,會報錯TypeError
。
示例一
var person = {};
Reflect.set(person, "name", "jidi");
person.name; // "jidi"
示例二
var person = {
name: "jidi",
age: 22,
set info(value) {
console.info(this === receiver)
this.name = value;
}
};
var receiver = {
name: "基地"
}
Reflect.set(person, "info", "jidi", receiver); // true
receiver.name; // "jidi"
上面代碼,person
對象設置了setter
,當調用setter
時,setter
內部this
會指向receiver
。
示例三
Reflect.set(1, 'name', {}) // Uncaught TypeError: Reflect.set called on non-object at Object.set
上面代碼演示了違反約束的情況。
2.3 Reflect.has()
Reflect.has
用於檢查一個對象是否擁有某個屬性, 相當於in
操作符 ,但是是以函數的形式。
語法
Reflect.has(target, property);
參數
以下是傳遞給has
方法的參數:
- target:目標對象
- property:屬性名
返回值
返回一個布爾值,表示對象是否擁有某個屬性。
約束
如果目標對象並非Object
類型,拋出TypeError
。
示例
var person = {
name: "jidi"
}
Reflect.has(person, "name"); // true
Reflect.has(person, "age"); // false
2.4 Reflect.deleteProperty()
Reflect.deleteProperty
用於刪除對象屬性,相當於delete obj[property]
。
語法
Reflect.deleteProperty(target, property);
參數
以下是傳遞給deleteProperty
方法的參數:
- target:目標對象
- property:屬性名
返回值
返回一個布爾值,表示對象屬性是否被刪除。
約束
如果目標對象並非Object
類型,拋出TypeError
。
示例
var person = {
name: "jidi",
age: 22
}
Reflect.deleteProperty(person, 'name'); // true
person; // {age: 22}
// 如果屬性不存在,返回 true
Reflect.deleteProperty({}, "name"); // true
2.5 Reflect.construct()
Reflect.construct
方法等同於new target(...args)
,這提供了一種不使用new
,來調用構造函數的方法。
語法
Reflect.construct(target, argumentsList[, newTarget]);
參數
以下是傳遞給construct
方法的參數:
- target:被運行的目標構造函數
- argumentsList:目標構造函數調用時的參數
- newTarget :新創建對象的原型對象, 默認值爲
target
返回值
返回一個實例對象。
約束
如果target
或者newTarget
不是構造函數,拋出TypeError
異常。
示例
// 定義構造函數
function Person(name, sex, age) {
if(!new.target) {
return new Person(name, sex, age);
}
this.name = name;
this.sex = sex;
this.age = age
}
// 使用new命令寫法
var p1 = new Person("jidi", "男", 22);
p1; // Person {name: "jidi", sex: "男", age: 22}
// 使用Reflect.construct()靜態方法
var p2 = Reflect.construct(Person, ["基地", "男", 23]);
p2; // Person {name: "jidi", sex: "男", age: 22}
2.6 Reflect.getPrototypeOf()
Reflect.getPrototypeOf
返回指定對象的原型 (即內部的 [[Prototype
]] 屬性的值) 。
語法
Reflect.getPrototypeOf(target);
參數
以下是傳遞給getPrototypeOf
方法的參數:
- target:目標對象
返回值
給定對象的原型。如果給定對象沒有繼承的屬性,則返回 null
。
約束
如果 target
不是 Object
,拋出一個 TypeError
異常。
演示
var person = { // 普通對象
name:"jidi"
}
var proto = { // 原型對象
sleep() {
console.info("sleeping....")
}
}
// 設置原型對象
Object.setPrototypeOf(person,proto);
Reflect.getPrototypeOf(person) === proto; // true
2.7 Reflect.setPrototypeOf()
Reflect.setPrototypeOf
方法改變指定對象的原型。
語法
Reflect.setPrototypeOf(target, prototype);
參數
以下是傳遞給setPrototypeOf
方法的參數:
- target:設置原型的目標對象
- prototype:對象的新原型(一個對象或
null
)
返回值
返回一個 Boolean
值表明原型是否已經成功設置。
約束
如果target
不是Object
,或 prototype
既不是對象也不是 null
,拋出一個 TypeError
異常。
示例
var person = {};
// 設置原型,成功返回true
Reflect.setPrototypeOf(person , Array.prototype); // true
person.length; // 0
// target不能爲null或undefined
Object.setPrototypeOf(null, {}); // Uncaught TypeError: Object.setPrototypeOf called on null or undefined at Function.setPrototypeOf
2.8 Reflect.apply()
靜態方法 Reflect.apply()
通過指定的參數列表發起對目標(target
)函數的調用。
語法
Reflect.apply(target, thisArgument, argumentsList);
參數
以下是傳遞給apply
方法的參數:
- target:目標函數
- thisArgument:target函數調用時綁定的this對象。
- argumentsList:target函數調用時傳入的實參列表,該參數應該是一個類數組的對象。
返回值
返回值是調用完帶着指定參數和this
值的給定的函數後返回的結果。
約束
如果 target
對象不可調用,拋出 TypeError
。
示例
// 舊寫法
Function.prototype.apply.call(Math.floor, Math, [1.23]); // 1
// 或者
Math.floor.apply(Math, [1.23]); // 1
// 新寫法
Reflect.apply(Math.floor, Math, [1.23]); // 1
2.9 Reflect.defineProperty()
靜態方法 Reflect.defineProperty()
基本等同於 Object.defineProperty()
方法,唯一不同是返回 Boolean
值。
語法
Reflect.defineProperty(target, property, attributes)
參數
以下是傳遞給defineProperty
方法的參數:
- target:目標對象
- property:要定義或修改的屬性的名稱
- attributes:要定義或修改的屬性的描述
返回值
返回Boolean
值,表示屬性是否被成功定義。
約束
如果target
不是 Object
,拋出一個 TypeError
。
示例
var person = {};
// 設置對象屬性
Reflect.defineProperty(person, "name", {
value: "jidi",
enumerable: true
})
person; // {name: "jidi"}
Object.getOwnPropertyDescriptor(person, "name"); // {value: "jidi", writable: false, enumerable: true, configurable: false}
2.10 Reflect.getOwnPropertyDescriptor()
Reflect.getOwnPropertyDescriptor
基本等同於Object.getOwnPropertyDescriptor
,用於得到指定屬性的描述對象。
語法
Reflect.getOwnPropertyDescriptor(target, property);
參數
- target:需要尋找屬性的目標對象
- property:獲取自己的屬性描述符的屬性的名稱。
返回值
如果屬性存在於給定的目標對象中,則返回屬性描述對象;否則,返回 undefined
。
約束
如果目標對象不是 Object
,拋出一個 TypeError
。
示例
var person = {
name: "jidi"
}
Reflect.getOwnPropertyDescriptor(person, "name"); // {value: "jidi", writable: false, enumerable: true, configurable: false}
2.11 Reflect.isExtensible ()
Reflect.isExtensible
方法對應Object.isExtensible
,返回一個布爾值,表示當前對象是否可擴展。
語法
Reflect.isExtensible(target);
參數
- target:檢查是否可擴展的目標對象。
返回值
返回一個Boolean
值表明該對象是否可擴展。
約束
如果目標對象不是 Object
,拋出一個 TypeError
。
示例
var p= {};
Reflect.isExtensible(p); // true
Reflect.preventExtensions(p);
Reflect.isExtensible(p); // false
2.12 Reflect.preventExtensions()
Reflect.preventExtensions
對應Object.preventExtensions
方法,用於讓一個對象變爲不可擴展。它返回一個布爾值,表示是否操作成功。
語法
Reflect.preventExtensions(target);
參數
- target:阻止擴展的目標對象。
返回值
返回一個Boolean
值表明目標對象是否成功被設置爲不可擴展。
約束
如果目標對象不是 Object
,拋出一個 TypeError
。
示例
var p= {};
Reflect.isExtensible(p); // true
Reflect.preventExtensions(p);
Reflect.isExtensible(p); // false
2.13 Reflect.ownKeys ()
Reflect.ownKeys
方法用於返回一個由目標對象自身的屬性組成的數組。
語法
Reflect.ownKeys(target);
參數
- target:獲取自身屬性的目標對象。
返回值
由目標對象的自身屬性組成的數組。
約束
如果目標對象不是 Object
,拋出一個 TypeError
。
示例
var person= {
name: "jidi",
age: 22,
[Symbol.for('x')]: 3,
[Symbol.for('y')]: 4,
};
Reflect.ownKeys(person); // ["name", "age", Symbol(x), Symbol(y)]
3 參考鏈接
本篇博文是我自己學習筆記,原文請參考:ECMAScript 6 入門,MDN網站。
如有問題,請及時指出!
歡迎溝通交流,郵箱:[email protected]。