


ES6 new features: Detailed explanation of Reflect object code in JavaScript
Reflect introduction:
The Reflect object has not been implemented in my node (v4.4.3), nor has babel (6.7.7). The new version of chrome is Yes, ff has supported Proxy and Reflect for a long time. If you want node to support Reflect, you can install harmony-reflect;
Reflect is not a constructor. When you want to use it, call it directly through Reflect.method(). Reflect has The methods are similar to those of Proxy, and most of the native Object Reflect methods have been re-implemented.
Why use Reflect
Here are a few reasons why you should use Reflect. Translation address: Reflect, roughly translated:
1: More useful return values : Reflect has some methods that are the same as the Object methods in ES5, such as: Reflect.getOwnPropertyDescriptor and Reflect.defineProperty. However, successful execution of Object.defineProperty(obj, name, desc) will return obj, as well as errors caused by other reasons. Reflect .defineProperty will only return false or true to indicate whether the object's properties are set. The following code can be refactored:
try { Object.defineProperty(obj, name, desc); // property defined successfully } catch (e) { // possible failure (and might accidentally catch the wrong exception) }
Refactored into this:
if (Reflect.defineProperty(obj, name, desc)) { // success } else { // failure }
The rest of the methods, such as Relect.set , Reflect.deleteProperty, Reflect.preventExtensions, Reflect.setPrototypeOf, can all be refactored;
2: Function operation, if you want to judge that an obj has a definition or inherits the attribute name, judge it like this in ES5: name in obj; or delete an attribute: delete obj[name]. Although these are easy to use, very short and clear, they must be encapsulated into a class when used;
With Reflect, it helps You have encapsulated it, Reflect.has(obj, name), Reflect.deleteProperty(obj, name);
3: A more reliable functional execution method: In ES, you want to execute a function f, and Pass it a set of parameter args, and if you want to bind this, you should write it like this:
f.apply(obj, args)
But f's apply may be redefined as the user's own apply, so it is more reliable to write it like this:
Function.prototype.apply.call(f, obj, args)
The above code is too long and difficult to understand. With Reflect, we can make it shorter, more concise and clear:
Reflect.apply(f, obj, args)
4: Constructor in the form of variable parameters: Imagine , you want to instantiate a constructor with parameters of uncertain length. In ES5, we can use extension symbols, which can be written like this:
var obj = new F(...args)
However, in ES5, extension symbols are not supported, so, we You can only use F.apply or F.call to pass different parameters. Unfortunately, F is a constructor, which is a cheat. But with Reflect, we can write like this in ES5:
var obj = Reflect.construct(F, args)
5: Control this of the accessor or reader: In ES5, if you want to read the attributes of an element or set the attributes, you need to do this:
var name = ... // get property name as a string obj[name] // generic property lookup obj[name] = value // generic property update
The Reflect.get and Reflect.set methods allow us to do the same thing, and he added an extra parameter receiver, allowing us to set the object's setter and getter's context:
var name = ... // get property name as a string Reflect.get(obj, name, wrapper) // if obj[name] is an accessor, it gets run with `this === wrapper` Reflect.set(obj, name, value, wrapper)
The accessor does not want to use its own method, but wants to redirect this to the wrapper:
var obj = { set foo(value) { return this.bar(); }, bar: function() { alert(1); } }; var wrapper = { bar : function() { console.log("wrapper"); } } Reflect.set(obj, "foo", "value", wrapper);
6: Avoid direct access to __proto__: ES5 provides Object.getPrototypeOf(obj) to access the prototype of the object, ES6 also provides Reflect.getPrototypeOf(obj)
and Reflect .setPrototypeOf(obj, newProto), this is a new method to access and set the prototype of an object:
Usage of Reflect.apply
Reflect.apply is actually Function.prototype in ES5. apply() substitute, three parameters are required to execute Reflect.apply
The first parameter is: the function that needs to be executed;
The second parameter is: the context this that needs to execute the function;
th The three parameters are: It is an array or pseudo-array, which will be used as a parameter to execute the function;
<script> let fn = function() { this.attr = [0,1,2,3]; }; let obj = {}; Reflect.apply(fn, obj, []) console.log(obj); </script>
Demo of Reflect.apply:
<script> Reflect.apply(Math.floor, undefined, [1.75]); // 输出:1; Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]); // 输出:"hello" Reflect.apply(RegExp.prototype.exec, /ab/, ["confabulation"]).index; //输出: 4 Reflect.apply("".charAt, "ponies", [3]); // 输出:"i" </script>
Reflect can be used in conjunction with 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, obj, arugments); return obj; } }); new ProxyFn (); //会先输出: "proxy constructor" ; 再输出: runs out }
Usage of Reflect.construct():
Reflect.construct is actually an instance The constructor is implemented in the form of passing parameters. The execution method is different, but the effect is actually the same. The first parameter of construct is the constructor, and the second parameter is an array or pseudo-array composed of parameters. The basic usage method is:
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 构
So Reflect.consturct is the same as the new constructor, at least so far..
We can pass the third parameter to Reflect.construct, and the third parameter is a super class. New elements will inherit this super class;
<script> function someConstructor() {} var result = Reflect.construct(Array, [], someConstructor); Reflect.getPrototypeOf(result); // someConstructor.prototype Array.isArray(result); // true //or var Fn = function() { this.attr = [1]; }; var Person = function() { }; Person.prototype.run = function() { }; console.log( Reflect.construct(Fn, [], Person) ); </script>
So we can use this to implement a special array, inherit the array, but also have its own methods;
var Fn = function() { Array.apply(this, arguments); this.shot = ()=> { console.log("heheda"); }; }; var arr = Reflect.construct(Fn, [])
Use of Reflect.defineProperty;
Reflect.defineProperty returns a Boolean value. Adding properties and property values to an object through direct assignment returns an entire object. If the addition fails, an error will be thrown;
var obj = {}; obj.x = 10; console.log(obj.x) //输出:10;
Use Reflect.defineProperty to add the value;
<script> var obj = {}; if( Reflect.defineProperty(obj, "x", {value : 7 }) ) { console.log("added success"); }else{ console.log("添加失败"); }; </script>
如果我们执行preventExtensions, 通过Object.defindProperty定义新属性报错了, 但是通过Reflect.defineProperty没有报错, 返回了一个false的值:
var obj = {}; Object.preventExtensions(obj); Object.defineProperty(obj, "x" , { value: 101, writable: false, enumerable: false, configurable: false });// 直接抛错了; console.log( Reflect.defineProperty(obj, "x", {value:101}) ) //返回false:
如果通过直接赋值的方式, 无论是否正确赋值, 都返回设置的值, 除非我们手动确认对象的属性值是否设置成功;
<script> var obj = {}; Object.preventExtensions(obj); console.log( obj.aa = 1 ); //输出:1; console.log(obj.aa) //输出:undefined; </script>
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", writable: false, enumerable: true, configurable: false}
Reflect.getPrototypeOf()方法的使用:
Reflect.getPrototypeOf和Object.getPrototypeOf是一样的, 他们都是返回一个对象的原型
Reflect.getPrototypeOf({}); // 输出:Object.prototype Reflect.getPrototypeOf(Object.prototype); // 输出:null Reflect.getPrototypeOf(Object.create(null)); // 输出: null
Reflect.has的使用
Reflect.has这个方法有点像操作符:in , 比如这样: xx in obj;
<script> Reflect.has({x:0}, "x") //输出: true; Reflect.has({y:0}, "y") //输出:true ; var obj = {x:0}; console.log( "x" in obj); var proxy = new Proxy(obj, { has : function(target, args) { console.log("执行has方法"); return Reflect.has(target,...args); } }); console.log( "x" in proxy); //输出:true; console.log(Reflect.has(proxy, "x")) //输出:true; </script>
这个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); // === false
Reflect.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); //不会抛错, 会返回:1
Reflect.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, 2, "goose"); // true console.log( arr[2] ); // "goose" Reflect.set(arr, "length", 1); // true console.log( arr );// ["duck"];
Reflect.set(obj)相当于 Reflect.set(obj, undefined, undefined);
var obj = {}; Reflect.set(obj); // 输出:true //以上的代码相当于 Reflect.set(obj, undefined, undefined); Reflect.getOwnPropertyDescriptor(obj, "undefined"); // { value: undefined, writable: true, enumerable: 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
以上就是ES6新特性:JavaScript中的Reflect对象代码详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

