es6学习日记

let 和 const 命令

let命令,用来声明变量。它的用法类似于var,但是所声明的变量,只在let命令所在的代码块内有效。

let name = 'zach'
{
    let name = 'obama'
    console.log(name)  //obama
}
console.log(name)  //zach

使用var声明的变量在for循环的计数器中,变量被泄露为全局变量,如:

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

上面代码中,变量i是var声明的,在全局范围内都有效。所以每一次循环,新的i值都会覆盖旧值,导致最后输出的是最后一轮的i的值。而使用let则不会出现这个问题。

var a = [];
for (let i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 6

const命令,用来声明一个只读的常量。一旦声明,常量的值就不能改变。

const PI = 3.1415;
PI // 3.1415

PI = 3;
// TypeError: Assignment to constant variable.

模板字符串

传统的JavaScript语言,输出模板通常是这样写的。

$('#result').append(
  'There are <b>' + basket.count + '</b> ' +
  'items in your basket, ' +
  '<em>' + basket.onSale +
  '</em> are on sale!'
);

上面这种写法相当繁琐不方便,ES6引入了模板字符串解决这个问题。

$('#result').append(`
  There are <b>${basket.count}</b> items
   in your basket, <em>${basket.onSale}</em>
  are on sale!
`);

用反引号(`)来标识起始,用${}来引用变量。

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);

ES6写法:

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }
}

var p = new Point(1, 2);

上面代码首先用class定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。简单地说,constructor内定义的方法和属性是实例对象自己的,而constructor外定义的方法和属性则是所有实力对象可以共享的,等同于ES5上构造函数的prototype方法和属性。另外,方法之间不需要逗号分隔,加了会报错。

extends继承

Class之间可以通过extends关键字实现继承,super关键字,它指代父类的实例(即父类的this对象)。在子类的构造函数中,只有调用super之后,才可以使用this关键字,否则会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。

class Point {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  toString() {
    return '(' + this.x + ', ' + this.y + ')';
  }

  toName(){
      return 'aaa'
  }
}
class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 调用父类的constructor(x, y)
    this.color = color;
  }

  toString() {
    return this.color + ' ' + super.toString(); // 调用父类的toString()
  }
}
var c = new ColorPoint(1,2,'red');
console.log(c.toString()) //red (1, 2)

箭头函数

ES6允许使用“箭头”(=>)定义函数。

// ES5
function(i) {
  return i + 1;
};
// ES6
(i) => i + 1;


// ES5
function(x, y) { 
    x++;
    y--;
    return x + y;
}
// ES6
(x, y) => {
    x++; 
    y--; 
    return x+y
}

箭头函数可以绑定this对象,大大减少了显式绑定this对象的写法(call、apply、bind)。

class Animal {
    constructor(){
        this.type = 'animal'
    }
    says(say){
        setTimeout(function(){
            console.log(this.type + ' says ' + say)
        }, 1000)
    }
}

var animal = new Animal()
animal.says('hi')  //undefined says hi

运行上面的代码会报错,这是因为setTimeout中的this指向的是全局对象。

class Animal {
    constructor(){
        this.type = 'animal'
    }
    says(say){
        setTimeout( () => {
            console.log(this.type + ' says ' + say)
        }, 1000)
    }
}
var animal = new Animal()
animal.says('hi')  //animal says hi

当我们使用箭头函数时,函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
并不是因为箭头函数内部有绑定this的机制,实际原因是箭头函数根本没有自己的this,它的this是继承外面的,因此内部的this就是外层代码块的this。

module模块

模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。

export的写法:

方法一:单个输出
// profile.js
export var firstName = 'Michael';
export function multiply(x, y) {
  return x * y;
};
export var year = 1958;

方法二:使用大括号指定所要输出的一组变量
// profile.js
var firstName = 'Michael';
export function multiply(x, y) {
  return x * y;
};
var year = 1958;
export {firstName, multiply, year};

方法三:使用as关键字重命名
// profile.js
var firstName = 'Michael';
export function multiply(x, y) {
  return x * y;
};
var year = 1958;
export {
  v1 as firstName ,
  v2 as multiply,
  v2 as year 
};

export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。

export var foo = 'bar';
setTimeout(() => foo = 'baz', 500);

上面代码输出变量foo,值为bar,500毫秒之后变成baz。

import的写法:

import {firstName, multiply, year} from './profile';

//使用as关键字,将输入的变量重命名
import { firstName as surname } from './profile';

//使用用星号(*)指定一个对象,所有输出值都加载在这个对象上面
import * as preson from './profile';
console.log(preson.firstName);
console.log(preson.multiply());

export default

export default命令,为模块指定默认输出,一个模块只能有一个默认输出。使用import命令可以用任意名称指向使用export default命令输出的方法。

// import-default.js
export default function foo() {
  console.log('foo');
}

// 或者写成

function foo() {
  console.log('foo');
}

export default foo;

//main.js
import customName from './export-default';
customName(); // 'foo'

Set和Map数据结构

Set它类似于数组,但是成员的值都是唯一的,没有重复的值。

// 删除数组中的重复项
const set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]

// size:获取数组的长度
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.size // 5

// add():添加某个值,返回Set结构本身
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.add(8);
[...items]
// [1, 2, 3, 4,5,8]

// delete:删除某个值,返回一个布尔值,表示删除是否成功
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.delete(1);
[...items]
// [ 2, 3, 4,5]

// has:返回一个布尔值,表示该值是否为Set的成员
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.has(1) 

// clear():清除所有成员,没有返回值
const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]);
items.clear() 

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

function dedupe(array) {
  return Array.from(new Set(array));
}

dedupe([1, 1, 2, 3]) // [1, 2, 3]

 

posted @ 2017-04-21 15:17  白色斑马线  阅读(216)  评论(0编辑  收藏  举报