声明方式:
- ES3: var
- ES6: const let
- const let出现的历史原因:ES6把OOP加装在JS过程中的副产品
四种变量声明方式:
-
var ES3 不推荐
-
implicit 暗示全局变量 ES3 不推荐
-
const ES6 推荐
-
let ES6 推荐
Q:这个implicit声明方式是什么样子的;
A:a = 1;比如这样;它会把这样声明的所有变量加到全局对象属性中去
Q:这四种变量方式有什么区别呢?为什么推荐const let;不推荐其他声明方式呢?
A:
-
变量初始化不同:let, var无需手动初始化,浏览器引擎等js底层会自动初始化为undefined(value)(如当前变量没有进行手动初始化变量时);而const和implicit必须手动初始化
-
那既然let和var都不用手动初始化,那它们有什么不同点吗?
-
初始化时机不一样
-
const和implicit呢?
-
const是js故意将其设为禁止手动不初始化的,而implicit纯纯是因为不初始化压根不会加到window/globalThis中,意思是get 变量而不是声明变量(error: uncaught reference)
-
var, implicit可以重复声明一个变量(JS bug), const, let 不行
-
var有变量提升,其他的没有(包括implicit)
-
什么是变量提升?
-
先访问变量再声明变量
-
出现原因:预编译
-
【预编译】找var -> xxx(变量)
-
【预编译】将xxx放入容器{xxx}
-
【预编译】自动初始化xxx = undefined
-
【执行期】再按照写的顺序一一执行
-
let有变量提升吗?没有;
-
let不经过预编译吗?
-
不是
-
【预编译】找let -> (变量xxx)
-
【预编译】将xxx放入容器{xxx}
-
(没有初始化步骤)
-
【执行期】再按照写的顺序一一执行
-
证据:先访问变量再用let声明会报无初始化错误,而不是未定义错误(暂时性死区)
-
implicit, var会把变量加到全局对象属性中去,(implicit没变量提升)
-
作用域不同:let const有块级作用域
-
不推荐原因:
-
var能重复声明
-
变量提升,预编译时会初始化undefined,会出现与开发人员预期不符的结果
-
implicit会被添加到全局对象的属性中去,会造成与预期不符的结果
作用域扫盲:
作用域:变量可被访问的范围
-
全局作用域
-
一个html所有的脚本script共享一个全局作用域
-
声明在ge中的变量,系统会在window, globalThis对象中创建相应属性
-
之所以可以直接访问变量而不用window.xxx访问是因为全局作用域属性对所有作用域可见
-
函数作用域
-
函数体(function body)内作用域
-
块级作用域
-
ES5之前没有块级作用域,想限制变量作用域就用函数解决
-
什么是块(block):{}包裹内容 (但const obj = {test: 1}显然只是一个对象,不是块,更没有作用域)
Tricks:
单一变量声明方式:
例:
var a = 1,
b = 2;
代码规范:
分号加不加?
- fact:js引擎自动加分号的
- 全篇代码保持一致性:要加都加,不加都不加
- 立即执行函数要在前面加分号
- 语句后不加分号