JS函数简单的底层原理
(个人理解):
1. 已经使用var申明且赋值,若再次申明,则第二次申明(不赋值)无效。
2.在同一个作用域下,只要是发生了同名,且变量完成赋值,后者会覆盖前者。存在两个相同的函数名的函数,后一个函数会覆盖前一个函数。用var声明的变量(需要赋值)亦是如此。
3.js代码执行机制从上至下, 作用域查找机制 从里到外,就近原则。
4.在预解析阶段,会给var申明的变量进行变量提升,和函数申明方式申明的函数进行函数提升(其他方式申明或创建的函数不具有函数提升),分配内存空间(堆内存或者是栈内容空间).这里注意this的指向问题.
5.在函数中, 如果有 不用 任何声明符号声明的变量直接使用(如: a = 10 ),并且在该函数中没有声明该变量, 且全局函数中也没有声明该变量, a =10, 会被隐式声明 为var a = 10,改变量会被提升为全局变量.
1. 已经使用var申明且赋值,若再次申明,则第二次申明(不赋值)无效。
就是说在同一作用域下,重复申明的变量(同名),但不赋值的变量,后一次的声明的变量无效,不会对原有的变量和函数产生影响。
var a = 1 ;
var a;
cosnoel.log(a) //1
function a(){
console.log('p');
};
var a;
a();// p
2.在同一个作用域下,只要是发生了同名,且变量完成赋值,后者会覆盖前者。存在两个相同的函数名的函数,后一个函数会覆盖前一个函数。用var声明的变量(需要赋值)亦是如此。
var a = 1;
var a = 2;
console.log(a);//2
function a(){ //
console.log(22)
};
var a = 10;
a();// a is not a function
//这里进行了变量提升和函数提升,函数提升优先级高于变量提升,然后变量a又进行了赋值,且函数名和变量名相同就覆盖了函数a了
//相同函数名,后一个函数覆盖前一个函数。
function a(){
console.log(99);
};
function a(){
console.log(6666)
};
a();// 6666
3.在函数中, 如果有 不用 任何声明符号声明的变量直接使用(如: a = 10 ),并且在该函数中没有声明该变量, 且全局函数中也没有声明该变量, a =10, 会被隐式声明 为var a = 10,改变量会被提升为全局变量.
function b() {
a = 10;
return;
};
var a = 1;
b();
console.log(a); // 10
5.在预解析阶段,会给var申明的变量,和函数声明方式声明的函数,分配内存空间(堆内存或者是栈内容空间).这里注意this的指向问题.
在JS中有一种预解析机制,就是在解析时会将函数申明和变量申明提前解析。
在预解析阶段会进行变量和函数提升,提升到该作用域的最顶部。在这里很明显进行了函数提升,和变量提升,且函数优先提升到本作用域的最顶部,其次是进行变量提升。
function b() {
a();
var a = 10;
console.log(a); // 10
return;
function a() {
console.log(a); // 这里打印函数体 ,
};
};
b();
变量和函数提升后
function b() {
function a() {
console.log(a); // 这里打印函数体 function(){console.log(a)}
};
var a ;
a();
a = 10;
console.log(a); // 10
return;
};
b();
在预解析时,同步在内存堆栈内存中开辟内存空间,进行存储,看下面的详细分解