let fn = function() {
this.attr = [0,1,2,3];
};
let obj = {};
Reflect.apply(fn,[])
console.log(obj);
Reflect.apply的DEMO:
Reflect可以与Proxy联合使用:
{
var Fn = function(){
};
Fn.prototype.run = function() {
console.log( "runs out" );
};
var ProxyFn = new Proxy(Fn,{
construct (target,arugments) {
console.log("proxy constructor");
var obj = new target(...arugments);
//Reflect.apply的使用
方法;
Reflect.apply(target.prototype.run,arugments);
return obj;
}
});
new ProxyFn (); //会先
输出: "proxy constructor" ; 再
输出: runs out
}Reflect.construct()的使用:
Reflect.construct其实就是实例化构造
函数,通过传参形式的实现, 执行的方式不同,
效果其实一样, construct的第一个参数为构造
函数, 第二个参数由参数组成的数组或者伪数组, 基本的使用
方法为:
var Fn = function(arg) {
this.args = [arg]
};
console.log( new Fn(1),Reflect.construct(Fn,[1]) ); //
输出是一样的
var d = Reflect.construct(Date,[1776,6,4]);
d instanceof Date; // true
d.getFullYear(); // 1776
//所以Reflect.consturct和new 构所以Reflect.consturct和new 构造
函数是一样, 至少到目前为止..
我们可以给Reflect.construct传第三个参数 , 第三个参数为一个超类, 新元素会继承这个超类;
所以我们可以用这个实现一个特殊的的数组, 继承数组, 但是也有自己的
方法;
var Fn = function() {
Array.apply(this,arguments);
this.shot = ()=> {
console.log("heheda");
};
};
var arr = Reflect.construct(Fn,[])Reflect.defineProperty的使用;
Reflect.defineProperty返回的是一个布尔值, 通过直接赋值的方式把
属性和
属性值
添加给对象返回的是一整个对象, 如果
添加失败会抛错;
var obj = {};
obj.x = 10;
console.log(obj.x) //
输出:10;使用Reflect.defineProperty的方式
添加值;
如果我们执行preventExtensions, 通过Object.defindProperty定义新
属性报错了, 但是通过Reflect.defineProperty没有报错, 返回了一个false的值:
var obj = {};
Object.preventExtensions(obj);
Object.defineProperty(obj,{
value: 101,writable: false,enumerable: false,configurable: false
});// 直接抛错了;
console.log( Reflect.defineProperty(obj,{value:101}) ) //返回false:如果通过直接赋值的方式, 无论是否正确赋值, 都返回设置的值, 除非我们手动确认对象的
属性值是否设置成功;
Reflect.deleteProperty的使用:
Reflect.deleteProperty和Reflect.defineProperty的使用
方法差不多, Reflect.deleteProperty和 delete obj.xx的操作结果是一样, 区别是使用形式不同:一个是操作符,一个是
函数调用;
Reflect.deleteProperty(Object.freeze({foo: 1}),"foo"); // false
delete Object.freeze({foo: 1}).foo; //
输出:false;Reflect.get()
方法的使用
这个
方法的有两个必须的参数: 第一个为obj目标对象, 第二个为
属性名对象, 第三个是可选的,是作为读取器的上下文(this);
var obj = {};
obj.foo = 1;
console.log( obj.foo ); //
输出:1;
console.log( Reflect.get(obj,"foo") ) //
输出:1;如果Reflect.get有第三个参数的话,第三个参数会作为读取器的上下文:
var Reflect = require('harmony-reflect');
var obj = {
"foo" : 1,get bar() {
return this.foo;
}
};
var foo = {};
foo.foo = "heheda";
console.log(Reflect.get(obj,"bar",foo));
Reflect.getOwnPropertyDescritptor()
方法的使用:
通过Reflect.getOwnPropertyDescritptor
获取属性描述:
Reflect.getOwnPropertyDescriptor({x: "hello"},"x");
//也可以这样
获取:
Object.getOwnPropertyDescriptor({x:"1"},"x");
//这两个的区别是一个会包装对象, 一个不会:
Reflect.getOwnPropertyDescriptor("hello",0); //抛出异常
Object.getOwnPropertyDescriptor("hello",0); //
输出: {value: "h",enumerable: true,configurable: false}Reflect.getPrototypeOf()
方法的使用:
Reflect.getPrototypeOf和Object.getPrototypeOf是一样的,他们都是返回一个对象的原型
Reflect.getPrototypeOf({}); //
输出:Object.prototype
Reflect.getPrototypeOf(Object.prototype); //
输出:null
Reflect.getPrototypeOf(Object.create(null)); //
输出: nullReflect.has的使用
Reflect.has这个
方法有点像操作符:in , 比如这样: xx in obj;
这个demo的obj相当于变成了一个
方法了, 没他什么用 , 只是利用了他的has
方法:
obj = new Proxy({},{
has(t,k) { return k.startsWith("door"); }
});
Reflect.has(obj,"doorbell"); // true
Reflect.has(obj,"dormitory"); // false
Reflect.isExtensible()的使用
// 现在这个元素是可以扩展的;
var empty = {};
Reflect.isExtensible(empty); // === true
// 使用preventExtensions
方法, 让这个对象无法扩展新
属性;
Reflect.preventExtensions(empty);
Reflect.isExtensible(empty); // === false
// 这个对象无法扩展新
属性, 可写的
属性依然可以改动
var sealed = Object.seal({});
Reflect.isExtensible(sealed); // === false
// 这个对象完全被冻结了
var frozen = Object.freeze({});
Reflect.isExtensible(frozen); // === falseReflect.isExtensible和Object.isExtensible的区别是, 如果参数不对,一个会抛错, 另一个只是返回true或者false:
Reflect.isExtensible(1);
// 抛错了: 1 is not an object
Object.isExtensible(1);
// 返回false;Reflect.ownKeys()
方法的使用:
Reflect.ownKeys, Object可没有ownKeys
方法,Reflect.ownKeysz他的作用是返回对象的keys;
console.log(Reflect.ownKeys({"a":0,"b":1,"c":2,"d":3})); //
输出 :["a","b","c","d"]
console.log(Reflect.ownKeys([])); // ["length"]
var sym = Symbol.for("comet");
var sym2 = Symbol.for("meteor");
var obj = {[sym]: 0,"str": 0,"773": 0,"0": 0,[sym2]: 0,"-1": 0,"8": 0,"second str": 0};
Reflect.ownKeys(obj); //
输出:/ [ "0","8","773","str","-1","second str",Symbol(comet),Symbol(meteor) ]Reflect.ownKeys的排序是根据: 先
显示数字, 数字根据大小排序,然后是 字符串根据插入的顺序排序, 最后是symbol类型的key也根据插入插入顺序排序;
出现这中排序是因为,你给一个对象
属性赋值时候, 对象的key的排序规则就是先数字, 在字符串, 最后是symbol类型的数据;
Reflect.preventExtensions()的使用
方法:
Object也有preventExtensions
方法, 和Reflect.preventExtensions()有一点区别, 如果Reflect.preventExtensions参数不是对象会抛错;
var empty = {};
Reflect.isExtensible(empty); // === true
// 执行preventExtensions后的对象可以
修改;
Reflect.preventExtensions(empty);
Reflect.isExtensible(empty); // === false
Reflect.preventExtensions(1);
// TypeError: 1 is not an object
Object.preventExtensions(1);
//不会抛错, 会返回:1Reflect.set()
Reflect.set
方法和get是差不多的;
var obj = {};
Reflect.set(obj,"prop","value"); //
输出:true
console.log( obj.prop ); //
输出:"value"
var arr = ["duck","duck","duck"];
Reflect.set(arr,"goose"); // true
console.log( arr[2] ); // "goose"
Reflect.set(arr,"length",1); // true
console.log( arr );// ["duck"];Reflect.set(obj)相当于 Reflect.set(obj,undefined);
var obj = {};
Reflect.set(obj); //
输出:true
//以上的
代码相当于 Reflect.set(obj,undefined);
Reflect.getOwnPropertyDescriptor(obj,"undefined");
// { value: undefined,writable: true,configurable: true }Reflect.set也可以有第四个参数, 这个参数会作为stter的this;
var obj = {
value : 10,set key( value ) {
console.log("setter");
this.value = value;
},get key() {
return this.value;
}
};
Reflect.set(obj,"key","heheda",obj);
console.log(obj);Reflect.setPrototypeOf()
Reflect.setPrototypeOf()
方法和Object.setPrototypeOf差不多一样样的, 会给对象设置原型, 就是更改对象的__proto__
属性了…;
Reflect.setPrototypeOf({},Object.prototype); //
输出true
// 给该对象数组[[Prototype]] 为null.
Reflect.setPrototypeOf({},null); // true
// 此时的obj.__proto__为undefine
//把对象冻结以后重新设置[[prototype]]
Reflect.setPrototypeOf(Object.freeze({}),null); // false
// 如果原型链循环依赖的话就会返回false.
var target = {};
var proto = Object.create(target);
Reflect.setPrototypeOf(target,proto); // false