ES6新语法概览

语法

箭头函数、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
}
// test
let 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); //1
const 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); //3

let [first,...last] = [1,2,3];
console.log(last); //[2,3]

//对象解构
let {name,age} = {name: "lisi", age: "20"};
console.log(name); //lisi
console.log(age); //20

let {ept} = {};
console.log(ept); //undefined
Rest + Spread

“…”



//Rest
function f(x, ...y) {
  return x * y.length;
}
f(3, "hello", true) == 6

//Spread
function 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) // 先返回yieId
console.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(键名只接受对象)

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;

// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;

// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined

// Weak Sets
var 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  // false

if (sym) {
  // ...
}

Number(sym) // TypeError
sym + 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值