JavaScript,如何利用Reflect获取及设置object属性?
发布于 作者:苏南大叔 来源:程序如此灵动~在JavaScript
的最新标准中,proxy
和reflect
总是在一起出现的。那么,本文就继续探讨一下js
中的reflect
的用法。reflect
能做的事情也很多,本文还是基于最基础的set
和get
来展开讨论。其它的reflect
能做的事情,留给后续讨论。
苏南大叔的“程序如此灵动”博客,记录苏南大叔的代码编程感悟。本文讨论在js
中reflect
的使用问题。测试环境:win10
,chrome@
。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 苏南大叔
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
修改数组的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)
在上面的例子里面,有对属性的setter
和getter
逻辑,注意里面:
- 有个没有定义的属性
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
,跳过了x
和y
属性限制。 - 对于
.get()
也使用了receiver
,却没能跳过y
的setter
设置。
对比proxy
对比proxy
的话,其实也是很明显。proxy
中有三个操作对象:原变量,代理变量,操作handler。而reflect
中,大多数情况下就操作原变量而已,个别情况下有个receiver
来修改this
的指向。(相对要死板一些)
而且,就目前的操作而言,reflect
没有什么使用上的便捷性而言。直接使用obj[prop]
或者obj.prop
不是更香么?就一个reveiver
使得reflect
有一点新意。
对比set和get编程
这部分和reflect
无关,只是对比proxy
中的set
和get
的验证编程逻辑。
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: 只能设置苏南开头词语
参考文献
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect
- https://newsn.net/say/js-proxy.html
结束语
reflect
按理说是十分强大有有用的,但是目前本文中的使用方式并没有显示其优越性。期待后续文章有所体现。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。