欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

深入理解 ES6中的 Reflect用法

 更新時(shí)間:2020年07月18日 15:52:06   作者:龍恩0707  
這篇文章主要介紹了深入理解 ES6中的 Reflect用法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧

Reflect對象是一個(gè)全局的普通的對象。Reflect的原型就是Object.

我們首先來驗(yàn)證下 看看Reflect的原型是否是Object, 基本代碼如下:

let obj = {};
console.log(Reflect.__proto__ === Object.prototype); // true
console.log(obj.__proto__ === Reflect.__proto__); // true

let str = '111';

console.log(str.__proto__); // String {"", length: 0, constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ, …}

Reflect是ES6為了操作對象而新增的API, 為什么要添加Reflect對象呢?它這樣設(shè)計(jì)的目的是為了什么?

1)將Object對象的一些明顯屬于語言內(nèi)部的方法(比如Object.defineProperty),放到Reflect對象上,那么以后我們就可以從Reflect對象上可以拿到語言內(nèi)部的方法。

2)在使用對象的 Object.defineProperty(obj, name, {})時(shí),如果出現(xiàn)異常的話,會拋出一個(gè)錯(cuò)誤,需要使用try catch去捕獲,但是使用 Reflect.defineProperty(obj, name, desc) 則會返回false。

比如 舊的寫法如下:

try {
 Object.defineProperty(target, property, attributes);
} catch(e) {
 // 失敗
}

// 新寫法
if (Reflect.defineProperty(target, property, attributes)) {
 // success
} else {
 // failure
}

等等這些考慮,所以就新增了這個(gè)靜態(tài)對象。

Reflect對象一共有13個(gè)靜態(tài)方法。

一:Reflect.get(target, name, receiver)

該方法是用來讀取一個(gè)對象的屬性。

參數(shù)如下解析:

target: 目標(biāo)對象

name: 是我們要讀取的屬性。

receiver(可選): 可以理解為上下文this對象。

先看如下demo來理解下 Reflect中的get方法的使用如下:

const obj = {
 name: 'kongzhi',
 age: 30,
 get xxx() {
 console.log(this.name); 
 console.log('-------');
 }
};

console.log(Reflect.get(obj, 'name')); // kongzhi
console.log(Reflect.get(obj, 'yyy')); // undefined

/* 
 先執(zhí)行 xxx 方法 打印 kongzhi 和 ----, 
 然后在打印undefined, 因?yàn)樵搙xx()函數(shù)沒有返回值
*/
console.log(Reflect.get(obj, 'xxx')); 

/* 
 會執(zhí)行 xxx() 方法,打印 happy, 因此第三個(gè)參數(shù)指向上下文
 就指向了這個(gè)對象,然后打印 ----- ,最后打印undefined
 因?yàn)樵摵瘮?shù)沒有返回值
*/
console.log(Reflect.get(obj, 'xxx', {name: 'happy'})); 

/*
 會執(zhí)行 xxx() 方法,打印 undefined, 因此第三個(gè)參數(shù)指向上下文
 就指向了這個(gè)對象,而這個(gè)對象里面又沒有name屬性,因此會打印undefined
 然后打印 ----- ,最后打印undefined. 因?yàn)樵摵瘮?shù)沒有返回值
*/
console.log(Reflect.get(obj, 'xxx', {age: 'happy'}));

const obj2 = {
 name: 'kongzhi2',
 age: 30,
 get xxx() {
 console.log(this.name); 
 console.log('----xxxx---');
 return 0;
 }
};
/*
 先執(zhí)行 obj2 該對象中的 xxx 方法,指定了第三個(gè)參數(shù)作為該上下文對象,
 因此會打印 happy2, 然后繼續(xù)打印 ----xxxx---, 最后我們可以看到
 有返回值為0,因此打印0了 
*/
console.log(Reflect.get(obj2, 'xxx', {name: 'happy2'})); 

二:Reflect.set(target,name,value,receiver)

上面的get方法是獲取對象中的值,那么set就是設(shè)置該對象的屬性值了,參數(shù)解析簡單如下:

target: 我們需要操作的對象。

name: 我們需要設(shè)置該對象的屬性名。

value: 我們要設(shè)置的屬性值。

receiver: 可以理解為上下文this對象。如果我們在設(shè)置值的時(shí)候遇到setter函數(shù),該參數(shù)就指向與setter中上下文this對象。

