Talking about the WITH keyword in JS, the first impression of many small partners may be that the WITH keyword is used to change the scope, and then the most critical point is not recommended using the WITH keyword. When you hear that the WITH keyword is not recommended, many of us will ignore the WITH keyword and think it is OK to leave it alone. But sometimes, when we look at some code or interview questions, there are related questions about the WITH keyword, many pits are not contacted by you, so it is necessary to say with this keyword.
Basic DescriptionIn JS advanced programming, this describes the WITH keyword: the action of the WITH statement is to set the scope of the code to a specific scope, the basic syntax is as follows: with (expression) statement; The WITH keyword is used to simplify the work of accessing the same object multiple times, such as the following example: var qs = location.search.substring (1); var hostName = Location.hostname; var url = location.href; These lines of code are access to the properties in the Location object, and if you use the WITH keyword, you can simplify the code as follows: with (location) {var qs = search.substring (1); var hostName = HostName; var url = href; In this code, the location object is associated with the WITH statement, which means that within the with code block, each variable is first considered a local variable, if the local variable has the same name as a property of the Location object. The local variable points to the Location object property. Note: You cannot use the WITH statement in strict mode.
with the disadvantages of the keywordIn the previous basic description, we can see that one of the functions of with is to simplify the code. But why not recommend it? Below we say with disadvantage: 1, performance Problem 2, semantics unknown, debugging difficulty
Performance Issues To start with the performance issue, about using the WITH keyword performance problem, first we take a look at two pieces of code: The first code is not using the WITH keyword: function func () { &NB Sp Console.time ("func"); var obj = { A: [1, 2, 3] }; for (var i = 0; i < 100000; i++) { var v = obj.a[0] ; &NBSP} console.timeend ("func");//0.847ms } func (); The second section of code uses the WITH keyword: function Funcwith () { Console.time ("FUNCWI Th "); var obj = { A: [1, 2, 3] }; var obj2 = {x:2}; with (OBJ2) { Console.log (x); for (var i = 0; i < 100000; i++) { var v = obj.a[0]; } console.timeend ("Funcwith");//84.808ms funcwith (); After using the WITH keyword, the performance of the code has been greatly reduced. The WITH statement of the second Code acts on the Obj2 object, and then the With block accesses the Obj object. One idea is that when you use the WITH keyword to access a variable in a with block, you first find the attribute on the obj2 that is named obj, and if not, the next step, which results in a decrease in performance. But is this really the reason for the real decline in program performance? We modify the second paragraph of code, and modify the following: function Funcwith () { console.time ("Funcwith"); var obj = { A: [1, 2, 3] }; with (obj) { for (var i = 0; i < 100000; i++) { ; var v = a[0]; } &NBSP ; &NBSP} console.timeend ("Funcwith");//88.260ms funcwith (); &nBsp This code uses the WITH statement on the Obj object, and then directly using a to access the A attribute of obj, which, according to the previous view, can be found on obj at one time, but why the code performance is still reduced. The real reason: After using the WITH keyword, the JS engine is unable to optimize the code. JS engine before code execution has a compile phase, when not using the WITH keyword, the JS engine knows that a is a property on obj, it can statically analyze the code to enhance the resolution of identifiers, thus optimizing the code, so the efficiency of code execution increased. Using the WITH keyword, the JS engine cannot tell whether a variable is a local variable or an attribute of obj, so the JS engine, after encountering the WITH keyword, discards the optimization of the code, so the execution efficiency is reduced. The effect of using the WITH keyword on performance is also the JS compression tool, which cannot compress this code, which is also a factor affecting performance.
ambiguous semantics, difficult to debugIn addition to the performance of the problem, with the existence of a shortcoming of the semantic ambiguity, difficult to debug, is caused by the code is not easy to read, and may cause potential bugs. function foo (obj) {with (obj) {a = 2; } var O1 = {A:3}; var O2 = {B:3}; Foo (O1); Console.log (o1.a); 2 foo (O2); Console.log (o2.a); Undefined Console.log (a); 2 This code is easy to understand, within the Foo function, using the WITH keyword to access the incoming Obj object, and then modify the A property. This is no problem when the O1 object is passed in because the O1 object has a property. When the O2 object is passed in, when the A property is modified, the modified a property becomes a global variable because the O2 object does not have a property. This creates a potential bug.
Extension AnalysisAs I have said before, I believe you have understood why the WITH keyword and possible problems are not recommended. Let's take a look at some of the more complex situations, and look at the following code: var obj = {x:10, foo:function () {with (this) { var x = 20; var y = 30; Console.log (y);//30}}; Obj.foo (); Console.log (obj.x);//20 console.log (OBJ.Y)//undefined in this code, respectively, output 30,20,undefined. The knowledge points involved are also more: With the keyword, this keyword, variable elevation and so on, we come to one by one to explain.
1. This keywordThe article on this keyword is quite a bit more than Google, and here we will just remember one point: this keyword always points to the object that calls the function. Here, in the Foo function, this refers to the Obj object. Therefore, in the WITH (this) statement block, you can access the X property of obj directly through the x variable.
2. Variable elevation JS in the variable ascension is also a frequent problem, we can simply understand that in JS, the variable declaration will be promoted to the top of the function, although sometimes it is declared later. So the above code can be resolved as follows: var obj = { x:10, foo:function () { VAR x;//declaration local variable x VAR y;//declaration local variable y with (obj) { x = 20;//access variable x, found x on obj, modified to - y = 30;//access variable y, unable to find Y on obj, further lookup, find local variable y, modified to , , , Console.log (y);//30//direct output local variable y, &NBSP; obj.foo (); console.log (obj.x);//20,obj.x has been modified to console.log (OBJ.Y);//undefined,obj does not exist Y property, undefined In the comments above, explained the code execution process, I believe that we have understood why the source 30,20,undefined reason. Interested students can take a look at the following code: ({ x:10, foo:function () { &NBSP ; FunctioN Bar () { Console.log (x); &NBSP ; Console.log (y); Console.log (this.x); { with (this) { &NB Sp var x = 20; var y = 30; bar.call (this); } } . foo (); What does this piece of code output? Why, then?