第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

ES6-10 入門教程

ES6+ Reflect(二)

1. 前言

上一節(jié)我們學(xué)習(xí)了 Reflect 的使用和一些基本的API,本節(jié)我們將繼續(xù)學(xué)習(xí) Reflect 的一些擴(kuò)展的API。

2 Reflect 擴(kuò)展方法

2.1 Reflect.defineProperty()

Reflect.defineProperty() 方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性,基本等同于 Object.defineProperty() 方法,唯一不同是 Object.defineProperty() 返回的是這個(gè)對(duì)象,Reflect.defineProperty() 返回的是 Boolean 值。

語法:

Reflect.defineProperty(target, propertyKey, attributes)
  • target:目標(biāo)對(duì)象;
  • propertyKey:需要定義或修改的屬性的名稱;
  • attributes:需要定義或修改的屬性的描述。

如果 target 不是 Object,拋出一個(gè) TypeError。

let obj = {}
Reflect.defineProperty(obj, 'a', {value: 10})  // true
obj.a;	// 10

Reflect.defineProperty 方法可以根據(jù)返回值檢查屬性是否被成功定義,而 Object.defineProperty 只能通過 try...catch 去捕獲其中的錯(cuò)誤,相比之下 Reflect.defineProperty() 方法更加方便。

var obj = {}
var r = Reflect.defineProperty(obj, 'a', {value: 10})

if (r) {
  // 成功 todo
} else {
  // 失敗 todo
}

try {
  let obj = {}
	Object.defineProperty(obj, 'a', {value: 10})
} catch(e) {
  // 如果失敗,捕獲的異常
}

2.2 Reflect.apply()

**Reflect.apply()** 通過指定的參數(shù)列表發(fā)起對(duì)目標(biāo) (target) 函數(shù)的調(diào)用。

語法:

Reflect.apply(target, thisArgument, argumentsList)
  • target:目標(biāo)函數(shù)。
  • thisArgument:target 函數(shù)調(diào)用時(shí)綁定的 this 對(duì)象。
  • argumentsList:target 函數(shù)調(diào)用時(shí)傳入的實(shí)參列表,該參數(shù)應(yīng)該是一個(gè)類數(shù)組的對(duì)象。

apply 函數(shù)我們都知道,它可以讓函數(shù)執(zhí)行并可以改變 this 指向。

const arr = [1, 6, 7, 10, 2, 5];
let max;
max = Math.max.apply(null, arr);
console.log(max);	// 10

Reflect.apply() 方法與

上面的代碼中 fn.apply(obj, args) 的寫法還可以寫成 Function.prototype.apply.call(func, thisArg, args) ,Function.prototype.apply.call(fn, obj, args) 這和 Reflect.apply() 的調(diào)用時(shí)傳參是一樣的。都是用于綁定 this 對(duì)象然后執(zhí)行給定函數(shù),Reflect 對(duì)象則簡化這種操作。

max = Function.prototype.apply.call(Math.max, null, arr);
console.log(max);	// 10

max = Reflect.apply(Math.max, null, arr);
console.log(max);  // 10

Reflect.apply() 可以接收截取字符串的函數(shù)。

let str = 'imooc ES6 wiki';
let newStr;

newStr = Reflect.apply(String.prototype.slice, str, [6, 9]);
console.log(newStr); // ES6

newStr = str.slice(6, 9);
console.log(newStr); // ES6
newStr = String.prototype.slice.apply(str, [6, 9]);
console.log(newStr); // ES6

2.3 Reflect.construct(target, args)

Reflect.construct()new 操作符構(gòu)造函數(shù)相似 ,相當(dāng)于運(yùn)行 new target(...args) ,提供了一種新的不使用 new 來調(diào)用構(gòu)造函數(shù)的方法。

語法:

Reflect.construct(target, argumentsList[, newTarget])

參數(shù):

  • target:被運(yùn)行的目標(biāo)構(gòu)造函數(shù);
  • argumentsList:類數(shù)組,目標(biāo)構(gòu)造函數(shù)調(diào)用時(shí)的參數(shù);
  • newTarget:(可選)作為新創(chuàng)建對(duì)象的原型對(duì)象的 constructor 屬性,默認(rèn)值為 target 。

下面的兩種實(shí)例化的方式是一樣的。

function Foo() {
  console.log(arguments);
}

var obj = new Foo(...args);
var obj = Reflect.construct(Foo, args); 

Reflect.construct() 返回值是以 target 函數(shù)為構(gòu)造函數(shù),如果 newTarget 存在,則為 newTarget 。argumentList 為其初始化參數(shù)。

對(duì)于有沒有傳遞第三個(gè)參數(shù),我們可以這樣理解:target 就是唯一的構(gòu)造函數(shù),但是如果傳遞了第三個(gè)參數(shù),那就表示:我們的實(shí)例由兩部分組成,實(shí)例上綁定在 this 上的屬性部分由第一個(gè)參數(shù)的構(gòu)造函數(shù)生成;不是實(shí)例上的屬性部分則由第三個(gè)參數(shù)的構(gòu)造函數(shù)生成。下面我們來看下具體的實(shí)例:

class A {
  constructor(name) {
    console.log('init A class');
    this.name = name || 'Jack';
  }
  getName() {
    console.log(this.name);
    return this.name;
  }
}
class B {
	constructor(age) {
    console.log('init A class');
    this.age = age || 18;
  }
  getAge() {
    console.log(this.age);
    return this.age;
  }
}

// 使用A類作為構(gòu)造函數(shù)
let a = Reflect.construct(A, ['David']);
// 使用B類作為構(gòu)造函數(shù)
let b = Reflect.construct(A, ['David'], B);

console.log(a);
console.log(b);
a.getName();
b.getAge();

下圖是上面代碼的打印結(jié)果,創(chuàng)建實(shí)例 a 時(shí)沒有第三個(gè)參數(shù),它的原型上的 constructor 指向的是類 A,并且有 getName 方法。創(chuàng)建實(shí)例 b 時(shí)有第三個(gè)參數(shù),打印的結(jié)果可以看到實(shí)例 b 原型上的 constructor 執(zhí)行的是類 B,并且有 B 上的 getAge 方法。

3. 小結(jié)

本節(jié)主要講解了 Reflect 擴(kuò)展方法的使用