ES6快速入门使用

 https://www.jianshu.com/p/061304806bdajavascript

Babel-webpack的配置

前段项目我想使用ES6的语法我应该怎么作呢?咱们能够查看Babel的官方文档,就简单用webpack如何配置
因此咱们就能够先用ES6语言来写代码,而后用webpack打包生成ES5的文件,下面只是简单介绍一下,详细的能够查看官方文档,固然了这只是一种工具,咱们只须要看官网怎么作的就能够java

1. Shell npm install --save-dev babel-loader babel-core 2. webpack.config.js module: { rules: [ { test: /\.js$/, exclude: /node_modules/, loader: "babel-loader" } ] } 3. create .babelrc npm install babel-preset-env --save-dev //JSON { "presets": ["env"] } 

var let const

  • var 可声明前置
var a a = 1 var a = 2 

ES6 新增了let命令,用来声明变量。它的用法相似于var,但也有区别:node

  • let 不存在变量提高
console.log(bar); // 报错ReferenceError let bar = 2; a = 1 //报错 let a 
  • let不容许在相同做用域内,重复声明同一个变量。
// 报错 function func() { let a = 10; var a = 1; } // 报错 function func() { let a = 10; let a = 1; } let a = 3 var a =4 //报错 let a =5 //报错 
  • 存在块级做用域
for(let i =0;i<3;i++){ console.log(i) } console.log(i) //报错 

块级做用域的出现,实际上使得得到普遍应用的当即执行函数表达式(IIFE)再也不必要了。webpack

(function(){ var a = 1 })() ==> { let a = 1 } 

ES5 只有全局做用域和函数做用域,没有块级做用域,这带来不少不合理的场景。web

  1. 内层变量可能会覆盖外层变量。
