好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ES6+ Reflect(二)

ES6+ Reflect(二)

1. 前言

上一节我们学习了 Reflect 的使用和一些基本的API,本节我们将继续学习 Reflect 的一些扩展的API。

2 Reflect 扩展 方法

2.1 Reflect.define property()

Reflect.define property() 方法 会直接在 一个 对象上定义 一个 新 属性 ,或者 修改 一个 对象的现有 属性 ,基本等同于 Object.define property() 方法 ,唯一不同是 Object.define property() 返回的是这个对象, Reflect.define property() 返回的是 Boolean 值。

语法:

 Reflect .  defineProperty  ( target ,  propertyKey ,  attributes ) 
 

target:目标对象; propertyKey:需要定义或 修改 的 属性 的 名称 ; attributes:需要定义或 修改 的 属性 的描述。

如果 target 不是 Object ,抛出 一个 TypeError 。

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

Reflect.defineProperty 方法 可以根据返回值检查 属性 是否被成功定义,而 Object.defineProperty 只能通过 try...catch 去捕获其中的 错误 ,相比之下 Reflect.define property() 方法 更加方便。

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

 if   ( r )   { 
   // 成功 t odo  
 }   else   { 
   // 失败 t odo  
 } 

 try   { 
   let  obj  =   {  } 
	Object .  defineProperty  ( obj ,   'a'  ,   { value :   }  ) 
 }   catch  ( e )   { 
   // 如果失败,捕获的异常 
 } 
 

2.2 Reflect.apply()

**Reflect.apply() ** 通过指定的参数列表发起对目标 (target) 函数 的 调用 。

语法:

 Reflect .  apply  ( target ,  thisArgument ,  argumentsList ) 
 

target:目标 函数 。 thisArgument:target 函数 调用 时绑定的 this 对象。 argumentsList:target 函数 调用 时传入的实参列表,该参数应该是 一个 类数组的对象。

apply 函数 我们都知道,它可以让 函数 执行并可以改变 this 指向。

  const  arr  =   [  ,   ,   ,   ,   ,   ]  ; 
 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() 的 调用 时传参是一样的。都是用于绑定 this 对象然 后执行 给定 函数 , Reflect 对象则简化这种操作。

  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() 可以接收 截取 字符串的 函数 。

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

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

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

2.3 Reflect.construct(target, args)

Reflect.construct() 和 new 操作符构造 函数 相似 ,相当于运行 new target(...args) ,提供了一种新的不使用 new 来 调用 构造 函数 的 方法 。

语法:

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

参数:

target:被运行的目标构造 函数 ; argumentsList:类数组,目标构造 函数 调用 时的参数; newTarget:(可选)作为新创建对象的原型对象的 constructor 属性 , 默 认值为 target 。

下面的两种实例化的方式是一样的。

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

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

Reflect.construct() 返回值是以 target 函数 为构造 函数 ,如果 newTarget 存在,则为 newTarget 。 argumentList 为其初始化参数。

对于有没有传递第三个参数,我们可以这样理解:target 就是唯一的构造 函数 ,但是如果传递了第三个参数,那就表示:我们的实例由两部分组成,实例上绑定在 this 上的 属性 部分由第 一个 参数的构造 函数 生成 ;不是实例上的 属性 部分则由第三个参数的构造 函数 生成 。下面我们来看下具体的实例:

  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  ||   ; 
   } 
   getAge  (  )   { 
    console .  log  (  this  . age )  ; 
     return   this  . age ; 
   } 
 } 

 // 使用A类作为构造 函数  
 let  a  =  Reflect .  construct  ( A ,   [  'David'  ]  )  ; 
 // 使用B类作为构造 函数  
 let  b  =  Reflect .  construct  ( A ,   [  'David'  ]  ,  B )  ; 

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

下图是上面 代码 的打印结果,创建实例 a 时没有第三个参数,它的原型上的 constructor 指向的是类 A,并且有 getName 方法 。创建实例 b 时有第三个参数,打印的结果可以看到实例 b 原型上的 constructor 执行的是类 B,并且有 B 上的 getAge 方法 。

3. 小结

本节主要讲解了 Reflect 扩展 方法 的使用

查看更多关于ES6+ Reflect(二)的详细内容...

  阅读:40次

上一篇

下一篇

第1节:ES6+ 简介    第2节:ES6 环境配置    第3节:ES6+ let    第4节:ES6+ const    第5节:ES6+ 展开语法    第6节:ES6+ 剩余参数    第7节:ES6+ 解构赋值    第8节:ES6+ 模版字符串    第9节:ES6+ 箭头函数    第10节:ES6+ 数值扩展    第11节:ES6+ isFinite()&isNaN()    第12节:ES6+ Number 对象的方法    第13节:ES6+ Math 对象的扩展    第14节:ES6+ includes()    第15节:ES6+ 字符串的扩展    第16节:ES6+ startsWith()    第17节:ES6+ endsWith()    第18节:ES6+ repeat()    第19节:ES6+ padStart()    第20节:ES6+ padEnd()    第21节:ES6+ trim()    第22节:ES6+ Array.from()    第23节:ES6+ of()    第24节:ES6+ find()和findIndex()    第25节:ES6+ copyWithin()    第26节:ES6+ fill()    第27节:ES6+ isArray()    第28节:ES6+ 对象的扩展    第29节:ES6+ flat()    第30节:ES6+ 可选链操作符    第31节:ES6+ Object.is()    第32节:ES6+ Object.assign()    第33节:ES6+ Object.keys()    第34节:ES6+ Object.values()    第35节:ES6+ Object.entries()    第36节:ES6+ 数据结构扩展    第37节:ES6+ Set    第38节:ES6+ WeakSet    第39节:ES6+ Map    第40节:ES6+ WeakMap    第41节:ES6+ Symbol    第42节:ES6+ for...of    第43节:ES6+ 迭代协议    第44节:ES6+ 实现一个简版的 Promise    第45节:ES6+ Promise 基础    第46节:ES6+ Promise 进阶    第47节:ES6+ Generator 基础    第48节:ES6+ Generator 函数应用    第49节:ES6+ async/await    第50节:ES6+ Class 前置知识    第51节:ES6+ Class    第52节:ES6+ Proxy    第53节:ES6+ Reflect(一)    第54节:ES6+ Reflect(二)    第55节:ES6+ 模块化(一)    第56节:ES6+ 模块化(二)    第57节:ES6实战1-实现Vue3 reactive 源码    第58节:ES6实战2-实现 Vue3 effect 源码    第59节:ES6 实战2-封装请求    第60节:ES6+ 实战3-代码整洁之道    第61节:ES6 Map原理分析    第62节:ES6module语法加载importexport    第63节:ES6的循环与可迭代对象示例详解