with is a grammar that is not recommended, because its role is to change the context, and the context environment has a great impact on the developer.
This week through JavaScript's Forgotten Keyword (with) this article introduces the function of with.
Overview
The following is an example of using with:
with (console) {
log('I dont need the "console." part anymore!');
}
We inject the console
object into the context, and console.log
is registered in this Scope.
Another example:
with (console) {
with (['a', 'b', 'c']) {
log(join('')); // writes "abc" to the console.
}
}
Through nesting, we can additionally inject context. Among them, with (['a', 'b', 'c'])
actually ['a', 'b', 'c']
the return value object of 061109a42c715d into the context, and the array object has a .join
, so you can directly call join('')
output "abc"
.
In order to prevent the result from being so magical, it is recommended to declare the key to be injected in an enumerated way:
with ({ myProperty: 'Hello world!' }) {
console.log(myProperty); // Logs "Hello world!"
}
So why is it not recommended to use with? For example, the following situation:
function getAverage(min, max) {
with (Math) {
return round((min + max) / 2);
}
}
getAverage(1, 5);
The injected context may conflict with the existing context, resulting in the output result of NaN
.
Therefore, with is not recommended in business code, and in fact, with is also forbidden strict mode
intensive reading
Since the context defined by with will be searched first, it is a solution in the front-end sandbox field. The specific approach is:
const sandboxCode = `with(scope) { ${code} }`
new Function('scope', sandboxCode)
In this way, all scope defined objects are restricted. But if you access objects outside the scope, you will still bubble up and search, we can combine with Proxy to limit the scope of the search, so that we can complete a sandbox with acceptable usability.
The second use of with is the front-end template engine.
forEach
and map
in the template engine. These grammars can be injected through with. Of course, not all template engines are implemented in this way. Another solution is to parse the template engine into an AST, and then construct and execute it based on the AST. If this process is put at compile time, then JSX is an example.
Finally, there is a misunderstanding about the with injection context, that is, that the following code only injects the run
attribute:
with ({ run: () => {} }) {
run()
}
In fact, as with the prototype looks at the entire chain, and {}
prototype chain is Object.prototype
, which led to a lot of hanging in unexpected properties.
If you want to mount a pure object, you can use Object.create()
create an object and mount it on with.
Summarize
There are few usage scenarios for with, and it is generally not recommended to use it.
If you have other serious use scenarios with with, you can let me know or give a comment.
The discussion address is: Intensive Reading of "JS with Grammar" · Issue #343 · dt-fe/weekly
If you want to participate in the discussion, please click here , a new theme every week, weekend or Monday. Front-end intensive reading-to help you filter reliable content.
Follow front-end intensive reading WeChat public
<img width=200 src="https://img.alicdn.com/tfs/TB165W0MCzqK1RjSZFLXXcn2XXa-258-258.jpg">
Copyright statement: Freely reprinted-non-commercial-non-derivative-keep the signature ( Creative Commons 3.0 License )
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。