Introduction to how to use JavaScript and WebSocket to implement a real-time online ordering system: With the popularity of the Internet and the advancement of technology, more and more restaurants have begun to provide online ordering services. In order to implement a real-time online ordering system, we can use JavaScript and WebSocket technology. WebSocket is a full-duplex communication protocol based on the TCP protocol, which can realize real-time two-way communication between the client and the server. In the real-time online ordering system, when the user selects dishes and places an order

How to use WebSocket and JavaScript to implement an online reservation system. In today's digital era, more and more businesses and services need to provide online reservation functions. It is crucial to implement an efficient and real-time online reservation system. This article will introduce how to use WebSocket and JavaScript to implement an online reservation system, and provide specific code examples. 1. What is WebSocket? WebSocket is a full-duplex method on a single TCP connection.

JavaScript and WebSocket: Building an efficient real-time weather forecast system Introduction: Today, the accuracy of weather forecasts is of great significance to daily life and decision-making. As technology develops, we can provide more accurate and reliable weather forecasts by obtaining weather data in real time. In this article, we will learn how to use JavaScript and WebSocket technology to build an efficient real-time weather forecast system. This article will demonstrate the implementation process through specific code examples. We

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

Usage: In JavaScript, the insertBefore() method is used to insert a new node in the DOM tree. This method requires two parameters: the new node to be inserted and the reference node (that is, the node where the new node will be inserted).

JavaScript is a programming language widely used in web development, while WebSocket is a network protocol used for real-time communication. Combining the powerful functions of the two, we can create an efficient real-time image processing system. This article will introduce how to implement this system using JavaScript and WebSocket, and provide specific code examples. First, we need to clarify the requirements and goals of the real-time image processing system. Suppose we have a camera device that can collect real-time image data
