JS学习之路-语法基础(1-变量)

66 阅读3分钟

变量

  • 变量是可以用于保存任何类型的数据。每个变量只不过是一个保存任意值的命名占位符。
var关键字
  • 定义了一个名为message的变量(不初始化的情况下,变量会保存一个undefined
  • 使用var操作符,后跟变量名(即标识符)
var message;
  • 定义了一个名为message并保存字符串hi的变量
  • 定义变量的同时设置它的值
var message = "hi"
var声明作用域
  • 使用var操作符定义的变量会成为包含它的函数的局部变量,也就意味着该变量将在函数退出被销毁
function test() { 
    var message = "hi"; // 局部变量 
} 
test(); 
console.log(message); // 出错!
  • 在函数内定义变量时省略var操作符,可以创建一个全局变量。(不推荐)
  • 在局部作用域中定义的全局变量很难维护,不能一下子断定省略var是不是有意而为之
function test() { 
    message = "hi"; // 全局变量 
} 
test(); 
console.log(message); // "hi"
var声明提升
  • 使用var关键字声明的变量会自动提升到函数作用域顶部提升 hoist),
function foo(){
    console.log(age);
    var age = 26;
}
foo(); //undefined
等价:
function foo(){
    var age;
    console.log(age);
    age = 26;
}
foo(); //undefined
let声明
let与var的区别是
  • let声明的范围是块级作用域(变量的作用域仅限于该块内部);
if (true) { 
    let age = 26; 
    console.log(age); // 26 
} console.log(age); // ReferenceError: age 没有定义
  • let不允许同一块作用域中出现冗余声明;
var name; 
var name; 
let age; 
let age; // SyntaxError;标识符 age 已经声明过了
  • var声明的范围是函数作用域;
if (true) { 
    var name = 'Matt'; 
    console.log(name); // Matt 
} 
console.log(name); // Matt
暂时性死区
  • let声明的变量不会在作用域中被提升
//age不会被提升
console.log(age); // ReferenceError:age 没有定义 
let age = 26;
//等价于
console.log(age); // ReferenceError:age 没有定义 
let age;
age = 26;

// name 会被提升 
console.log(name); // undefined 
var name = 'Matt'; // age 会被提升
//等价于:
var name;
console.log(name); // undefined
name = 'Matt';     // age 会被提升
全局声明
  • 使用let在全局作用域中声明的变量不会成为window对象的属性(var声明的变量则会)
    • let声明仍然是在全局作用域中发生的,相应的变量会在页面的生命周期内存续
let age = 26; 
console.log(window.age); // undefined

var name = 'Matt'; 
console.log(window.name); // 'Matt' 
for循环中的let声明
  • let出现之前,for循环定义的迭代变量会渗透到循环体外部。迭代变量保存的是导致循环退出的值:5
for(var i = 0;i < 5; ++i) {
    //循环逻辑
    setTimeout(()=>console.log(i),,0)
}
//5,5,5,5,5,5
  • 使用let关键字,迭代变量的作用域仅限于for循环内部。JavaScript引擎在后台会为每一个新的迭代变量
for(let i = 0;i < 5; ++i) {
    //循环逻辑
    setTimeout(()=>console.log(i),,0)
}
//0,1,2,3,4
const声明
  • const 的行为与 let 基本相同,唯一一个重要区别是用它声明变量时必须同时初始化变量,且尝试修改const声明的变量会导致运行时错误
const age = 26; 
age = 36; // TypeError: 给常量赋值
  • const 声明的限制只适用于它指向的变量的引用。 比如:如果const变量引用一个对象,那么修改这个对象内部的属性并不违反const的限制
const person = {};
person.name = 'Matt'; //ok
声明风格及最佳实践
  • 不使用var关键字
  • const优先,let次之