我们相信:世界是美好的,你是我也是。平行空间的世界里面,不同版本的生活也在继续...

JavaScript的最新标准中,proxyreflect总是在一起出现的。那么,本文就继续探讨一下js中的reflect的用法。reflect能做的事情也很多,本文还是基于最基础的setget来展开讨论。其它的reflect能做的事情,留给后续讨论。

苏南大叔:JavaScript,如何利用Reflect获取及设置object属性? - reflect获取改写属性
JavaScript,如何利用Reflect获取及设置object属性?(图5-1)

苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程感悟。本文讨论在jsreflect的使用问题。测试环境:win10chrome@reflect是js内置的,不可构造。

reflect获取属性get

原型是这样的:

Reflect.get(target,property,receiver)

使用例子:

var greeting = Reflect.get(["hello", "苏南大叔"], 0);
var obj = {
  greeting: "hello",
  to: "苏南大叔",
};
var to = Reflect.get(obj, "to");
console.log(greeting,to);

输出:

hello 苏南大叔

苏南大叔:JavaScript,如何利用Reflect获取及设置object属性? - 代码一get
JavaScript,如何利用Reflect获取及设置object属性?(图5-2)

reflect设置属性set

函数原型是:

Reflect.set(target,propName,propValue,receiver)

这里因为操作对象仅仅是原对象,所以并没有像proxy一样的透传的说法。但是,可以从下面的代码看到,这个reflect.get()的操作,似乎没有什么使用的必要呢。

var obj = {};
Reflect.set(obj, "www", "newsn.net");
var www = Reflect.get(obj, "www");
console.log(www, obj.www, obj["www"]);

输出:

newsn.net newsn.net newsn.net

苏南大叔:JavaScript,如何利用Reflect获取及设置object属性? - 代码二set
JavaScript,如何利用Reflect获取及设置object属性?(图5-3)

修改数组的length属性,居然会有截断数组的副作用,这个用法非常奇特。

const arr1 = ["hello", "苏南大叔", "newsn.net"];
Reflect.set(arr1, 0, "hola");
console.log(arr1[0]);          // hola

Reflect.set(arr1, "length", 1);
console.log(arr1);             // ["hola"];

输出:

hola
['hola']

reflect修改receiver(this)

在上面的例子里面,有对属性的settergetter逻辑,注意里面:

  • 有个没有定义的属性x
  • 并且y属性必须设置以文字"苏南"开头。

在这里,通过reflect里改变receiver,突破上面的两条限制。实际上是修改了this的指向了。

receiver = {
  x: "hello",
  y: "虎子二赖子",
};
get_ = Reflect.get(obj, "sn", receiver);
console.log(get_); // hello,虎子二赖子
set_ = Reflect.set(obj, "sn", "虎子", receiver); // 这里依然走原来的setter逻辑判断,抛出错误
console.log(set_);
  • 这里在.set()里面设置了receiver,跳过了xy属性限制。
  • 对于.get()也使用了receiver,却没能跳过ysetter设置。

苏南大叔:JavaScript,如何利用Reflect获取及设置object属性? - 代码四receiver
JavaScript,如何利用Reflect获取及设置object属性?(图5-4)

对比proxy

对比proxy的话,其实也是很明显。proxy中有三个操作对象:原变量,代理变量,操作handler。而reflect中,大多数情况下就操作原变量而已,个别情况下有个receiver来修改this的指向。(相对要死板一些)

而且,就目前的操作而言,reflect没有什么使用上的便捷性而言。直接使用obj[prop]或者obj.prop不是更香么?就一个reveiver使得reflect有一点新意。

对比set和get编程

这部分和reflect无关,只是对比proxy中的setget的验证编程逻辑。

let obj = {
  y: "",
  get sn() {
    console.log("get sn prop");
    return (this.x === undefined ? "hi" : this.x) + "," + this.y;
  },
  set sn(val) {
    console.log("set sn prop to "+val);
    if (!val.startsWith("苏南")) {
      throw Error("只能设置苏南开头词语");
    }
    this.y = val;
    return true;
  },
};
obj.sn = "苏南大叔";   // set
console.log(obj.sn);  // get,注意this.x取值变化
obj.sn="虎子";        // Uncaught Error: 只能设置苏南开头词语

这里可以设置属性sn为"苏南大叔",但是设置为"虎子"的时候,就会被抛出异常信息。
输出:

set sn prop to 苏南大叔
get sn prop
hi,苏南大叔

set sn prop to 虎子
Uncaught Error: 只能设置苏南开头词语

苏南大叔:JavaScript,如何利用Reflect获取及设置object属性? - 代码三x
JavaScript,如何利用Reflect获取及设置object属性?(图5-5)

参考文献

结束语

reflect按理说是十分强大有有用的,但是目前本文中的使用方式并没有显示其优越性。期待后续文章有所体现。

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。

 【福利】 腾讯云最新爆款活动!1核2G云服务器首年50元!

 【源码】本文代码片段及相关软件,请点此获取更多信息

 【绝密】秘籍文章入口,仅传授于有缘之人   js