該函數(shù)會返回一個(gè)Boolean的值,代表在目標(biāo)對象上設(shè)置屬性是否成功。

如下代碼演示:

const obj = {
 age: 30,
 set name(name) {
 console.log(this); 
 console.log('-------');
 }
};

const res = Reflect.set(obj, 'age', 31);
console.log(res); // true
console.log(obj); // {age: 31, set name:function} 這樣的
console.log(obj.age); // 打印 31

/*
 如下代碼,設(shè)置 obj對象中的name屬性,因此打印 console.log(this)
 返回 {age: 31, set name:function} 這樣的, console.log(res2)返回true,設(shè)置成功
*/
const res2 = Reflect.set(obj, 'name', 'xxxx');
console.log(res2); // true

/*
 先執(zhí)行 set 中的name方法,打印 console.log(this);this就指向了第四個(gè)參數(shù) {test: 'test'}
 然后會打印 '-----'; 
*/
const r2 = Reflect.set(obj, 'name', 'dreamapple', {test: 'test'}); // this: --> { test: 'test' }
console.log(r2); // true
console.log(obj); // { name: [Setter], age: 31 }

三:Reflect.apply(target,thisArg,args)

該方法的含義是:通過指定的參數(shù)列表對該目標(biāo)函數(shù)的調(diào)用。該方法類似于我們之前的 Function.prototype.apply 方法的。

參數(shù)解析如下:

target: 我們的目標(biāo)函數(shù).

thisArg: target函數(shù)調(diào)用的時(shí)候綁定的this對象。

args: 就是函數(shù)參數(shù)列表。

如下代碼demo演示:

// 查找數(shù)組里面最小的元素值

const arrs = [1, 2, 3, 4];
// ES6 的語法如下
const min = Reflect.apply(Math.min, arrs, arrs);

console.log(min); // 1

// ES5的語法如下:

const min2 = Math.min.apply(arrs, arrs);
console.log(min2); // 1

// 或者我們使用 Finction.prototype 代碼如下演示

const min3 = Function.prototype.apply.call(Math.min, arrs, arrs);
console.log(min3); // 1

// 下面是截取字符串的方法演示下 

const strs = 'kongzhi';

// 使用ES6的語法 代碼演示如下:

const str1 = Reflect.apply(String.prototype.slice, strs, [0, 3]);
console.log(str1); // 打印 kon

// 使用 ES5的語法 
const str2 = strs.slice(0, 3);
console.log(str2); // 打印 kon

// 或者我們使用 String.prototype 代碼如下演示
const str3 = String.prototype.slice.apply(strs, [0, 3]);
console.log(str3); // kon

四:Reflect.construct(target,args[, newTarget])

該方法的作用和 new AAA() 創(chuàng)建一個(gè)實(shí)列方法作用類似,那么使用該方法,我們就可以提供一種不使用new來調(diào)用構(gòu)造函數(shù)的方法,

參數(shù)含義如下:

target: 被運(yùn)行的目標(biāo)函數(shù)。

args: 調(diào)用構(gòu)造函數(shù)傳遞的參數(shù)數(shù)組或偽數(shù)組。

newTarget: 也是構(gòu)造函數(shù),表示使用 Reflect.construct后生成的實(shí)列對象是誰的實(shí)列。如果沒有該參數(shù),默認(rèn)生成的實(shí)列對象就和target構(gòu)造函數(shù)是一樣的。

代碼演示如下:

function XXXX(name) {
 this.name = name;
}

XXXX.prototype.getName = function() {
 return this.name;
}

function YYYY(age) {
 this.age = age;
}

YYYY.prototype.getAge = function() {
 return this.age || 31;
}

// 使用 XXXX函數(shù)作為構(gòu)造函數(shù), 那么構(gòu)造函數(shù)就指向了 XXXX函數(shù)
const xxxx = Reflect.construct(XXXX, ['xx']);
console.log(xxxx); // 打印 XXXX {name: xx}
console.log(xxxx.getName()); // 打印 xx

如下圖所示:

// 使用 YYYY 函數(shù)作為構(gòu)造函數(shù),那么構(gòu)造函數(shù)就指向了 YYYY函數(shù)
const yyyy = Reflect.construct(XXXX, ['30'], YYYY);

