ES6学习笔记(十三)Reflect对象

Reflect与Proxy一样,是为了更好地操作对象而设计的,Proxy代理通过拦截修改某些方法,而Reflect是将一些方法移植到该对象上,使某些方法变为更加合理。

Reflect设计的目的


  1. 将Object中一些方法放到reflect对象上。现阶段某些方法同时在Object和Reflect对象上部署,未来的新方法将只在Reflect对象上部署。
  2. 修改某些Object的返回值,使其更为合理。
  3. 让Object操作变为函数行为。如in操作符和delete操作符使用has和deleteProperty方法来代替
  4. 与Proxy对象的方法一一对应,使得Proxy对象可以随时调用对应的默认方法,完成默认行为。(如果不使用Reflect中的方法来执行Proxy对象拦截的默认操作,可能会导致不停被Proxy对象拦截)
var obj=new Proxy({},{
    set(target,name,value){
        console.log(value);
        obj.name=value;
    }
})

obj.name='jack';

//会无限打印出'jack',因为该操作一直被拦截。

Reflect的方法


Reflect一共有13个方法,与Proxy对象的方法一一对应,大部分与Object对象的方法同名的方法作用都是相同的。

Reflect.get(target,name,receiver)

该方法传入三个参数,第一个参数为要查找的对象,第二个参数为要查找的属性名,第三个参数为查找对象中读取函数中this绑定的对象。

该方法用于获取target对象中属性名为name的值,如果没有该属性,则返回undefined。若有第三个参数,则读取函数中this指向第三个参数的对象,若没有第三个参数,则this指向目标对象。

var obj={

    foo:1,

    bar:2,

    get fn(){

        return this.foo+this.bar;

    }

}

var outObj={

    foo:4,

    bar:4

}

Reflect.get(obj,'foo')

// 1

Reflect.get(obj,'fn')

//3

Reflect.get(obj,'fn',outObj)

// 8

上面代码中,最后依次第三个参数为outObj对象,所以Reflect.get调用的方法fn中的this指向outObj对象,所以foo属性加bar属性才为8,没有传入参数时指向obj对象,所以最后结果为3。

方法的第一个参数若不为对象,则会报错,最后一个参数不为对象不会报错。下面出现的方法第一个参数也一样必须为对象,否则会报错(Reflect.apply和Reflect.construct方法第一个参数得是个方法)。

Reflect.get(1,'foo')

// Uncaught TypeError: Reflect.get called on non-object at Object.get

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

该方法传入四个参数,第一个参数为要查找的对象,第二个参数为要查找的属性名,第三个参数为要给对应属性名设置的值,第四个参数为查找对象中赋值函数中this绑定的对象。

该方法用于设置对象的属性值,同样的在赋值函数中若有this,有第四个参数时this指向第四个参数的对象,没有第四个参数时指向目标对象。在设置时,若有对应的属性名,则修改属性名,若没有,则给对象一个新的属性。

var obj={

    foo:1,

    set fn(value){

        this.foo=value;

    }

}

var outObj={

foo:10

}

Reflect.set(obj,'foo',2)

console.log(obj);

// {foo: 2}

Reflect.set(obj,'bar',2)

console.log(obj);

// {foo: 2, bar: 2}

Reflect.set(obj,'fn',3,outObj)

console.log(obj);

// {foo: 2, bar: 2}

console.log(outObj)

// {foo: 3}

同样的,如果第一个参数不是对象时会报错。

Reflect.has(obj,name)

该方法传入两个参数,第一个参数为查找的对象,第二个参数为查找的属性名。

该方法查找name属性是否在对象obj中,即返回 obj in name。

var obj={

    foo:1

}

Reflect.has(obj,'foo')

// true

Reflect.deleteProperty(obj,name)

该方法传入两个参数,第一个参数为要执行操作的对象,第二个参数为要删除的属性

该方法等同于delete obj[name],用于删除对象的属性,该方法返回一个布尔值,若删除成功或找不到该属性返回true,删除失败返回false。

var obj={

    foo:1

}

Reflect.deleteProperty(obj,'foo')

// true 删除成功

