ECMAScript6的新特性--数据类型

1 let命令

ECMAScript6新增了let命令,用来声明变量。它的用法类似与var,
但是所声明的变量只在let命令所在的代码块有效。

for(let i=0;i<5;i++){
    console.log(i);
}
console.log(i);//error

上面代码在for循环代码块中输出i的值时 输出的值分别为0、1、2、3、4、5,
但在for循环外输出i的值时,系统报错。这表明let声明的变量只有在它所在的
代码块有效

var list = document.getElementById("list");

for (var i = 1; i <= 5; i++) {
  var item = document.createElement("LI");
  item.appendChild(document.createTextNode("Item " + i));
  let j = i;
  item.onclick = function (ev) {
    console.log("Item " + j + " is clicked.");
  };
  list.appendChild(item);
}

上面这段代码的意图是创建5个li,点击不同的li能够打印出当前li的序号。如果不用let,而改用var的话,将总是打印出 Item 5 is Clicked,因为 j 是函数级变量,5个内部函数都指向了同一个 j ,而 j 最后一次赋值是5。用了let后,j 变成块级域(也就是花括号中的块,每进入一次花括号就生成了一个块级域),所以 5 个内部函数指向了不同的 j 。

let不允许在相同的作用域内,重复声明同一个变量

{let a=10;
    var a=1;
    //error
}

let 实际上为js新增了块级作用域

function f1(){
    let n=5;
    if(true){
    let n=10;
}
console.log(n);//5
}

需要注意的是,let声明的变量不存在“变量提升”的现象(变量提升: 在指定作用域里,从代码顺序上看是变量先使用后声明,但运行时变量的 “可访问性” 提升到当前作用域的顶部,其值为 undefined ,没有 “可用性”。)

console.log(x);
let x=10;

上述代码会报错,表示x没有定义。如果用var声明x,不会报错 输出undefined

2 const命令

const也用来声明变量,但是声明的是常量。一旦声明,常量的值就不会改变

const PI=3.1415;
console.log(PI);//3.1415
PI=3;
console.log(PI)//3.1415
const PI=3.1;
console.log(PI);//3.1415

const的作用域与var命令相同:如果在全局环境中声明,常量就在全局环境中有效,如果在函数内声明,常量就在函数体内有效。

3 set数据结构

ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,
没有重复的值

Set本身是一个构造函数,用来生成Set数据结构

var s=new Set();
[2,3,4,5,3,6,1,2,3].map(x=>s.add(x));
for(i of s){
    console.log(i);//2,3,4,5,6,1
}

上面代码通过add方法向Set结构加入成员,结构表明Set结构不会加入重复值。

Set函数可以接受一个数组作为参数,用来初始化。

var items=new Set([1,2,3,4,3,2,1]);
console.log(items);//Set{1,2,3,4}

向Set加入值的时候,不会发生类型转换,5和”5”是另个不相同的值

var items=new Set([1,2,3,4,"3",2,1]);
console.log(items);//Set{1,2,3,4,"3"}

属性和方法

Set结构有以下属性

  • Set.prototype.constructor:构造函数,默认值就是Set函数
  • Set.prototype.size:返回Set成员总数
    Set数据结构有以下方法

  • add(value):添加某个值,返回Set结构本身

  • delete(value): 删除某个值,返回一个布尔值,表示删除是否成功
  • has(value): 返回一个布尔值,表示该值是否为Set的成员
  • clear(): 清除所有成员
    Set属性和方法的使用

    var items=new Set();
    items.add(3).add(5).add(2).add(3);
    console.log(items.size);//3
    console.log(items.has(3));//true
    console.log(items.has(1));//false
    console.log(items.delete(2));//true
    console.log(items.has(2));//false

Array.from方法可以将Set结构转为数组

var items=new Set([1,2,4,5,2,]);
console.log(Object.prototype.toString.call(items));//[object Set]
var arr=Array.from(items);
console.log(Object.prototype.toString.call(items));//[object Array]

Set的遍历操作

Set的默认遍历器是values方法

let set=new Set(["red","green","blue"]);
for(let x of set){
    console.log(x);//red green blue
}

扩展运算符(…)内部使用for…of循环,所以也可用于Set结构

var arr1=[1,2,3,4,2,1];
var unique=[...new Set(arr1)];
console.log(unique);

该方法可以作为一种数组去重的方法

4 Map

js的对象本质上时键值对的集合,但是只能用字符串当做键

var data={};
var ele=document.getElementById("MyDiv");
data[element]=metadata;

该代码愿意是将一个DOM节点作为对象的键,但是由于对象只接受字符串作为键值,
所以element被自动转为字符串

为了解决这个问题,ES6提供了map数据结构,它类似于对象,也是键值对的集合,
但是键的范围不限于字符串,各种类型的值(包括对象)都可以当做键

Map是ES6新增的有序键值对集合。其基本思想就是把一个值映射给一个唯一的键,
这样在任何时刻,都能根据该键获取到对应的值。也就是说,object结构提供了“字符串-值”的对用,Map结构提供了“值-值”的对应。

var m = new Map();
var o = {p: "Hello World"};
m.set(o, "content")
m.get(o) // "content"
m.has(o) // true
m.delete(o) // true
m.has(o) // false

上面代码使用set方法,将对象o当作m的一个键,然后又使用get方法读取这个键,接着使用delete方法删除了这个键。

作为构造函数,Map也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。

var map = new Map([ ["name", "张三"], ["title", "Author"]]);

map.size // 2
map.has("name") // true
map.get("name") // "张三"
map.has("title") // true
map.get("title") // "Author"

Map的键实际上是跟内存地址绑定的,只要内存地址不一样,就视为两个键。这就解决了同名属性碰撞(clash)的问题,我们扩展别人的库的时候,如果使用对象作为键名,就不用担心自己的属性与原作者的属性同名。

Map数据结构的属性和方法

  • size:返回成员总数。
  • set(key, value):设置key所对应的键值,然后返回整个Map结构。如果key已经有值,则键值会被更新,否则就新生成该键。
  • get(key):读取key对应的键值,如果找不到key,返回undefined。
  • has(key):返回一个布尔值,表示某个键是否在Map数据结构中。
  • delete(key):删除某个键,返回true。如果删除失败,返回false。
  • clear():清除所有成员,没有返回值。

Map数据结构的遍历

Map原生提供三个遍历器。

keys():返回键名的遍历器。

values():返回键值的遍历器。

entries():返回所有成员的遍历器。

let map = new Map([
  ['F', 'no'],
  ['T',  'yes'],
]);

for (let key of map.keys()) {
  console.log(key);
}
// "F"
// "T"

for (let value of map.values()) {
  console.log(value);
}
// "no"
// "yes"

for (let item of map.entries()) {
  console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"

// 或者
for (let [key, value] of map.entries()) {
  console.log(key, value);
}

// 等同于使用map.entries()
for (let [key, value] of map) {
  console.log(key, value);
}

上面代码最后的那个例子,表示Map结构的默认遍历器就是entires方法

Map结构转为数组结构,比较快速的方法是结合使用扩展运算符(…)

let map = new Map([
  [1, 'one'],
  [2, 'two'],
  [3, 'three'],
]);

[...map.keys()]
// [1, 2, 3]

[...map.values()]
// ['one', 'two', 'three']

[...map.entries()]
// [[1,'one'], [2, 'two'], [3, 'three']]

[...map]
// [[1,'one'], [2, 'two'], [3, 'three']]

参考文献:javascript标准参考教程
ECMAScript6入门

你可能感兴趣的:(ECMAScript6)