• Javascript 变量


    有 3 个关键字可以声明变量: var 、 const 和 let。

    变量可以用于保存任何类型的数据。

    1 var 关键字

    var message; //不初始化的情况下,变量会保存一个特殊值 undefined
    var message = "hi"; // 声明并且初始化变量
    

    1.1 var 声明作用域

    使用 var 操作符定义的变量会成为包含它的函数的局部变量

    function test() {
    	var message = "hi"; // 局部变量
    }
    test();
    console.log(message); // 出错!
    

    在函数内定义变量时省略 var 操作符,可以创建一个全局变量

    function test() {
    	message = "hi"; //  全局变量
    }
    test();
    console.log(message); // "hi"
    

    虽然可以通过省略 var 操作符定义全局变量,但不推荐这么做。在局部作用域中定
    义的全局变量很难维护,在严格模式下,如果像这样给未声明的变量赋值,则会导致抛出 ReferenceError 。

    一次定义多个变量

    var message = "hi",
    	found = false,
    	age = 29;
    

    1.2 声明提升(hoist)

    function foo() {
    	console.log(age);
    	var age = 26;
    }
    foo(); // undefined
    

    上一段不会报错,是因为 ECMAScript 运行时把它看成等价于如下代码:

    即,把所有变量声明提升到作用域顶部

    function foo() {
    	var age;
    	console.log(age);
    	age = 26;
    }
    foo(); // undefined
    

    因此多次声明同一个变量也没有问题

    function foo() {
    	var age = 16;
    	var age = 26;
    	var age = 36;
    	console.log(age);
    }
    foo(); // 36
    

    2 let 关键字

    2.1 let 声明的范围是块作用域

    var 声明的范围是函数作用域。

    块作用域是函数作用域的子集.

    if (true) {
    	var name = 'Matt';
    	console.log(name); // Matt
    }
    console.log(name); // Matt
    
    if (true) {
    	let age = 26;
    	console.log(age); // 26
    }
    console.log(age); // ReferenceError: age 没有定义
    

    2.2 let 不允许同一个块作用域中出现冗余声明

    var name;
    var name; // 不会报错
    
    let age;
    let age; // SyntaxError;标识符 age 已经声明过了
    

    嵌套使用相同的标识符不会报错

    let age = 30; // 作用域是整个块
    console.log(age); // 30
    if (true) {
    	let age = 26; // 作用域是if块
    	console.log(age); // 26
    }
    

    这两个关键字声明的并不是不同类型的变量,它们只是指出变量在相关作用域如何存在

    var name;
    let name; // SyntaxError
    let age;
    var age; // SyntaxError
    

    2.3 let 不会提升(hoist)

    console.log(age); // ReferenceError:age 没有定义
    let age = 26;
    

    2.4 let 全局作用域声明不会成为 window 对象

    var 声明的变量会成为 window 对象的属性

    var name = 'Matt';
    console.log(window.name); // 'Matt'
    
    let age = 26;
    console.log(window.age); // undefined
    

    2.5 let 不能条件声明

    <script>
    	var name = 'Nicholas';
    	let age = 26;
    </script>
    <script>
    	// 假设脚本不确定页面中是否已经声明了同名变量
    	// 那它可以假设还没有声明过
    	var name = 'Matt';
    	// 这里没问题,因为可以被作为一个提升声明来处理
    	// 不需要检查之前是否声明过同名变量
    	let age = 36;
    	// 如果 age 之前声明过,这里会报错
    </script>
    

    对于 let 这个新的 ES6 声明关键字,不能依赖条件声明模式

    <script>
    	let name = 'Nicholas';
    	let age = 36;
    </script>
    <script>
    	// 假设脚本不确定页面中是否已经声明了同名变量
    	// 那它可以假设还没有声明过
    	if (typeof name === 'undefined') {
    		let name;
    	}
    	// name 被限制在 if {} 块的作用域内
    	// 因此这个赋值形同全局赋值
    	name = 'Matt';
    	try {
    		console.log(age); // 如果 age 没有声明过,则会报错
    	}
    	catch(error) {
    	let age;
    	}
    	// age 被限制在 catch {}块的作用域内
    	// 因此这个赋值形同全局赋值
    	age = 26;
    </script>
    

    2.6 for 循环中的 let 声明不会渗透到循环体外部

    for (var i = 0; i < 5; ++i) {
    // 循环逻辑
    }
    console.log(i); // 5
    
    for (let i = 0; i < 5; ++i) {
    // 循环逻辑
    }
    console.log(i); // ReferenceError: i 没有定义
    

    3 const 声明

    • const 的行为与 let 基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量

    • 尝试修改 const 声明的变量会导致运行时错误

    const age = 26;
    age = 36; // TypeError: 给常量赋值
    
    • const 声明的限制只适用于它指向的变量的引用。如果 const 变量引用的是一个对象,那么修改这个对象内部的属性并不违反 const 的限制
    const person = {};
    person.name = 'Matt'; // ok
    
    • 不能用 const 来声明迭代变量(因为迭代变量会自增)
    for (const i = 0; i < 10; ++i) {} // TypeError:给常量赋值
    
    • 如果你只想用 const 声明一个不会被修改的 for 循环变量,那也是可以的。也就是说,每次迭代只是创建一个新变量
    let i = 0;
    for (const j = 7; i < 5; ++i) {
    	console.log(j);
    }
    // 7, 7, 7, 7, 7
    
    for (const key in {a: 1, b: 2}) {
    	console.log(key);
    }
    // a, b
    
    for (const value of [1,2,3,4,5]) {
    	console.log(value);
    }
    // 1, 2, 3, 4, 5
    

    4 关键字使用原则

    1. 不使用 var
    2. const 优先, let 次之

    使用 const 声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作。因此,很多开发者认为应该优先使用 const 来声明变量,只在提前知道未来会有修改时,再使用 let。

    本文是JavaScript高级程序设计(第四版)学习笔记

  • 相关阅读:
    asp.net core mvc 之 DynamicApi
    打造适用于c#的feign
    asp.net App_Code文件夹相关操作
    基于Mono.Cecil的静态注入
    补充ICache
    自制简单实用IoC
    自制简单的.Net ORM框架 (一) 简介
    解决Asp.net Mvc中使用异步的时候HttpContext.Current为null的方法
    微信开发之.Net
    VS2017 网站打包发布生成的文件中包含.pdb文件,解决办法
  • 原文地址:https://www.cnblogs.com/lichunl/p/14208597.html
Copyright © 2020-2023  润新知