Reflect.deleteProperty(obj,'bar')

// true 找不到对应的属性

Reflect.construct(target,args)

该方法传入两个参数,第一个参数为要新建的方法名,第二个参数为传入的参数数组

该方法等同于使用new运算符,new target(...args),调用一个构造函数。

function fn(name){

    this.name=name;

}

var person=Reflect.construct(fn,['jack']);

console.log(person);

// fn {name: "jack"}

Reflect.getPrototypeOf(obj)

该方法传入一个参数,即要读取原型的对象。

该方法用于读取指定对象的原型对象,等同于Object.getPrototype

var pro={}

var obj=Object.create(pro);

Reflect.getPrototypeOf(obj)===pro

// true

Reflect.setPrototypeOf(obj,newProto)

该方法传入两个参数,第一个参数为要设置的对象,第二个参数为要作为原型的对象。

该方法用于设置原型的对象,即将第一个参数的原型设置为第二个参数

var obj={}

var pro={}

Reflect.setPrototypeOf(obj,pro)

// true

Reflect.getPrototypeOf(obj)===pro

// true

Reflect.definePrototype(target,prototypekey,attributes)

该方法传入三个参数,第一个参数为要操作的对象,第二个参数为要设置的属性名,第三个参数为要设置的属性的描述对象

该方法用于设置对象的属性的描述对象,等同于Object.definePrototype,阮一峰的书中提及尽可能地使用该方法,后者会被替代。

var obj={}

Reflect.defineProperty(obj,'foo',{value:10})

console.log(obj);

{foo: 10}

Reflect.getOwnPropertyDescriptor(target,prototypeKey)

该方法传入两个参数,第一个参数为要操作的对象,第二个参数为属性名。

该方法等同于Object.getOwnPrototyDescriptor,该方法会替代后者,获取属性的描述对象。

var obj={

    foo:1

}

Reflect.getOwnPropertyDescriptor(obj,'foo')

// {value: 1, writable: true, enumerable: true, configurable: true}

Reflect.isExtensible(target)

该方法传入一个参数,即要操作的对象。

该方法等同于Object.isExtensible,返回一个布尔值,表示对象是否可扩展。

var obj={

    foo:1

}

Reflect.isExtensible(obj)

// true

Reflect.preventExtensions(target)

该方法传入一个参数,即要操作的对象。

该方法等同于Object.preventExtensions,用于让一个对象变为不可扩展,返回一个布尔值,表示操作是否成功。

var obj={

    foo:1

}

Reflect.preventExtensions(obj)

// true

Reflect.isExtensible(obj)

// false

Reflect.ownKeys(target)

该方法传入一个参数,即要操作的对象。

该方法等同于Object.getOwnPrototyNames与Object.getOwnPrototySymbols得到的属性名值合,即获取对象自身的属性,包括Symbol值作属性名的属性,不能获取继承的属性。

var obj={

    foo:1

}

obj[Symbol()]=2

Reflect.ownKeys(obj)

// ["foo", Symbol()]

参考自阮一峰的《ECMAScript6入门》


ES6学习笔记目录

 

ES6学习笔记(一)let和const

ES6学习笔记(二)参数的默认值和rest参数

ES6学习笔记(三)箭头函数简化数组函数的使用

ES6学习笔记(四)解构赋值

ES6学习笔记(五)Set结构和Map结构

ES6学习笔记(六)Iterator接口

ES6学习笔记(七)数组的扩展

ES6学习笔记(八)字符串的扩展

ES6学习笔记(九)数值的扩展

ES6学习笔记(十)对象的扩展

ES6学习笔记(十一)Symbol

ES6学习笔记(十二)Proxy代理

ES6学习笔记(十三)Reflect对象

ES6学习笔记(十四)Promise对象

ES6学习笔记(十五)Generator函数

ES6学习笔记(十六)asnyc函数

ES6学习笔记(十七)类class

ES6学习笔记(十八)尾调用优化

ES6学习笔记(十九)正则的扩展

ES6学习笔记(二十)ES Module的语法

 

你可能感兴趣的:(ES6学习笔记,JavaScript)