ES6
ECMAScript和JavaScript的关系
1.JavaScript 是一种基于 ECMAScript 规范的脚本语言,并在此基础上进行了自己的封装。
2.ECMAScript不是一种编程语言,仅仅是一种脚本语言规范,由欧洲计算机协会制定和发布,任何基于此规范实现的脚本语言都要遵守它的约定。
3.ECMAScript 规定了 JavaScript 脚本的核心语法,如 数据类型、关键字、保留字、运算符、对象和语句等,它不属于任何浏览器。
JavaScript 的内容,包含以下三部分:
- ECMAScript(核心):JavaScript 语言基础;
- DOM(文档对象模型):规定了访问HTML和XML的接口;
- BOM(浏览器对象模型):提供了独立于内容而在浏览器窗口之间进行交互的对象和方法。
各大浏览器的最新版本,对ES6的支持可以查看kangax.github.io/es5-compat-table/es6/
let 与 const 关键字
可以把let看成var,只是它定义的变量被限定在了特定范围内才能使用,而离开这个范围则无效。 const则很直观,用来定义常量,即无法被更改值的变量。
for (let i=0;i<2;i++){
console.log(i);//输出: 0,1
}
console.log(i);
let & const更多http://es6.ruanyifeng.com/#docs/let
var 和 let 、const 的区别:
1、 var 是 ES5 语法,let、const 是 ES6 语法;var 有变量提升
2、 var 和 let 是变量,可修改;const 是常量,不可修改
3、let 和 const 是块级作用域,var 是函数作用域
解构-Destructuring
ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值 1.数组解构
var [a, b, c] = [1, 2, 3];
如果解构不成功,变量的值就等于undefined; 如果等号的右边不是数组(或者严格地说,不是可遍历的结构,参见《Iterator》一章),那么将会报错。 解构赋值允许指定默认值,默认值生效的条件是,对象的属性值严格等于undefined。
2.对象的解构赋值 对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。
var { foo: baz } = { foo: "aaa", bar: "bbb" };
baz // "aaa"
foo // error: foo is not defined
上面代码中,真正被赋值的是变量baz,而不是模式foo 对象的解构也可以指定默认值。
var {x = 3} = {x: undefined};
x // 3
var {x = 3} = {x: null};
x // null
3.函数参数的解构赋值
function add([x, y]){
return x + y;
}
add([1, 2]); // 3
解构-更多http://es6.ruanyifeng.com/#docs/destructuring#对象的解构赋值
字符串扩展-string
模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量
var name = "Bob", time = "today";
\`Hello ${name}, how are you ${time}?\`
函数扩展-function
箭头函数
var array = [1, 2, 3];
//传统写法
array.forEach(function(v, i, a) {
console.log(v);
});
//ES6
array.forEach(v = > console.log(v));
var f = () => 5;
// 等同于
var f = function () { return 5 };
var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
return num1 + num2;
};
增强的对象字面量object
对象字面量被增强了,写法更加简洁与灵活,同时在定义对象的时候能够做的事情更多了。具体表现在:
- 可以在对象字面量里面定义原型
- 定义方法可以不用function关键字
- 直接调用父类方法
//通过对象字面量创建对象
var human = {
breathe() {
console.log('breathing...');
}
};
var worker = {
__proto__: human, //设置此对象的原型为human,相当于继承human
company: 'freelancer',
work() {
console.log('working...');
}
};
human.breathe();//输出 ‘breathing...’
//调用继承来的breathe方法
worker.breathe();//输出 ‘breathing...’
Symbol
ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:Undefined、Null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
Symbol值通过Symbol函数生成,Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象。也就是说,由于Symbol值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。
let s = Symbol();
typeof s
// "symbol"
Symbol值不能与其他类型的值进行运算,会报错。
Symbol值可以显式转为字符串。
Symbol值也可以转为布尔值,但是不能转为数值。
var mySymbol = Symbol();
// 第一种写法
var a = {};
a[mySymbol] = 'Hello!';
// 第二种写法
var a = {
[mySymbol]: 'Hello!'
};
// 第三种写法
var a = {};
Object.defineProperty(a, mySymbol, { value: 'Hello!' });
// 以上写法都得到同样结果
a[mySymbol] // "Hello!"
注意,Symbol值作为对象属性名时,不能用点运算符。
var a = {};
var name = Symbol();
a.name = 'lili';
a[name] = 'lucy';
console.log(a.name,a[name]); //lili,lucy
Symbol.for()
Symbol.for机制有点类似于单例模式,首先在全局中搜索有没有以该参数作为名称的Symbol值,如果有,就返回这个Symbol值,否则就新建并返回一个以该字符串为名称的Symbol值。和直接的Symbol就点不同了。
var s1 = Symbol.for('foo');
var s2 = Symbol.for('foo');
s1 === s2 // true
Proxy
Proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。
Proxy可以监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操作。一下子让我们对一个对象有了很强的追踪能力,同时在数据绑定方面也很有用处。
Proxy可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写。Proxy这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”。
//定义被侦听的目标对象
var engineer = { name: 'Joe Sixpack', salary: 50 };
//定义处理程序
var interceptor = {
set: function (receiver, property, value) {
console.log(property, 'is changed to', value);
receiver[property] = value;
}
};
//创建代理以进行侦听
engineer = Proxy(engineer, interceptor);
//做一些改动来触发代理
engineer.salary = 60;//控制台输出:salary is changed to 60
set和map数据结构
Set
ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。
var s = new Set();
[2, 3, 5, 4, 5, 2, 2].map(x => s.add(x));
for (let i of s) {
console.log(i);
}
// 2 3 5 4
Set操作方法
- add(value):添加某个值,返回Set结构本身。
- delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
- has(value):返回一个布尔值,表示该值是否为Set的成员。
- clear():清除所有成员,没有返回值。
Set结构的实例有四个遍历方法,可以用于遍历成员。
- keys():返回键名的遍历器
- values():返回键值的遍历器
- entries():返回键值对的遍历器
- forEach():使用回调函数遍历每个成员
let set = new Set(['red', 'green', 'blue']);
for (let item of set.keys()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.values()) {
console.log(item);
}
// red
// green
// blue
for (let item of set.entries()) {
console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]
WeakSet
WeakSet结构与Set类似,也是不重复的值的集合。但是,它与Set有两个区别。
首先,WeakSet的成员只能是对象,而不能是其他类型的值。
其次,WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet之中。这个特点意味着,无法引用WeakSet的成员,因此WeakSet是不可遍历的。
var a = [[1,2], [3,4]];
var ws = new WeakSet(a);
var b = [3, 4];
var ws = new WeakSet(b);
// Uncaught TypeError: Invalid value used in weak set(…)
Map
JavaScript的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。
ES6提供了Map数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object结构提供了“字符串—值”的对应,Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。如果你需要“键值对”的数据结构,Map比Object更合适。
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
作为构造函数,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"
Iterator和for…of循环
未完待续。。。