Javascript-reading study notes from Uncle TOM's blog
Part1 Partition ---------------------------------------------------------------------------------------------------------
1. Preface
In the past two days, I took a look at the basic part of Uncle TOM's deep understanding of the js series. According to my actual situation, I made Reading Notes and recorded some of the problems that are easy to understand. Write an article for your sharing.
2. "Real-Time query" of HTMLCollection"
var divs = document.getElementsByTagName(div), i;for (i = 0; i < divs.length; i++) { //……}
In the above Code, performance problems may occur. The problem is that divs is an HTMLCollection object, which will be analyzed and computed again from the dom every time data is obtained. Therefore, in the for loop, each cycle executes a divs. length calculation, and the browser re-traverses the dom tree.
Therefore, the length attribute value of divs should be calculated early out of the loop. As follows:
var divs = document.getElementsByTagName(div), i, length = divs.length;for (i = 0; i < length; i++) { //……}3. for... in..., pay attention to hasOwnProperty verification.
Var obj = {a: 10, B: 20}; // note the word code Object. prototype. c = 30; var item; for (item in obj) {console. log (item );}
In the above Code, pay attention to the sentence marked in the middle. The addition and absence of this code will affect the following for... in... loop. When "c" is added, "c" is output without adding ". The principle is very simple. for... in... loop can not only traverse the properties of the obj object itself, but also the properties in the obj prototype.
To shield the attributes in the prototype, use the hasOwnProperty function as follows:
for (item in obj) { if (obj.hasOwnProperty(item)) { //if (Object.prototype.hasOwnProperty.call(obj, item)) { console.log(item); } }
The two if statements can be used, and the results are the same. The first code is highly readable, and the second code is highly efficient. We recommend that you use the first one unless otherwise specified.
4. Old Problem: Closure of function/event generation in a loop
Var events = [], I = 0; // create a function for (; I <10; I ++) {events [I] = function () {console. log (I) ;};}// verification result for (I = 0; I <events. length; I ++) {events [0] ();}
Look at the above code first. People with js development experience are certainly familiar with it, but some people know it and some people do not know it. Following the code above, the events array is traversed cyclically and the functions in the array elements are executed. What numbers will these 10 functions print? The answer is: "10" is output ". The reasons are as follows:
When each function is generated/created, the system assigns a variable environment to it, which also includes closure data. However, when multiple environments share the data of a closureReferenceThis is the focus. Reference, not copy. If this public data is changed, the changed data is obtained in these public environments.
Therefore, when creating the first function, I = 0. The value of I in the closure referenced by the first function is 0. When the second function is created, I = 1. This is the value of I in the application closure of the first and second functions, both of which are 1. And so on, until the tenth function is created, I = 9; but in the last step of the for loop, I ++ is executed, So I = 10.
Do you understand?
If you want to change this problem and want each function to output different values, you need to avoid every function having to share a closure-so that each function can use independent closure data without sharing. Just change the part of the for Loop function creation:
// Create a function cyclically for (; I <10; I ++) {events [I] = (function (index) {return function (index) {console. log (index) ;}}) (I );}
In this case, I is used as a parameter to pass in the anonymous Automatic execution function and assign the value to the index parameter. The variable environment of this anonymous function saves the index and does not change with I. This is the key point.
Welcome to Weibo: weibo.com/madai01
Part2 Partition -----------------------------------------------------------------------------------------------------------
1. Preface
Yesterday I wrote "js notes (11)-reading the study notes of Uncle TOM's blog part1", which records several questions. The focus of part1 is the problem of creating a function in the last loop, that is, the issue that multiple subfunctions share a closure data. If you are interested, you can try again.
I will continue to write the remaining questions today.
2. Scope chain
Js learners, even those who are beginners, know the prototype chain, but the scope chain may not have heard of it. Most people know or have heard of "closures", but many may not know that closures are actually highly related to the scope chain. If you do not understand a closure from the scope chain, you can only understand the closure.
I also learned about the scope chain from Uncle TOM's blogs. I have read many books before and have not clearly understood the concept of the scope chain. In fact, the scope chain is easy to understand. The Code is as follows:
var x = 10; function fn() { var y = 20; return function () { var z = 30 console.log(x + y + z); } }
In the code above, if you want to print the value of x + y + z, you must traverse the context or scope of the three layers, which is similar to the structure of the prototype chain. However, it will take a lot of content to elaborate on the future together with the illustrated closure.
I will not go into it here. I will have the opportunity to introduce it in detail in the future.
3. Two-Dimensional link search
As mentioned above, variables are searched up through scope training. In the process of searching for variables, two-dimensional chain lookup-scope chain + prototype chain is used ". See the following code:
Object.prototype.x = 10; function fn() { var y = 20; return function () { var z = 30 console.log(x + y + z); } }
This code is similar to the code that demonstrates the scope chain in the article, but it uses the Object. prototype. x = 10; such a sentence, it shows the role of the prototype chain in it.
Therefore, when searching for variable values, both the prototype chain and the scope chain are taken into account, that is, "two-dimensional chain search ".
4. Independent scopes can only be created through Functions
The next half of this sentence is: it cannot be created through statement blocks such as if/. You may know the last half of the sentence, but its essence is indeed the first half-the Independent scope can only be created through functions (except for the independent scope, the rest is the global scope ). Since the independent scope can only be created through the function, the free variables in any part of the function are at the function level. Therefore, the following code does not want to appear again:
5. Nature of implicit global variables
var a = 10;b = 20;
The code above seems to be a declaration of two global variables, but according to Uncle TOM, only var can declare a variable, that is, var a = 10; is the real declaration variable.
The next sentence B = 20 is actually equivalent to setting an attribute value of window.
Therefore, the essence of the first sentence is to declare a global variable; the essence of the second sentence is to set a property value of the window.
Of course, the second sentence is not recommended.
6. Different function declarations and function expressions
There are multiple methods for defining functions in js, but let's look at the following code:
Fn (); var fn = function () {// function expression alert (123); // error} // ------ fn (); function fn () {// function declaration alert (123); // 123}
The two function definitions have different results.
I didn't go into detail here, because there are not many cases in this way, so I didn't go into detail, but I just made a mark. If you know anyone, do not explain it.
7. js uses static scopes
As mentioned in part1, when a function is passed in as a parameter and the latter is returned as a value, what is passed together with it is its scope. That is, the closure. See the following code:
Var x = 10; function foo () {alert (x) ;}( function (funarg) {var x = 20; funarg (); // 10, not 20 }) (foo );
Foo is a function that is passed into another function as a parameter and executed together. It is the scope of foo. Foo uses a static scope. The variable x has been assigned a value at the time of transmission and will not be affected by the variable x in other environments.
This principle also applies to functions as return values. As follows:
Function fn () {var x = 10; return function () {alert (x) ;}} var ret = fn (); var x = 20; ret (); // 10, not 20