There are two ways to define a function in JavaScript:
function ftn(){} // 第一种 var ftn = function(){} // 第二种
Some people say that these two ways of writing are completely equivalent. However, before parsing, the former way of writing will be automatically promoted to the head of the code by the parser, which violates the principle of defining functions first and then using them. Therefore, it is recommended to use the latter way of writing when defining functions.
After reading this sentence, my first feeling is that the two are completely the same when used, but there are differences in analysis. But his explanation that "the former way of writing will be automatically promoted to the head of the code by the parser" confused me.
So I had the following first test:
<script type="text/javascript"> function ftn() { alert('old'); } var b = ftn; function ftn() { b(); alert('new'); } ftn();//浏览器报内存溢出 </script>
Then I did the second test:
<script type="text/javascript"> var ftn = function() { alert('old'); } var b = ftn; var ftn = function() { b(); alert('new'); } ftn();//old,new依次弹出 </script>
The explanation on the Internet is: the first way, the Function of ftn was not redefined at the beginning. executed itself inside. The second way, ftn=function() here is not executed into the code in Function. ftn has been redefined, so the redefinition here is valid.
If it’s not clear, then I did another test as follows:
<script type="text/javascript"> function ftn() { alert('old'); } var b = ftn; function ftn() { b(); alert('new'); } alert(b);//结果是重新定义的ftn内容 </script>
The test results found that after redefining ftn, the content of b will also change. Next, I did two more tests:
<script type="text/javascript"> var ftn = function() { alert('old'); } var b = ftn; var ftn = function() { b(); alert('new'); } alert(b);//结果是老的ftn内容 </script>
This is very interesting. In JavaScript, except for basic data types, other types are objects. The object is stored in the heap, and its alias is the address stored in the stack. One test can obviously be understood using this principle. So why did the previous test b change with the redefinition of ftn?
I have a new explanation, I don’t know if it’s right or not. It will be mentioned in all JavaScript books that there is no method overloading in JavaScript. A function with the same name defined later will overwrite the previous function, var b = ftn; This sentence points the references of b and ftn to the memory in the same heap. After redefining function ftn(){}, the new function object overwrites the old object, but the heap address space referenced by b and ftn remains unchanged. , if this is the case, then this way of writing is reasonable:
<script type="text/javascript"> function ftn() { alert('old'); } var b = ftn; var ftn = function() { b(); alert('new'); } alert(b);//老的ftn alert(ftn);//新的ftn ftn();//old ,new </script>
In this way, the address of the new ftn in the stack has changed, pointing to the definition of the new function object, and the original function has not been overwritten and is still saved, so b It is still the address referenced by the old ftn.
I just wrote an article about understanding the functions in JavaScript. When I look back and think about the content of my article, I feel that my understanding of the test results is still a bit problematic. In fact, understanding still needs to be based on the principles of compilation and operation. . JavaScript compiles the code when the code is executed, so the type defined by our var can be variable. The objects we encapsulate often add properties and methods, so we can understand the problems caused by my title in this way. The general language of javascript, such as definition A variable var obj = new Object() only performs a very initial process, which is called precompilation in JavaScript. This precompilation capability is very weak. It is so weak that you can change it at will without affecting the running of the program. When the object is called, the JavaScript interpreter will compile and then run the code. This is very different from Java. Java compiles the code first and then runs it when it is called. This is the characteristic of script languages, so most script languages Not fast. But when you define a function like this: fonction ftn(){}, the code is compiled, that is, executed. This writing method is very similar to the definition of a java function. This is my new interpretation, and I think this explanation is more reasonable.
The "compilation" of JavaScript only checks whether there are code errors and does not run the code. You can try writing anything in the function to test it. Preloading, function first, then var. In the above code, only demo1 and demo3 are affected. The source code order of demo1 and demo3 is function - var - function. The order after applying preloading is: function - function - var. The complete code after preloading:
<script type="text/javascript"> //demo1 function ftn() { alert('old'); } function ftn() { b(); alert('new'); } var b = ftn; ftn();//浏览器报内存溢出 </script>
<script type="text/javascript"> //demo3 function ftn() { alert('old'); } function ftn() { b(); alert('new'); } var b = ftn; alert(b);//结果是重新定义的ftn内容 </script>
preloading That's about it.