这里是我学习中注意到的一些问题
- 临时死区:暂时性死区:在代码块内,使用let和const命令声明变量之前,该变量都是不可用的,语法上被称为暂时性死区。 相关:
-
let 和const 是使用块级作用域,而var 是使用函数作用域
-
let 和 const 声明之前访问对应的变量和常量,会抛出ReferenceError错误,但在var 声明之前就访问对应的变量,会得到undefined
-
形参和ES6中的
let和const声明一样,具有作用域,并且根据参数的声明顺序,存在暂时性死区。``` function hd(a = b, b = 3) {} hd(); //Cannot access 'b' before initialization //报错 function hd(a = 2, b = a) {} //正确 hd(); ```
暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
-
污染全局: 定义变量要用var声明 , 不然如果他是本来是局部变量 , 但他却不起作用 , 应为这个原因才有了严格模式 , 要求必须声明变量
-
如果不是在函数中var不能生成块级作用域 例如:
在这里块级只是大括号内的为块级作用域
var i = 100;
for (var i = 0; i < 10; i++) {
console.log(i);
}
console.log(i); //输出i变成了10
所以说var没有块级作用域
let i = 100;
for (let i = 0; i < 6; i++) {
console.log(i);
}
console.log(i); // 这样用let就有了块级作用域 整个循环都是一个块
- let和const也不可以重复声明同名的变量 , 避免像var同名的变量不提示发生冲突
共同点:
var/let/const共同点是全局作用域中定义的变量,可以在函数中使用
临时死区(暂时性死区 TDZ):
TDZ 又称暂时性死区,指变量在作用域内已经存在,但必须在let/const声明后才可以使用。
TDZ可以让程序保持先声明后使用的习惯,让程序更稳定。
变量要先声明后使用 建议使用let/const 而少使用var 使用let/const 声明的变量在声明前存在临时性死区(TDZ)使用会发生错误 在代码块内,使用let和const命令声明变量之前,该变量都是不可用的,语法上被称为暂时性死区。
console.log(x); // Cannot access 'x' before initialization
let x = 1;
var
使用 var 声明的变量存在于最近的函数或全局作用域中,没有块级作用域的机制。 没有块作用域很容易污染全局,下面函数中的变量污染了全局环境
function run() {
web = "houdunren";
}
run();
console.log(web); //houdunren
没有块作用作用域时var也会污染全局
全局污染就是下面for中的i,会影响外部声明的i
for (var i = 0; i < 10; i++) {
console.log(i);
}
console.log(i);
使用let有块作用域时则不会
let i = 100;
for (let i = 0; i < 6; i++) {
console.log(i);
}
console.log(i);
下例中体验到 var 没有块作用域概念, do/while 定义的变量可以在块外部访问到
var num = 0;
function show() {
var step = 10;
do {
var res = 0;
console.log(num = step++);
res = num;
} while (step < 20);
console.log(`结果是${res}`);
}
show();
var 全局声明的变量也存在于 window对象中
var hd = "houdunren";
console.log(window.hd); //houdunren
以往没有块任用时使用立即执行函数模拟块作用域
(function() {
var $ = this.$ = {};
$.web = "后盾人";
}.bind(window)());
console.log($.web);
有了块作用域后实现就变得简单多了
块级作用域就是大括号的为一个块
{
let $ = (window.$ = {});
$.web = "后盾人";
}
console.log($.web);
let
与 var 声明的区别是 let/const 拥有块作用域,下面代码演示了块外部是无法访问到let声明的变量。
建议将let在代码块前声明 用逗号分隔定义多个 let存在块作用域特性,变量只在块域中有效
if (true) {
let web = 'hdcms',url = 'houdunren.com';
console.log(web); //hdcms
}
console.log(web); //web is not defined
块内部是可以访问到上层作用域的变量
if (true) {
let user = "向军大叔";
(function() {
if (true) {
console.log(`这是块内访问:${user}`);
}
})();
}
console.log(user);
每一层都是独立作用域,里层作用域可以声明外层作用域同名变量,但不会改变外层变量
function run() {
hd = "houdunren";
if (true) {
let hd = "hdcms";
console.log(hd); //hdcms
}
console.log(hd); //houdunren
}
run();
const
使用 const 用来声明常量,这与其他语言差别不大,比如可以用来声明后台接口的URI地址。
常量名建议全部大写 只能声明一次变量 声明时必须同时赋值 不允许再次全新赋值 可以修改引用类型变量的值 拥有块、函数、全局作用域 常量不允许全新赋值举例
try {
const URL = "https://www.houdunren.com";
URL = "https://www.hdcms.com"; //产生错误
} catch (error) {
throw new Error(error);
}
改变常量的引用类型值
const INFO = {
url: 'https://www.houdunren.com',
port: '8080'
};
INFO.port = '443';
console.log(INFO);