变量提升(声)
当浏览器开辟出供代码执行的栈内存后,代码并没有自上而下执行,而是继续做了一些事情:把当前作用域中所有带var/function关键字的进行提前声明和定义=>变量提升机制
- 带var的只是提前声明(declare)var a; 如果只声明没有赋值,默认值是undefined
- 带function的不仅声明,而且还定义了(defined)"a=13"定义其实就是赋值,准确来说就是让变量和某个值进行关联(可以不重新声明,但是赋值操作一定是要继续进行的)
函数表达式方式,由于使用var来创建sum,变量提升阶段只会声明变量,不会赋值,所以此时函数在前面执行,函数是没有值的,不能执行(真实项目中这种方式最常用,因为他操作严谨)
全局作用域(栈内存)
1. 变量提升
不管条件是否成立,都要进行变量提升
但是做函数的有特殊性:在老版本浏览器中,确实不论条件是否成立,函数也是提前声明或者定义的,但是新版本浏览器中,为了兼容ES6严谨的语法规范,条件中的函数在变量提升阶段只能提前声明,不能提前定义
2. 代码执行
在JS中上一行代码报错,下面的代码都不会再去执行了
带var和不带var的区别
// =>在全局作用域下的区别
/*
* 不带var的:相当于给全局对象window设置一个属性a
* window.a = 13;
*/
a = 13;
console.log(a);//=>window.a
/*
* 带var的:是在全局作用域下声明了一个变量b(全局变量),但是在全局下声明的变量也同样相当于给window增加了一个对应的属性(只有全局作用域具备这个特点)
*/
var b = 14; //=>创建变量b & 给window设置了属性b
console.log(b);//=>14
console.log(window.b);//=>14
函数执行会形成一个私有作用域 1.变量提升 2.代码执行
let/const和var的区别
- let和const不存在变量提升机制
创建变量的六种方式中:var/function有变量提升,而let/const/class/import都不存在这个机制
- var允许重复声明,而let不允许
在相同的作用域中(或执行上下文中),如果使用var/function关键词和声明变量并且重复声明,是不会有影响的(声明第一次之后,之后再遇到就不再重复声明了);但是let/const就不行,浏览器会校验当前作用域中是否已经存在这个变量了,如果已经存在了,则再次基于let等重新声明就会报错
//=>在浏览器开辟栈内存供代码自上而下执行之前,不仅有变量提升操作,还有很多其他的操作=>“词法解析”或“词法检测”:就是检测当前即将要执行的代码是否会出现“语法错误 SyntaxError”,如果出现错误,代码将不会在执行(第一行都不会执行)
console.log(1); //=>这行代码就已经不会再被执行了
let a = 12;
console.log(a);
let a = 13; //=> 报错
console.log(a);
所谓重复是:不管之前通过什么办法,只要当前栈内存中存在这个变量,我们使用let/const等重复在声明这个变量就是语法错误
console.log(a);
var a = 12;
let a = 13; //=>报错(语法错误)
console.log(a);
自执行函数
前面加 ()、!、~、-、+只有一个目的,让语法符合而已
自执行函数本身不进行变量提升(没名字)
网友评论