ES6(JaveScript 的下一个版本标准)学习(一) let、const、结构赋值、Symbol

初学不知道别人提到的ES6是什么,查一下原来是JavaScript(JavaScript 也称 ECMAScript) 的下一个版本标准,所以学习起来应该不会太陌生

主要学习地址:菜鸟教程 http://www.runoob.com/w3cnote/es6-tutorial.html

学习方式:一边看教程一边记录要点,掌握自己之前不知道的知识点,弄不清楚的地方用代码调试(调试环境:Node.js)辅助理解

ES6, 全称 ECMAScript 6.0 ,是 JaveScript 的下一个版本标准,2015.06 发版。

ES6 主要是为了解决 ES5 的先天不足,比如 JavaScript 里并没有类的概念,但是目前浏览器的 JavaScript 是 ES5 版本,大多数高版本的浏览器也支持 ES6,不过只实现了 ES6 的部分特性和功能。

Node.js 是运行在服务端的 JavaScript,它对 ES6 的支持度更高。

/*教程里突然出现了webpack和gulp,后面再看看它们跟ES6有什么联系
webpack
webpack 是一个现代 JavaScript 应用程序的静态模块打包器 (module bundler) 。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图 (dependency graph) ,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle 。
gulp
gulp 是一个基于流的自动化构建工具,具有易于使用、构建快速、插件高质和易于学习的特点,常用于轻量级的工程中。*/

ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const。

let 声明的变量只在 let 命令所在的代码块内有效。

const 声明一个只读的常量,一旦声明,常量的值就不能改变。
let 是在代码块内有效,var 是在全局范围内有效

let 只能声明一次, var 可以声明多次

for 循环计数器适合用 let

let 不存在变量提升,var 会变量提升:先使用变量再用let定义报错,先使用变量再用var定义值是undefined

const 声明一个只读变量,声明之后不允许改变。意味着,一但声明必须初始化,否则会报错。ES6 明确规定,代码块内如果存在 let 或者 const,代码块会对这些命令声明的变量从块的开始就形成一个封闭作用域。代码块内,在声明变量之前使用它会报错。

const 如何做到变量在声明初始化之后不允许改变的?其实 const 其实保证的不是变量的值不变,而是保证变量指向的内存地址所保存的数据不允许改动。此时,你可能已经想到,简单类型和复合类型保存值的方式是不同的。是的,对于简单类型(数值 number、字符串 string 、布尔值 boolean),值就保存在变量指向的那个内存地址,因此 const 声明的简单类型变量等同于常量。而复杂类型(对象 object,数组 array,函数 function),变量指向的内存地址其实是保存了一个指向实际数据的指针,所以 const 只能保证指针是固定的,至于指针指向的数据结构变不变就无法控制了,所以使用 const 声明复杂类型对象时要慎重。

解构赋值是对赋值运算符的扩展。

他是一种针对数组或者对象进行模式匹配,然后对其中的变量进行赋值。

在代码书写上简洁且易读,语义更加清晰明了;也方便了复杂对象中数据字段获取。

直接看教程:http://www.runoob.com/w3cnote/deconstruction-assignment.html

ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值,最大的用法是用来定义对象的唯一属性名。

ES6 数据类型除了 Number 、 String 、 Boolean 、 Objec t、 null 和 undefined ,还新增了 Symbol 。

Symbol 函数栈不能用 new 命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,为新创建的 Symbol 提供描述,用来显示在控制台或者作为字符串的时候使用,便于区分。
注:教程例子那里因为sy是大写的KK而sy1是小写的kk所以有点费解,调试发现就算是大写的KK也是不等的

let sy = Symbol("KK");
console.log(sy);   // Symbol(KK)

// 相同参数 Symbol() 返回的值不相等
let sy1 = Symbol("kk");
console.log(sy1);
console.log(sy === sy1);       // false

let sy2 = Symbol("KK");
console.log(sy2);
console.log(sy === sy2);       // false

上面的代码输出:
Symbol(KK)
Symbol(kk)
false
Symbol(KK)
false

由于每一个 Symbol 的值都是不相等的,所以 Symbol 作为对象的属性名,可以保证属性不重名。

