ES6新语法概览

来源:互联网 发布:艾默生网络能源年终奖 编辑:程序博客网 时间:2024/05/16 23:58

语法

箭头函数、this

ES6中可以使用 => 作为函数表达形式,极简风格,参数+ => +函数体。

// 1.1单行 无参数var foo = function(){return 1}//等价于let foo = () => 1// 1.1单行 有参数var foo = function(x){return x}//等价于let foo = (x) => x// 2.1多行function add(a,b){    console.log(a+b)    return a+b}// 等价于let add = (a,b)=>{    console.log(a+b)    return a+b}// testlet nums = [1,2,3,5,10]let fives = []nums.forEach(v => {  if (v % 5 === 0)    fives.push(v)});console.log(fives) //[5,10]

箭头函数中的 this 指的不是window,是对象本身。

function aa(){  this.bb = 1;  setTimeout(() => {    this.bb++; //this指向aa    console.log(this.bb);  },500);}aa(); //2

let、const

  • ES6 推荐在函数中使用 let 定义变量

  • const 用来声明一个常量,但也并非一成不变的

  • let 和 const 只在最近的一个块中(花括号中)有效
var a = 1;{  let a = 2;  console.log(a); //2}console.log(a); //1const A = [1,2];A.push = 3;console.log(A); //[1,2,3]A = 10; //Error

Classes

  • JavaScript语言的传统方法是通过构造函数,定义并生成新对象

  • Class内部只有静态方法,没有静态属性,但可以用另外方式解决

function Point(x, y) {  this.x = x;  this.y = y;}Point.prototype.toString = function () {  return '(' + this.x + ', ' + this.y + ')';};var p = new Point(1, 2);//这种写法跟传统的面向对象语言(比如C++和Java)差异很大,很容易让新学习这门语言的程序员感到困惑
  • ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
//定义类class Point {  constructor(x, y) {    this.x = x;    this.y = y;  }  toString() {    return '(' + this.x + ', ' + this.y + ')';  }}//上面代码定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。//也就是说,ES5的构造函数Point,对应ES6的Point类的构造方法

test

class Animal {  constructor(){    console.log('我是一个动物');  }}class Person extends Animal {  constructor(){    super();    console.log('我是一个程序员');  }}let aa = new Person();//我是一个动物//我是一个程序员

解构

解构赋值是ES6中推出的一种高效、简洁的赋值方法

没啥说的,直接上代码:

//通常情况下var first = someArray[0];var second = someArray[1];var third = someArray[2];//解构赋值let [first, second, third] = someArray; //比上面简洁多了吧//还有下面例子let [,,third] = [1,2,3];console.log(third); //3let [first,...last] = [1,2,3];console.log(last); //[2,3]//对象解构let {name,age} = {name: "lisi", age: "20"};console.log(name); //lisiconsole.log(age); //20let {ept} = {};console.log(ept); //undefined

Rest + Spread

“…”

//Restfunction f(x, ...y) {  return x * y.length;}f(3, "hello", true) == 6//Spreadfunction f(x, y, z) {  return x + y + z;}f(...[1,2,3]) == 6

对象于面量扩展

  • 可以在对象字面量里面定义原型
  • 定义方法可以不用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...’

模版字符串

ES6中提供了用反引号`来创建字符串,里面可包含${…}等

`This is a pretty little template string.``In ES5 this is not legal.`let name = "Bob", time = "today";`Hello ${name}, how are you ${time}?`

Iterators(迭代器)

ES6 中可以通过 Symbol.iterator 给对象设置默认的遍历器,直到状态为true退出。可以是数组,对象,Set,Map类型的。

var arr = [11,12,13];var itr = arr[Symbol.iterator]();itr.next(); //{ value: 11, done: false }itr.next(); //{ value: 12, done: false }itr.next(); //{ value: 13, done: false }itr.next(); //{ value: undefined, done: true }// 循环输出,该循环速度快for(;;){  let elem = itr.next()  if(elem.done){    break  }  console.log(elem.value)}

Generators

Generators函数是ES6新增的一种异步编程方案。是一种新的语法结构,一个遍历器对象生成器,它内部可以封装多个状态,非常适合异步操作。

Generators函数语法和普通的function函数类似,但是有三个不同点:

  • (1)function关键字和函数名称之间有一个星号(*)
  • (2)函数体内可以使用yieId语句
  • (3)函数调用后不会立即执行,返回的是一个遍历器对象

Run-Stop-Run…

// 1.function *foo(x) {    var y = 2 * (yield (x + 1));    var z = yield (y / 3);    return (x + y + z);}var it = foo( 5 );console.log( it.next() );       // { value:6, done:false }console.log( it.next( 12 ) );   // { value:8, done:false }console.log( it.next( 13 ) );   // { value:42, done:true }// 2.// 一个Generators函数function *yuanku(){    yieId "冤苦",    yieId "冤苦",    yieId "冤苦",    return "end"}// 函数内部使用yieId语句定义不同状态,return也可以定义一个状态,也就是说上面代码有四个状态var y = yuanku() // 调用此函数,并不会立即执行它其中的代码,而是返回一个遍历器对象console.log(y.next()) // 返回一个具有value和done属性的对象console.log(y.next()) // youreturn,返回(value:end,done:true);如果没有return,返回(value:undefined,done:true)// yieId语句// 每一个yieId语句定义不同的状态,它也是一个代码执行暂停标识//yieId语句不能在普通函数中使用,否则会报错// 调用Generators函数可以返回一个遍历器对象,要想访问Generators函数中的每一个状态,需要使用遍历器对象调用next()方法// 如果使用yieId语句作为其他语句的额一部分,那么必须使用小括号包裹,否则会报错。例如:function *yuanku(){    //console.log("欢迎来到"+yieId"冤苦") // 报错    console.log("欢迎来到"+(yieId"冤苦"))// 正确}let y = yuanku()console.log(y.next().value) // 先返回yieIdconsole.log(y.next().value) // 再返回return,yieId为undefined

generator能实现好多功能,如配合for…of使用,实现异步等等,我在这里就不多说了。

for…of && for…in

  • for…of 遍历(数组)
let arr = [1,2,3];for (let itr of arr) {  console.log(itr); //1 2 3}
  • for…in 遍历(对象中的属性)
let arr = [1,2,3];arr.aa = 'bb';for (let itr in arr) {  console.log(itr); //0 1 2 aa}

Map + Set + WeakMap + WeakSet

  • Set 对象是一组不重复的值,重复的值将被忽略,值类型可以是原始类型和引用类型

  • WeakSet是一种弱引用(垃圾自动回收,防止内存泄漏),只用于对象。同理WeakMap(键名只接受对象)

// Setsvar s = new Set();s.add("hello").add("goodbye").add("hello");s.size === 2;s.has("hello") === true;// Mapsvar m = new Map();m.set("hello", 42);m.set(s, 34);m.get(s) == 34;// Weak Mapsvar wm = new WeakMap();wm.set(s, { extra: 42 });wm.size === undefined// Weak Setsvar ws = new WeakSet();ws.add({ data: 42 });

Proxies

  • Proxy可以监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操作。

  • Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程

  • 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

Symbols

  • ES5的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是ES6引入Symbol的原因。

  • ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript语言的第七种数据类型,前六种是:Undefined、Null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)

  • Symbol值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的Symbol类型

  • Symbol 是一种新的字符串数据类型,它的值是唯一的,不可变的。

  • ES6 中提出 symbol 的目的是为了生成一个唯一的标识符,不过你访问不到这个标识符.

1、类型

let s = Symbol();typeof s// "symbol"
  • 上面代码中,变量s就是一个独一无二的值。typeof运算符的结果,表明变量s是Symbol数据类型,而不是字符串之类的其他类型
  • 注意,Symbol函数前不能使用new命令,否则会报错。这是因为生成的Symbol是一个原始类型的值,不是对象。也就是说,由于Symbol值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型

2、 如果 Symbol 的参数是一个对象,就会调用该对象的toString方法,将其转为字符串,然后才生成一个 Symbol 值

var s1 = Symbol('foo');var s2 = Symbol('bar');s1 // Symbol(foo)s2 // Symbol(bar)s1.toString() // "Symbol(foo)"s2.toString() // "Symbol(bar)"

注意,Symbol函数的参数只是表示对当前 Symbol 值的描述,因此相同参数的Symbol函数的返回值是不相等的。

3 、没有参数的情况

var s1 = Symbol();var s2 = Symbol();s1 === s2 // false

4、有参数的情况

var s1 = Symbol('foo');var s2 = Symbol('foo');s1 === s2 // false

上面代码中,s1和s2都是Symbol函数的返回值,而且参数相同,但是它们是不相等的

5、Symbol值不能与其他类型的值进行运算,会报错

var sym = Symbol('My symbol');"your symbol is " + sym// TypeError: can't convert symbol to string`your symbol is ${sym}`// TypeError: can't convert symbol to string

6、但是,Symbol值可以显式转为字符串。

var sym = Symbol('My symbol');String(sym) // 'Symbol(My symbol)'sym.toString() // 'Symbol(My symbol)'

8、另外,Symbol值也可以转为布尔值,但是不能转为数值。

var sym = Symbol();Boolean(sym) // true!sym  // falseif (sym) {  // ...}Number(sym) // TypeErrorsym + 2 // TypeError
  • 如果要获取对象 symbol 属性,需要使用Object.getOwnPropertySymbols(o)

Promises

  • ES6 对 Promise 有了原生的支持,一个 Promise 是一个等待被异步执行的对象,当它执行完成后,其状态会变成 resolved 或者 rejected

  • Promises对象具有三种状态:Pending(等待)、Resolved(已完成)、Rejected(未完成)

  • Promises对象状态的改变只有两种可能:Pending转变为Resolved,或者Pending转变为Rejected

  • Promises是处理异步操作的一种模式,之前在很多三方库中有实现,比如jQuery的 deferred 对象。当你发起一个异步请求,并绑定了.when(), .done()等事件处理程序时,其实就是在应用promise模式

function timeout(duration = 0) {    return new Promise((resolve, reject) => {        setTimeout(resolve, duration);    })}var p = timeout(1000).then(() => {    return timeout(2000);}).then(() => {    throw new Error("hmm");}).catch(err => {    return Promise.all([timeout(100), timeout(200)]);})

想要了解promise实际应用等,详见。

小结

总之,ES6还是有很多棒棒的语法,有利于精简代码,高效开发;只不过一些低级别浏览器不支持,可以用Babel等工具把ES6转化成ES5

原创粉丝点击