当前位置:网站首页>ES6 essence:
ES6 essence:
2020-11-06 01:17:00 【:::::::】
Introduction
This paper mainly introduces ES6 in Proxy and Reflect The essence of knowledge , And some examples are given .Proxy Agent means agent , Agents generated for objects through operations , Implement intercepting programming for various operations of objects .Reflect It's a more strict one 、 Sound operation object method module . because Proxy The method of agency and Reflect The methods included basically correspond to , And in the interception method should use the corresponding Reflect Method returns the result , So combine the two together to share .
1 Proxy
1.1 Ascend the hall
Think of a question first , How to control the reading and modification of a property of an object ( It doesn't involve closures creating private properties )? First create container properties that should not be changed directly :_ Property name , Then set the corresponding setter and getter Function or create the corresponding operation method .
--- Set up setter and getter function
let obj = {
_id: undefined,
get id() {
return this._id;
},
set id(v) {
this._id = v;
}
};
obj.id = 3; // Quite a :obj._id = 3
console.log(obj.id); // console.log(obj._id);
--- Create access and modify methods
let obj = {
_id: undefined,
id() {
if (!arguments.length) return this._id;
this._id = arguments[0];
}
};
obj.id(3); // Quite a :obj._id = 3
console.log(obj.id()); // console.log(obj._id);
There are obvious flaws in this : Repeat the settings for each attribute that needs to be controlled , And in fact, container properties can be arbitrarily modified . If an upgrade is required , We need to monitor to see 、 Delete 、 The operation of traversing the properties of an object , What do I do ?ES6 Before, it was only cold sauce ,ES6 after Proxy Do it for you .
let obj = { id: 0, name: 'Wmaker' };
let objProxy = new Proxy(obj, {
get(target, attr) {
console.log(`Get ${attr}`);
return target[attr];
},
set(target, attr, val) {
console.log(`Set ${attr}`);
target[attr] = val;
return true;
}
});
objProxy.id; // Print out :Get id, Quite a :obj.id;
objProxy.name; // Print out :Get name, Quite a :obj.name;
1.2 Enter the room
As can be seen from the example in the previous section ,Proxy Is the constructor that generates the proxy . The first parameter passed in is the object to be proxy , The second parameter is the configuration object that needs to be intercepted ( After that, all interceptable operations, their meanings and considerations are listed ). Each interception operation in the configuration object , Both have default format input parameters , Some also require specific return values ( Here are some of the rules ).
The generated proxy is a proxy instance associated with the proxy object , It can be treated like a normal object . That is , Can be delete Drop an attribute , Can be traversed or prototyped . All actions on the agent , They all act directly on the surrogate object , You can also configure interception operations for them . The point of anger is , Mr. Cang can do well , How can our teacher Ozawa be poor ? What's more, it's not just objects that can be represented , Functions that belong to objects 、 Arrays are unconditionally accepted .
After generating a proxy for an object , You can still manipulate the original object , But of course this is not recommended .
Parameters Different interceptors have different input parameters , But it's usually the principal object , This operation requires parameters, etc. and proxy objects . You don't have to remember the parameters of each interceptor function , Reduce the burden on the brain , Print out when using arguments Check it out at a glance .
Return value In the interception method , Try to use Reflect The corresponding method is operated , And return the return value of the method . On the one hand, it's simple , What's more important is that in different ways or under certain circumstances , There are rigid requirements for return values , Otherwise, report the error directly . such as construct() An object must be returned , Otherwise, the report will be wrong . Another example set() In strict mode , Must return true Or it can be transformed into true Value , Whether the operation is successful or not .
"use strict";
--- Wrong way
let obj = { id: 0 };
let objProxy = new Proxy(obj, {
set(target, attr, val) {
console.log(`Set ${attr}`);
return target[attr] = val;
}
});
objProxy.id = 1; // Successful operation .
objProxy.id = 0; // The operation has been successful , But wrong reporting , No further execution .
--- Recommended Practice
let obj = { id: 0 };
let objProxy = new Proxy(obj, {
set(target, attr, val) {
console.log(`Set ${attr}`);
return Reflect.set(target, attr, val);
}
});
objProxy.id = 1; // Successful operation .
objProxy.id = 0; // Successful operation .
The return value of the interceptor method is not directly reflected to the outside ,JS There will be some validation and exclusion . For example, even in ownKeys() Return all the values in , But actually, only the corresponding series goes to the outside .
The results of two printing are not equal .
let obj = { id: 0, [Symbol.iterator]() {} };
let objProxy = new Proxy(obj, {
ownKeys(target) {
let res = Reflect.ownKeys(target);
console.log('1', res);
return res;
}
});
console.log( Object.keys('2', objProxy) );
Restrictive continuance When the surrogate object itself has some limitations , For example, it is not extensible or its properties are not writable and configurable . The operation of the object itself has been limited , In this case, if you execute the corresponding proxy operation , It's natural to report a mistake . For example, when an attribute is not writable , If the agent and execute set() operation , It will directly report an error .
let obj = { id: 0 };
Object.defineProperty(obj, 'name', {
value: 'Wmaker'
});
let objProxy = new Proxy(obj, {
set(target, attr, val) {
return Reflect.set(target, attr, val);
}
});
objProxy.id = 1; // Successful operation .
objProxy.name = 'Limo'; // Report errors .
this Some internal properties or methods of native objects , Only through the right this Ability to visit , So there's no agency . For example, date objects ,new Proxy(new Date(), {}).getDate(), Wrong presentation : This is not a Date object .
There are also workarounds , For example, for the need to be right this You can do this .
let p = new Proxy(new Date(), {
get(target, attr) {
const v = Reflect.get(target, attr);
return typeof v === 'function'
? v.bind(target)
: v;
}
});
p.getTime(); // There is no mistake .
In the configuration object this Point directly to the configuration object , Not a delegate object or a proxy object . In the delegate object this, It can be divided into two parts: existing in method and existing in getter/setter Two of them . Both get this In different ways , We illustrate with examples .
--- Patients with a , No, set Intercept operation .
let obj = {
get id() {
console.log('o', this);
},
fn() {
console.log('o', this);
}
};
let objProxy = new Proxy(obj, {});
objProxy.id; // Print out objProxy .
objProxy.fn(); // Print out objProxy .
--- Example 2 , Yes set Intercept operation . Actually used target[attr] Get attribute value .
let obj = {
get id() {
console.log('o', this);
},
fn() {
console.log('o', this);
}
};
let objProxy = new Proxy(obj, {
get(target, attr) {
console.log('p', this);
return target[attr];
}
});
objProxy.id;
// Print out the configuration object and obj.
// Because it's actually through the proxy object, that is target Access to the id It's worth it .
objProxy.fn();
// Print out the configuration object and objProxy.
// The method can be transformed into (objProxy.fn).call(objProxy).
// Although the method is also through target Visited , But for the method , Environment variables are determined from the beginning .
The prototype is a proxy If the prototype of the object is a proxy , When the operation reaches the prototype , It's actually a proxy object that operates on the prototype . At this time , Its behavior is consistent with that of normal agents .
let obj = Object.create(new Proxy({}, {
get(target, attr) {
console.log('In proxy.');
return Reflect.get(target, attr);
}
}));
obj.name; // Print out In proxy. .
// When the corresponding property cannot be found on the instance , It's on the prototype , And then they were intercepted .
1.3 Agent category
Here's just a list of key points , For details, please see manual ( Standards and behavior are changing ).
get Block the read operation of property , Including array values .
set Block the assignment of properties , Including array assignment . In strict mode , Must return to be converted to true Value . In strict mode , If the proxy object has some restrictions ( Properties are not writable, etc ), An error will be reported when the corresponding interception operation is executed .
apply Intercept function calls 、call and apply operation .
has Intercept to determine whether the object has a certain property . Only right in and Reflect.has() Effective method ,for in It belongs to the traversal series .
construct Intercept new command , An object must be returned .
deleteProperty Intercept delete Attribute operation . In strict mode , Must return to be converted to true Value . In strict mode , If the proxy object has some restrictions ( Properties are not writable, etc ), An error will be reported when the corresponding interception operation is executed .
defineProperty Intercept Object.defineProperty(), Don't intercept defineProperties. In strict mode , If the proxy object has some restrictions ( Properties are not configurable, etc ), An error will be reported when the corresponding interception operation is executed .
getOwnPropertyDescriptor Intercept Object.getOwnPropertyDescriptor(), Don't intercept getOwnPropertyDescriptors. Must return an object or undefined, That is to return the same return value as the original method , Otherwise, the report will be wrong .
getPrototypeOf Intercept to get the object prototype , Must return an object or null. If the object is not extensible , Must return the real prototype object . Direct access __proto__, All kinds of methods and so on will trigger interception .
setPrototypeOf Intercept Object.setPrototypeOf() Method .
isExtensible Intercept Object.isExtensible() operation . The return value must be the same as isExtensible Attributes are consistent , Otherwise, an error will be thrown .
preventExtensions Intercept Object.preventExtensions(), The return value is automatically converted to a Boolean value .
ownKeys Intercept the traversal operation of the object's own properties . such as keys(),getOwnPropertyNames(),getOwnPropertySymbols() wait . The return value must be an array , Items can only be strings or Symbol, Otherwise, the report will be wrong . The return value is filtered according to the requirements of the calling method , such as Object.keys() There won't be symbole. If the target object itself contains non configurable properties , The property must be returned , Otherwise, the report will be wrong . If the target object is not extensible , The return value must contain all properties of the original object , And can't contain extra properties , Otherwise, the report will be wrong .
1.4 Proxy.revocable
This static method is also used to generate , But it also returns a method to recycle the agent . Use scenarios : Direct access to the target object is not allowed , Must be accessed through a proxy . And once the visit is over , Take back the agency , Not allowed to visit again .
let {proxy, revoke} = Proxy.revocable(obj, {});
revoke();
In this case, its internal attribute value [[IsRevoked]] by true, The agent can no longer be manipulated , Otherwise, the report will be wrong .
2 Reflect
2.1 effect
The ultimate goal is to be the host object of the internal methods of the language . for instance defineProperty, getPrototypeOf, preventExtensions It's obviously internal , It should not be hung on Object Next .
Provides the corresponding function to replace the imperative operation . Use Reflect.has(obj, attr) replace in operation . Use Reflect.deleteProperty(obj, attr) replace delete operation .
Make the behavior of function more perfect and strict . When properties cannot be defined ,Reflect.defineProperty return false Instead of throwing errors . When a parameter of type object is required to be non object , It will report an error directly instead of calling Object() To convert .
And Porxy Interceptable methods correspond to , Convenient when implementing custom behavior , Call directly to complete the default behavior .
2.2 Static methods
Here's just a list of key points , For details, please see manual .
Reflect.get Reflect.get(obj, attr, receiver) Return property value , No return undefined. receiver It's settings getter and setter Inside this Point to , The default point to obj.
Reflect.set Reflect.set(obj, attr, value, receiver) Setting property values , Returns a Boolean value . Be careful : When the attribute is not getter when , Pass in receiver Equivalent to setting receiver Property values on the object .
Reflect.has Reflect.has(obj, attr) equivalent attr in obj.
Reflect.deleteProperty Reflect.deleteProperty(obj, attr) equivalent delete obj[attr].
Reflect.construct Reflect.construct(func, args) args Equivalent to the use of apply The parameter array passed in by the method . Provides no use of new To call the constructor method , equivalent new func(...args).
Reflect.getPrototypeOf Function and parameter are equivalent Object.getPrototypeOf(obj).
Reflect.setPrototypeOf Function and parameter are equivalent Object.setPrototypeOf(obj, newProto).
Reflect.apply Function and parameter are equivalent Function.prototype.apply.call(func, thisArg, args).
Reflect.defineProperty Function and parameter are equivalent Object.defineProperty(obj, attr, descriptor).
Reflect.getOwnPropertyDescriptor Function and parameter are equivalent Object.getOwnPropertyDescriptor(obj, attr).
Reflect.isExtensible Reflect.isExtensible(obj) Returns a Boolean value , Indicates whether the current object is extensible .
Reflect.preventExtensions Reflect.preventExtensions(obj) Set the object to be non extensible , Returns a Boolean value .
Reflect.ownKeys Reflect.ownKeys(obj) Returns all properties of the object itself . Equate to Object.getOwnPropertyNames And Object.getOwnPropertySymbols The sum of the .
Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .
版权声明
本文为[:::::::]所创,转载请带上原文链接,感谢
边栏推荐
- Jmeter——ForEach Controller&Loop Controller
- 在大规模 Kubernetes 集群上实现高 SLO 的方法
- 技術總監,送給剛畢業的程式設計師們一句話——做好小事,才能成就大事
- Pycharm快捷键 自定义功能形式
- Flink的DataSource三部曲之二:内置connector
- How to select the evaluation index of classification model
- In depth understanding of the construction of Intelligent Recommendation System
- OPTIMIZER_ Trace details
- Installing the consult cluster
- Basic principle and application of iptables
猜你喜欢

加速「全民直播」洪流,如何攻克延时、卡顿、高并发难题?

(1) ASP.NET Introduction to core3.1 Ocelot

Character string and memory operation function in C language

How long does it take you to work out an object-oriented programming interview question from Ali school?

快快使用ModelArts,零基础小白也能玩转AI!

数字城市响应相关国家政策大力发展数字孪生平台的建设

Kitty中的动态线程池支持Nacos,Apollo多配置中心了

制造和新的自动化技术是什么?

谁说Cat不能做链路跟踪的,给我站出来

“颜值经济”的野望:华熙生物净利率六连降,收购案遭上交所问询
随机推荐
[C#] (原創)一步一步教你自定義控制元件——04,ProgressBar(進度條)
PHPSHE 短信插件说明
Real time data synchronization scheme based on Flink SQL CDC
快快使用ModelArts,零基礎小白也能玩轉AI!
Wiremock: a powerful tool for API testing
Python自动化测试学习哪些知识?
Don't go! Here is a note: picture and text to explain AQS, let's have a look at the source code of AQS (long text)
Swagger 3.0 天天刷屏,真的香嗎?
3分钟读懂Wi-Fi 6于Wi-Fi 5的优势
Microservices: how to solve the problem of link tracing
2018个人年度工作总结与2019工作计划(互联网)
Kitty中的动态线程池支持Nacos,Apollo多配置中心了
2018中国云厂商TOP5:阿里云、腾讯云、AWS、电信、联通 ...
遞迴思想的巧妙理解
IPFS/Filecoin合法性:保护个人隐私不被泄露
【快速因數分解】Pollard's Rho 演算法
向北京集结!OpenI/O 2020启智开发者大会进入倒计时
iptables基礎原理和使用簡介
《Google軟體測試之道》 第一章google軟體測試介紹
Network security engineer Demo: the original * * is to get your computer administrator rights! 【***】