Symbol 作为对象属性名时不能用.运算符,要用方括号。因为.运算符后面是字符串,所以取到的是字符串 sy 属性,而不是 Symbol 值 sy 属性。

Symbol 值作为属性名时,该属性是公有属性不是私有属性,可以在类的外部访问。但是不会出现在 for…in 、 for…of 的循环中,也不会被 Object.keys() 、 Object.getOwnPropertyNames() 返回。如果要读取到一个对象的 Symbol 属性,可以通过 Object.getOwnPropertySymbols() 和 Reflect.ownKeys() 取到。

在 ES5 使用字符串表示常量。但是用字符串不能保证常量是独特的,这样会引起一些问题,比如多个变常量都为同一个值。但是使用 Symbol 定义常量,这样就可以保证这一组常量的值都不相等。Symbol 的值是唯一的,所以不会出现相同值得常量,即可以保证 switch 按照代码预想的方式执行。
这里看教程的例子不太能理解,所以自己尝试运行和改动一些地方看看结果:

const COLOR_RED = "red";
const COLOR_YELLOW = "yellow";
const COLOR_BLUE = "blue";
const MY_BLUE = "blue";

function getConstantName(color) {
  switch (color) {
    case COLOR_RED:
      return "COLOR_RED";
    case COLOR_YELLOW:
      return "COLOR_YELLOW ";
    case COLOR_BLUE:
      return "COLOR_BLUE";
    case MY_BLUE:
      return "MY_BLUE";
    default:
      throw new Exception("Can't find this color");
    }
}

console.log(getConstantName(COLOR_BLUE))
console.log(getConstantName(MY_BLUE))

上面的代码输出:
COLOR_BLUE
COLOR_BLUE
这是因为COLOR_BLUE和MY_BLUE相等,都为"blue"

const COLOR_RED = Symbol("red");
const COLOR_YELLOW = Symbol("yellow");
const COLOR_BLUE = Symbol("blue");
const MY_BLUE = Symbol("blue");

function getConstantName(color) {
  switch (color) {
    case COLOR_RED:
      return "COLOR_RED";
    case COLOR_YELLOW:
      return "COLOR_YELLOW ";
    case COLOR_BLUE:
      return "COLOR_BLUE";
    case MY_BLUE:
      return "MY_BLUE";
    default:
      throw new Exception("Can't find this color");
  }
}

console.log(getConstantName(COLOR_BLUE))
console.log(getConstantName(MY_BLUE))

上面的代码输出:
COLOR_BLUE
MY_BLUE
这是因为COLOR_BLUE和MY_BLUE不相等,即Symbol(“blue”)与Symbol(“blue”)不相等

Symbol.for()
Symbol.for() 类似单例模式,首先会在全局搜索被登记的 Symbol 中是否有该字符串参数作为名称的 Symbol 值,如果有即返回该 Symbol 值,若没有则新建并返回一个以该字符串参数为名称的 Symbol 值,并登记在全局环境中供搜索。

Symbol.keyFor()
Symbol.keyFor() 返回一个已登记的 Symbol 类型值的 key ,用来检测该字符串参数作为名称的 Symbol 值是否已被登记。
教程中的代码yellow === yellow1为false的原因是第一行并没有登记"Yellow",必须用Symbol.for()才能登记

let yellow = Symbol("Yellow");
let yellow1 = Symbol.for("Yellow");
yellow === yellow1;      // false
 
let yellow2 = Symbol.for("Yellow");
yellow1 === yellow2;     // true

用Symbol.keyFor()即可判断登记情况:

let yellow = Symbol("Yellow");
console.log(Symbol.keyFor(yellow));
let yellow1 = Symbol.for("Yellow");  
console.log(Symbol.keyFor(yellow1));  

上面代码输出:
undefined
Yellow
登记成功后,用Symbol.for()得到的值都是一样的,所以yellow1 === yellow2为true,这是跟Symbol()不同的地方。
个人理解是Symbol()就像每个人虽然有的人名字一样,但都是不同的人,而Symbol.for()只要第一个人第一次登记后,后面别人再用都是在用第一个人所登记的,比如公共库,网站名称(不一定准确)等。

更详细准确的用法可以参考官方文档:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for
和阮一峰的开源教程书籍:http://es6.ruanyifeng.com/#docs/symbol

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值