前言
记录自己阅读《javascript高级程序设计》的读书笔记。
- var声明的变量可以被提升到函数作用域顶部,let声明的变量无法提升,函数提升只会提升函数声明,而不会提升函数表达式。(注意,变量提升指的是声明被提升,赋值等操作未被提升)
var声明:
function foo() {
console.log(age);
var age = 26;
}
foo();
之所以不会报错,是因为 ECMAScript 运行时把它看成等价于如下代码:
function foo() {
var age;
console.log(age); age = 26;
}
foo();
let声明
if (true) {
let age = 26;
console.log(age);
}
console.log(age);
- var作用范围是函数作用域,let作用范围是块状作用域
- 在函数体内使用var 声明变量,会成为局部变量,该变量在函数退出时被销毁。
function test() {
var message = "hi";
console.log(message);
- 在函数体中去掉var操作符,声明变量会成为全局变量。(注意 虽然可以通过省略 var 操作符定义全局变量,但不推荐这么做。在局部作用域中定义的全局变量很难维护,也会造成困惑)
function test() {
message = "hi";
}
test();
console.log(message);
- var可以重复声明变量,let不可以重复声明变量
function foo() {
var age = 16;
var age = 26;
var age = 36;
console.log(age);
}
foo();
var name;
var name;
let age;
let age;
- const:
const也不允许重复声明 const 声明的限制只适用于它指向的变量的引用。换句话说,如果 const 变量引用的是一个对象, 那么修改这个对象内部的属性并不违反 const 的限制。
const person = {};
person.name = 'Matt';
- let在全局作用域中声明的变量不会成为windows对象属性,var则会
var name = 'Matt';
console.log(window.name);
console.log(window.age);
- for循环中的let声明与var声明
for (var i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
}
for (let i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
}
原因: 1.使用var声明时,所有的迭代变量保存的都是退出循环的值,所以是5,而使用let声明,js引擎后台会为每个迭代循环声明一个新的迭代变量。每个 setTimeout 引用的都是不同的变量实例,所以 console.log 输出的是我们期望的值,也就是循 环执行过程中每个迭代变量的值。 2.setTimeout()属于异步程序,在js事件循环机制中,所有的同步程序都在执行栈中顺序执行。如果异步程序有返回结果,便将异步程序放到任务队列中。当所有的同步程序执行完成后,便将异步程序依次放入执行栈中执行。这也就是为什么var声明输出的结果会是退出循环的值,因为同步程序已经结束,i=5退出循环。
|