JavaScript高级

155 阅读3分钟

变量提升:

当浏览器开辟出供代码执行的栈内存后,代码并没有自上而下立即执行,而是继续做了一些事情,把当前作用域所有带var/function关键字的进行提前的声明和定义=>变量提升机制

  • 带var的只是提前申明(declare)"var a";如果只声明没有赋值,默认值是underfined;
  • 带function的不仅申明,而且还定义了(defined)"a=13"定义其实就是赋值,准确来说就是让变量和某个值进行关联;
  • 变量和基本数据类型存在栈中
  • 函数和对象存在堆中
  1. 开辟一个新的内存(堆内存16进制的内存地址)
  2. 把内容存储在堆内存中(对象存储的是键值对,函数存储的是函数体中的代码字符串)
  3. 让变量和地址关联在一起

带var和不带var的区别:

var和let,const区别

1.let和const不存在变量提升机制

创建变量的六种方式中:var/function有变量提升.而let/const/calss/import都不存在这个机制

2.var允许重复声明,而let是不允许的

在相同的作用域中(或执行上下文)

  • 如果使用var/function关键词声明变量并且重复声明,是不会有影响我的(声明第一次之后,只有在遇到就不在重复声明了)
  • 但是使用let/const就不行。浏览器会检验当前作用域是否已经存在这个变量了,如果已经存在了,则再次基于let等重新声明就会报错

在浏览器开始栈内存供代码自上而下执行之前,不仅有变量提升的操作,还有很多其他操作=>"词法解析"或者"词法检测;就是检查当前即将要执行的代码是否会出现语法错误,如果出现错误,代码将不会再执行(第一次都不会执行)

SyntaxError(词法解析错误)对象代表尝试解析语法上不合法的代码的错误当Javascript语言解析代码时,Javascript引擎发现了不符合语法规范的tokens或token顺序时抛出SyntaxError

 ReferenceError(引用错误当你尝试引用一个未被定义的变量时,将会抛出一个 ReferenceError

TypeError(类型错误) 对象用来表示值的类型非预期类型时发生的错误

变量提升中关于判断条件的处理

变量提升(不管条件是否成立都要进行变量提升

console.log(a)
if(!'a' in window){
    var a=1;
}
console.log(a)

但是做函数的有特殊性,在老版本浏览器中,确实不论条件是否成立,函数也是提前声明或者定义的,但是新版本浏览器中,为了兼容es6严谨的语法规范,条件中的函数在变量提升阶段只能提前声明,不能提前定义

console.log(fn) =>undedfined
if('fn' in window){
    fn(); //=>哈哈哈
//条件成立,进来后的第一件事就是给FN赋值,然后在代码执行     function fn(){
        console.log('哈哈哈')
    }
}
fn() => '哈哈哈'