console.log(yyyy); // 打印 YYYY {name: 30}
console.log(yyyy.name); // 30
console.log(yyyy.age); // undefined
console.log(yyyy instanceof YYYY); // true
console.log(yyyy instanceof XXXX); // false
console.log(yyyy.getAge()); // 31

如上demo所示:當(dāng)const xxxx = Reflect.construct(XXXX, ['xx']); 沒有第三個(gè)參數(shù)的時(shí)候,那么構(gòu)造函數(shù)指向了 XXXX 函數(shù)。

我們繼續(xù)看第二個(gè)demo,const yyyy = Reflect.construct(XXXX, ['30'], YYYY); 有第三個(gè)參數(shù),因此 yyyy的實(shí)列指向了 YYYY.

如上代碼打印的信息看到 console.log(yyyy instanceof YYYY); 返回true, console.log(yyyy instanceof XXXX); 返回false.

但是呢 console.log(yyyy.getAge()); 返回的是 31. 如果我們沒有默認(rèn)的 31值的話,那么就應(yīng)該返回undefined了,可以看到,請看下面的注意總結(jié):

注意:如果有第三個(gè)參數(shù)的話,那么我們的實(shí)列由兩部分組成,實(shí)列的屬性部分由第一部分構(gòu)造函數(shù)生成。實(shí)列的方法由第三個(gè)參數(shù)對象生成。

比如上面打印的 console.log(yyyy); // 打印 YYYY {name: 30} 看到只返回了 XXXX中的name屬性,XXXX中的getName方法并沒有拿到。

同理如上 console.log(yyyy.age); 為undefined, console.log(yyyy.getAge()); 返回了31. 如下圖所示:

五:Reflect.defineProperty(target,name,desc)

該方法與Object.defineProperty方法類似的,不過唯一的區(qū)別是 Reflect.defineProperty返回值是一個(gè)Boolean的值。

比如如下基本的代碼比較:

const obj = {};
// 使用 Object.defineProperty
try {
 Object.defineProperty(obj, 'a', {
 value: 22
 })
} catch(e) {
 console.log('define property failed');
}

// 使用 Reflect.defineProperty

const res = Reflect.defineProperty(obj, 'b', {
 configurable: true,
 enumerable: true
});

console.log(res); // true

既然兩者的用法是一樣的,那配置項(xiàng)也是一樣的,那這邊就不多介紹了,只是返回值不一樣而已,那么Object.defineProperty 的具體用法,

請看我上一篇文章(http://www.dbjr.com.cn/article/191097.htm)。

因此總結(jié)一下:如果使用Object.defineProperty的屬性定義失敗了,就會拋出一個(gè)錯(cuò)誤,成功的話就會返回這個(gè)對象;

Reflect.defineProperty如果定義屬性失敗的話就會返回false,如果成功定義的話,就會返回true。

但是如果使用Reflect.defineProperty函數(shù),它的第一個(gè)參數(shù)不是對象的話,也會拋出錯(cuò)誤。

六:Reflect.deleteProperty(target,name)

該方法用于刪除一個(gè)對象上的屬性,它和delete操作符類似的。

參數(shù)如下:

target: 表示要操作的對象。

name: 表示要?jiǎng)h除該對象上的屬性。

該函數(shù)返回值是一個(gè)Boolean的值,如果成功的話,返回true,失敗的話返回false。比如如下demo演示:

const obj = {
 name: 'kongzhi',
 age: 30
};

let test1 = Reflect.deleteProperty(obj, 'name');
console.log(test1); // true
console.log(obj); // {age: 30}

// 如果刪除對象上不存在的屬性的話,也是返回true的
let test2 = Reflect.deleteProperty(obj, 'xx');
console.log(test2); // true
console.log(obj); // {age: 30}

let test3 = Reflect.deleteProperty(obj, 'age');
console.log(test3); // true
console.log(obj); // {}

七:Reflect.has(target,name)

該方法的含義是:檢查一個(gè)對象上是否含有特定的屬性。相當(dāng)于es5中的in操作符。

那么參數(shù) target: 就是改對象哦,name的含義是:該對象上的屬性。

具體的demo演示如下:

// 一般的對象
const obj = {
 name: 'kongzhi',
 age: 30
};

console.log(Reflect.has(obj, 'name')); // true
console.log(Reflect.has(obj, 'username')); // 該對象上沒有 username屬性 返回false
console.log(Reflect.has(obj, 'age')); // true