var tmp = new Date(); function f() { console.log(tmp); if (false) { var tmp = 'hello world'; // var tmp 变量提高 } } f(); // undefined 
  1. 用来计数的循环变量泄露为全局变量。
var s = 'hello'; for (var i = 0; i < s.length; i++) { console.log(s[i]); // i泄露为全局变量 } console.log(i); // 5 
  • 暂时性死区(TDZ)
var tmp = 123; if (true) { tmp = 'abc'; // ReferenceError let tmp; } 

只要块级做用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,再也不受外部的影响。
暂时性死区的本质就是,只要一进入当前做用域,所要使用的变量就已经存在了,可是不可获取,只有等到声明变量的那一行代码出现,才能够获取和使用该变量。ajax

  • const

const声明一个只读的常量。一旦声明,常量的值就不能改变。
const一旦声明变量,就必须当即初始化,不能留到之后赋值。npm

//基本类型 const PI = 3.1415; PI // 3.1415 PI = 3; // TypeError: Assignment to constant variable. //引用类型 const foo = {}; // 为 foo 添加一个属性,能够成功 foo.prop = 123; foo.prop // 123 // 将 foo 指向另外一个对象,就会报错 foo = {}; // TypeError: "foo" is read-only 

适用let的也适用const编程


解构赋值

ES6 容许按照必定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。数组

  • 数组的解构赋值
let [a,b,c] = [1,2,3] console.log(a,b,c) // 1 2 3 let [a, [b], c] = [1, [2], 3] a // 1 b // 2 c // 3 let [x, , y] = [1, 2, 3] // x=1 y=3 let [head, ...tail] = [1, 2, 3, 4]; head // 1 tail // [2, 3, 4] 

若是解构不成功,变量的值就等于undefined。bash

let [foo] = []; let [bar, foo] = [1]; 
// 报错 let [foo] = 1; 

默认值
解构赋值容许指定默认值。
数组对应值有没有?若是没有(没有指undefined),使用默认值,有就使用对应值

let [foo = true] = []; foo // true let [x, y = 'b'] = ['a']; // x='a', y='b' let [x, y = 'b'] = ['a', undefined]; // x='a', y='b' let [a=2,b=3] = [undefined, null] a //2 b //null 
  • 对象的解构赋值
    实际上说明,对象的解构赋值是下面形式的简写
let { foo: foo, bar: bar } = { foo: "aaa", bar: "bbb" }; 
let { foo, bar } = { foo: "aaa", bar: "bbb" }; foo // "aaa" bar // "bbb" 

对象的解构与数组有一个重要的不一样。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

let { bar, foo } = { foo: "aaa", bar: "bbb" }; foo // "aaa" bar // "bbb" let { baz } = { foo: "aaa", bar: "bbb" }; baz // undefined 没有同名的 

对象解构的默认值
默认值生效的条件是,对象的属性值严格等于undefined。

var {x = 3} = {}; x // 3 var {x, y = 5} = {x: 1}; x // 1 y // 5 var {x: y = 3} = {}; y // 3 var {x: y = 3} = {x: 5}; y // 5 var { message: msg = 'Something went wrong' } = {}; msg // "Something went wrong" 
  • 字符串的解构赋值
const [a, b, c, d, e] = 'hello'; a // "h" b // "e" c // "l" d // "l" e // "o" 
相似数组的对象都有一个length属性,所以还能够对这个属性解构赋值。

let {length : len} = 'hello'; len // 5 
  • 数值和布尔值的解构赋值

解构赋值时,若是等号右边是数值和布尔值,则会先转为对象。

let {toString: s} = 123; s === Number.prototype.toString // true let {toString: s} = true; s === Boolean.prototype.toString // true 

解构赋值的规则是,只要等号右边的值不是对象或数组,就先将其转为对象。因为undefined和null没法转为对象,因此对它们进行解构赋值,都会报错。

let { prop: x } = undefined; // TypeError let { prop: y } = null; // TypeError 
  • 函数参数的解构赋值
function add([x, y] = [1,1]){ return x + y; } add() // 2 add([2]) // 3 add([1, 2]); // 3 function sum({x,y} = {x:0, y:0},{a=1,b=1}){ return [x+a,y+b] } console.log(sum({x:1,y:2},{a:2})) //[3,3] 
  • 解构赋值的做用
  1. 交换变量的值
let x = 1; let y = 2; [x, y] = [y, x]; // [2,1] 
  1. 函数参数默认值
function ajax(url , type='GET'){ } ajax(url:'http://localhost') 

字符串经常使用

  • 字符串模板
// ES5字符串拼接 $('#result').append( 'There are <b>' + basket.count + '</b> ' + 'items in your basket, ' + '<em>' + basket.onSale + '</em> are on sale!' ); 

模板字符串(template string)是加强版的字符串,用反引号(`)标识。它能够看成普通字符串使用,也能够用来定义多行字符串,或者在字符串中嵌入变量。

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

模板字符串中嵌入变量,须要将变量名写在${}之中

function authorize(user, action) { if (!user.hasPrivilege(action)) { throw new Error( // 传统写法为 // 'User ' // + user.name // + ' is not authorized to do ' // + action // + '.' `User ${user.name} is not authorized to do ${action}.`); } } 

数组扩展经常使用

  • 扩展运算符
    扩展运算符(spread)是三个点(...)
var a = [1,2] console.log(...a) // 1,2 var b = [...a,3] b // [1,2,3] function add(x, y) { return x + y; } const numbers = [4, 38]; add(...numbers) // 42 
... 应用替代apply用法
// ES5 的写法 Math.max.apply(null, [14, 3, 77]) // ES6 的写法 Math.max(...[14, 3, 77]) // ES5的 写法 var arr1 = [0, 1, 2]; var arr2 = [3, 4, 5]; Array.prototype.push.apply(arr1, arr2); // ES6 的写法 let arr1 = [0, 1, 2]; let arr2 = [3, 4, 5]; arr1.push(...arr2); 函数参数的扩展 function sort(...arr){ console.log(arr.sort()) } sort(3,1,5) //[1,3,5] 
  • Array.form()
    • Array.from方法用于将两类对象转为真正的数组:相似数组的对象(array-like object)和可遍历(iterable)的对象(包括 ES6 新增的数据结构 Set 和 Map)。
// NodeList对象 let ps = document.querySelectorAll('p'); Array.from(ps).forEach(function (p) { console.log(p); }); // arguments对象 function foo() { var args = Array.from(arguments); // ... } 
// 类数组对象 let arrayLike = { '0': 'a', '1': 'b', '2': 'c', length: 3 }; // ES5的写法 var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c'] // ES6的写法 let arr2 = Array.from(arrayLike); // ['a', 'b', 'c'] 

函数扩展

  • 能够给参数添加默认值
function log(x, y = 'World') { console.log(x, y); } log('Hello') // Hello World log('Hello', 'China') // Hello China log('Hello', '') // Hello 
//练习,区别? // 写法一 function m1({x = 0, y = 0} = {}) { return [x, y]; } // 写法二 function m2({x, y} = { x: 0, y: 0 }) { return [x, y]; } // 函数没有参数的状况 m1() // [0, 0] m2() // [0, 0] // x 和 y 都有值的状况 m1({x: 3, y: 8}) // [3, 8] m2({x: 3, y: 8}) // [3, 8] // x 有值,y 无值的状况 m1({x: 3}) // [3, 0] m2({x: 3}) // [3, undefined] // x 和 y 都无值的状况 m1({}) // [0, 0]; m2({}) // [undefined, undefined] m1({z: 3}) // [0, 0] m2({z: 3}) // [undefined, undefined] //总结 ex1: 调用函数须要你传递一个对象,若是你没传对象就用默认值对象{},默认值对象里面都是 undefined, 因此属性使用初始值 ex2:参数须要是一个对象,若是没传对象,就用默认值对象{ x: 0, y: 0 }若是传了对象,就使用你传递的对象 
  • 箭头函数
    • ES6 容许使用“箭头”(=>)定义函数。
var f = v => v; //等价于 var f = function(v) { return v; }; var f = () => 5; // 等同于 var f = function () { return 5 }; var sum = (num1, num2) => num1 + num2; // 等同于 var sum = function(num1, num2) { return num1 + num2; }; 

若是箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,而且使用return语句返回。

var sum = (num1, num2) => { return num1 + num2; } 
  • 箭头函数的this

函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。this对象的指向是可变的,可是在箭头函数中,它是固定的。

function foo() { setTimeout(() => { console.log('id:', this.id); }, 100); } var id = 21; foo.call({ id: 42 }); // id: 42 

setTimeout的参数是一个箭头函数,这个箭头函数的定义生效是在foo函数生成时,而它的真正执行要等到 100 毫秒后。若是是普通函数,执行时this应该指向全局对象window,这时应该输出21。可是,箭头函数致使this老是指向函数定义生效时所在的对象(本例是{id: 42}),因此输出的是42

对象扩展

  • 属性的简洁表示法
    ES6 容许直接写入变量和函数,做为对象的属性和方法。这样的书写更加简洁。
const foo = 'bar'; const baz = {foo}; baz // {foo: "bar"} // 等同于 const baz = {foo: foo}; 
function f(x, y) { return {x, y}; } // 等同于 function f(x, y) { return {x: x, y: y}; } f(1, 2) // Object {x: 1, y: 2} 
//方法简写 const o = { method() { return "Hello!"; } }; // 等同于 const o = { method: function() { return "Hello!"; } }; 

Module的语法 模块化

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

一个模块就是一个独立的文件。该文件内部的全部变量,外部没法获取。若是你但愿外部可以读取模块内部的某个变量,就必须使用export关键字输出该变量。下面是一个 JS 文件,里面使用export命令输出变量。

// profile.js export var firstName = 'Michael'; export var lastName = 'Jackson'; export var year = 1958; // profile.js var firstName = 'Michael'; var lastName = 'Jackson'; var year = 1958; export {firstName, lastName, year}; //usage.js import {firstName, lastName, year} from './profile'; 

export命令除了输出变量,还能够输出函数或类(class)。

export function multiply(x, y) { return x * y; }; 
  • export default 命令
    使用import命令的时候,用户须要知道所要加载的变量名或函数名,不然没法加载,为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。
// export-default.js export default function () { console.log('foo'); } 

其余模块加载该模块时,import命令能够为该匿名函数指定任意名字。

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

Class和继承

ES6 的class能够看做只是一个语法糖,它的绝大部分功能,ES5 均可以
作到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。上面的代码用 ES6 的class改写,就是下面这样。

//定义类 class Point { constructor(x, y) { this.x = x; this.y = y; } toString() { return '(' + this.x + ', ' + this.y + ')'; } } //等价于 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 { // ... } typeof Point // "function" Point === Point.prototype.constructor // true 

构造函数的prototype属性,在 ES6 的“类”上面继续存在。事实上,类的全部方法都定义在类的prototype属性上面。

class Point { constructor() { // ... } toString() { // ... } toValue() { // ... } } // 等同于 Point.prototype = { constructor() {}, toString() {}, toValue() {}, }; 

constructor方法是类的默认方法,经过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,若是没有显式定义,一个空的constructor方法会被默认添加。

class Point { } // 等同于 class Point { constructor() {} } 
  • Class静态方法
    类至关于实例的原型,全部在类中定义的方法,都会被实例继承。若是在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接经过类来调用,这就称为“静态方法”。
class Foo { //类 static classMethod() { return 'hello'; } } Foo.classMethod() // 'hello' var foo = new Foo(); foo.classMethod() // TypeError: foo.classMethod is not a function 

上面代码中,Foo类的classMethod方法前有static关键字,代表该方法是一个静态方法,能够直接在Foo类上调用(Foo.classMethod()),而不是在Foo类的实例上调用。若是在实例上调用静态方法,会抛出一个错误,表示不存在该方法。

  • 继承
    Class 能够经过extends关键字实现继承,这比 ES5 的经过修改原型链实现继承,要清晰和方便不少。
class Point { } class ColorPoint extends Point { } 

super 关键字

super这个关键字,既能够看成函数使用,也能够看成对象使用。在这两种状况下,它的用法彻底不一样。

class Person { constructor(name, age) { this.name = name; this.age = age; } sayHello() { console.log( `hello, ${this.name}, i am ${this.age} years old`); } } class Student extends Person { constructor(name, age, score) { super(name, age); this.score = score; } sayScore() { console.log( `hello, ${this.name}, i am ${this.age} years old, i get ${this.score}`); } } 
相关文章
相关标签/搜索