// 函數(shù)的實(shí)列

function Obj(name) {
 this.name = name;
}
Obj.prototype.getName = function() {
 return this.name;
}
const test = new Obj();

// 使用in操作符測試
console.log('name' in test); // true
console.log('getName' in test); // true

// 使用Reflect.has 測試
console.log(Reflect.has(test, 'name')); // true
console.log(Reflect.has(test, 'getName')); // true

八:Reflect.ownKeys(target)

該函數(shù)的作用是:返回由目標(biāo)對象自身的屬性鍵組成的數(shù)組。如果這個(gè)目標(biāo)對象不是一個(gè)對象的話,那么該函數(shù)就會拋出一個(gè)異常。 target參數(shù):它是一個(gè)對象。如下代碼演示:

const obj = {
 name: 'kongzhi',
 age: 30
};
console.log(Reflect.ownKeys(obj)); // ['name', 'age'];

九:Reflect.preventExtensions(target)

該方法的作用是 阻止新的屬性添加到對象中去。target參數(shù)必須是一個(gè)對象,否則的話會拋出一個(gè)異常。

如下代碼演示:

const obj = {};
// 判斷該對象是否可以擴(kuò)展,使用 Reflect.isExtensible 該方法
const t1 = Reflect.isExtensible(obj);
console.log(t1); // true

// 使用 Reflect.preventExtensions 來阻止該對象擴(kuò)展

Reflect.preventExtensions(obj);

// 再來擴(kuò)展下該對象,看是否可以
const t2 = Reflect.isExtensible(obj);
console.log(t2); // false

十:Reflect.isExtensible(target)

該方法的作用是檢查一個(gè)對象是否可以擴(kuò)展的,也就是說對象里面是否可以添加新的屬性或方法。

target參數(shù)表示目標(biāo)對象。如果該目標(biāo)對象不是一個(gè)對象的話,那么函數(shù)會拋出一個(gè)異常。

該函數(shù)會返回一個(gè)Boolean值,如果為true的話,說明該對象可以擴(kuò)展,否則的話返回false,表示該對象不可以擴(kuò)展。

如下demo來演示下:

const obj = {};
// 判斷該對象是否可以擴(kuò)展,使用 Reflect.isExtensible 該方法
const t1 = Reflect.isExtensible(obj);
console.log(t1); // true

// 使用 Reflect.preventExtensions 來阻止該對象擴(kuò)展
Reflect.preventExtensions(obj);

// 再來擴(kuò)展下該對象,看是否可以
const t2 = Reflect.isExtensible(obj);
console.log(t2); // false

十一:Reflect.getOwnPropertyDescriptor(target, name)

該方法的參數(shù)如下解析:

target: 表示的是目標(biāo)對象。

name: 表示目標(biāo)對象的屬性

該方法的具體含義是:如果目標(biāo)對象中的屬性描述符存在的話,就返回這個(gè)屬性描述符,如果不存在,就返回undefined。

如下demo演示:

const obj = {};

Reflect.defineProperty(obj, 'name', {
 configurable: true,
 enumerable: true,
 writable: true,
 value: '30'
});

const test1 = Reflect.getOwnPropertyDescriptor(obj, 'name');
/*
 打印值如下:
 {
 configurable: true
 enumerable: true
 value: "30"
 writable: true
 }
*/
console.log(test1);

const test2 = Reflect.getOwnPropertyDescriptor(obj, 'age');
console.log(test2); // undefined

// 如果第一個(gè)參數(shù)不是對象
const test3 = Object.getOwnPropertyDescriptor('kkkk', 'name');
console.log(test3); // undefined

// 使用 try catch 包圍,會執(zhí)行 catch方法內(nèi)部代碼
try {
 const test4 = Reflect.getOwnPropertyDescriptor('kkkk', 'name');
 console.log(test4);
} catch (e) {
 console.log('error');
} 

十二:Reflect.getPrototypeOf(target)

該方法是返回一個(gè)對象的原型的,也就是說內(nèi)部的 [[Prototype]] 屬性的值。來看如下代碼:

function testA() {};
testA.prototype.xxx = function() {};
const a = new testA();
console.log(Object.getPrototypeOf(a));

打印 如下圖所示:

十三:Reflect.setPrototypeOf(target, prototype)

該方法的作用是設(shè)置一個(gè)對象的原型。如果設(shè)置成功的話,這個(gè)對象就返回一個(gè)true,如果設(shè)置失敗的話,這個(gè)對象就返回一個(gè)false。

比如如下代碼:

const obj = {};
const test1 = Reflect.setPrototypeOf(obj, Object.prototype);
console.log(test1); // true

let test2 = Reflect.setPrototypeOf(Object.freeze({}), null);
console.log(test2); // false

以上這篇深入理解 ES6中的 Reflect用法就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • js對象的復(fù)制繼承實(shí)例

    js對象的復(fù)制繼承實(shí)例

    這篇文章主要介紹了js對象的復(fù)制繼承用法,以一個(gè)較為簡單的實(shí)例分析了js對象復(fù)制繼承的使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-01-01
  • 沒有document.getElementByName方法

    沒有document.getElementByName方法

    document.getElementByName方法沒有document.getElementsByName得到的是標(biāo)簽的數(shù)組,下面為大家詳細(xì)介紹下具體的使用,感興趣的朋友可以參考下,希望對大家有所幫助
    2013-08-08
  • JS定義函數(shù)的幾種常用方法小結(jié)

    JS定義函數(shù)的幾種常用方法小結(jié)

    這篇文章主要介紹了JS定義函數(shù)的幾種常用方法,結(jié)合實(shí)例形式總結(jié)分析了javascript函數(shù)表達(dá)式、Lambda 表達(dá)式、對象方法等常見函數(shù)定義操作技巧,需要的朋友可以參考下
    2019-05-05
  • js讀取被點(diǎn)擊次數(shù)的簡單實(shí)例(從數(shù)據(jù)庫中讀取)

    js讀取被點(diǎn)擊次數(shù)的簡單實(shí)例(從數(shù)據(jù)庫中讀取)

    這篇文章主要介紹了js讀取被點(diǎn)擊次數(shù)的簡單實(shí)例(從數(shù)據(jù)庫中讀取)。需要的朋友可以過來參考下,希望對大家有所幫助
    2014-03-03
  • JavaScript中for-in和for-of的不同之處及如何正確使用

    JavaScript中for-in和for-of的不同之處及如何正確使用

    這篇文章主要給大家介紹了關(guān)于JavaScript中for-in和for-of的不同之處及如何正確使用它們的相關(guān)資料,無論是for...in還是for...of語句都是迭代一些東西,它們之間的主要區(qū)別在于它們的迭代方式,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-05-05
  • js 立即調(diào)用的函數(shù)表達(dá)式如何寫

    js 立即調(diào)用的函數(shù)表達(dá)式如何寫

    如果不需要顯示調(diào)用函數(shù), 讓這個(gè)函數(shù)在定義的時(shí)候就執(zhí)行的話, 該如何寫才可以呢,下面為大家介紹下具體的實(shí)現(xiàn)步驟,喜歡的朋友可以了解下
    2014-01-01
  • Bootstrap每天必學(xué)之基礎(chǔ)排版

    Bootstrap每天必學(xué)之基礎(chǔ)排版

    Bootstrap每天必學(xué)之基礎(chǔ)排版,排版是學(xué)習(xí)的最基礎(chǔ)環(huán)節(jié),相當(dāng)于地基,所以大家一定要認(rèn)真對待,認(rèn)真學(xué)習(xí)本文內(nèi)容。
    2015-11-11
  • JavaScript ES2019中的8個(gè)新特性詳解

    JavaScript ES2019中的8個(gè)新特性詳解

    這篇文章主要介紹了JavaScript ES2019中的8個(gè)新特性詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-02-02
  • JS 簡單展開關(guān)閉切換代碼

    JS 簡單展開關(guān)閉切換代碼

    一個(gè)JS實(shí)現(xiàn)的展開關(guān)閉來回切換的代碼。用于一段內(nèi)容的顯示與隱藏,點(diǎn)一次隱藏,再點(diǎn)一次就顯示,來回切換。
    2010-04-04
  • uniapp表單驗(yàn)證方法詳解

    uniapp表單驗(yàn)證方法詳解

    From表單組件具有數(shù)據(jù)收集、提交數(shù)據(jù)的功能,某種程度上說它就是一個(gè)容器,下面這篇文章主要給大家介紹了關(guān)于uniapp表單驗(yàn)證的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-10-10

最新評論