es6学习手记

来源:互联网 发布:百胜软件工资待遇 编辑:程序博客网 时间:2024/05/24 01:41

本来是要学习现在流行的前端框架的,结果发现好多都在使用es6,所以还是先学习一下es6吧。顺便记录一下自己感觉有用的新特性。

本文的栗子可以在babel官网上运行

let、const以及块状作用域

const用来定义常量,let也是用来定义变量的,但是用let定义的变量会被限定在当前作用域。
es5没有块状作用域,写代码时经常会造成困扰,本次es6终于添加了。

let m=6;const n=8;{    let m=9;    const n=0;    console.log(m)    console.log(n)}console.log(m)console.log(n)//n=9;//报错

模板字符串(` `)

es5可以用单引号或双引号来表示字符串,es6添加了一种用反引号(` `)框起来的,称为模板字符串。
最大的特点是两个反引号之间的内容可以换行,并且支持用${}来引入javascript表达式。

var m='i am';var n=`${m}template string`console.log(n)

方法参数默认值

es5写法

function log(x, y) {  var y = y || 'World';//此处还可以重新用var定义y}

es6写法,支持在参数列表直接赋值,此值即为默认值。

function log(x, y = 'World') {  //let y=6;报错。与参数同名变量再次定义会报错。  console.log(x, y);}

…(三个点)

有两种用法
- rest:用在方法参数列表,有点类似Java的可变参数(void test(String... args)),规则也差不多
1. 只能有一个rest参数
2. rest参数只能是最后一个

function test(a,...b){  console.log(a)  b.forEach(function(item){    console.log(item)  })}test('f','1',2,3,4)
  • spread:用作传参,可以将数组转换为以逗号隔开的参数。
function test(a,b,c){  console.log(a);  console.log(b);  console.log(c);}var arr=[1,2]test(...arr);//1 2 undefined//复制对象let m = { a: 1, b: 2 };let n = { ...m };

箭头函数(=>)

箭头函数可概括为:参数列表 => 方法体,如:

var f=(m)=>{console.log(m)}//等同于var f = function(m) {    console.log(m);};

当参数列表或方法体很简洁时可以省略括号:

var m=v=>v;var n=()=>1;

需要注意的是:箭头函数没有属于自己的this,而是使用外层的this,所以也无法用作构造函数。
什么意思呢?看以下代码:

function out(){  this.num=0;  this.f=()=>{console.log(this.num)}  this.m=function(){    console.log(this.num);  }}//翻译为es5后"use strict";function out() {  var _this = this;  this.num = 0;  this.f = function () {    console.log(_this.num);  };  this.m = function () {    console.log(this.num);  };}

可以看到翻译后的箭头函数使用的是外部的this,而普通函数则使用的还是本身的this,结合js‘谁调用函数,this便指向谁’的特性,可以很好的理解二者的不同。

属性名表达式

如果我们要定义一个对象,来看es5和es6的写法

    var namePro='name';    var age=18;    var es5Obj={        name:'peter',        age:age,        doSth:function(){            console.log(this.name)        }    }    //es6座位    var es6Obj={        [namePro]:'peter',//表达式        age,        doSth(){            console.log(this[namePro])        }    }    es5Obj.doSth();    es6Obj.doSth();

可以看到如果属性名和值用到同一个定义的话可以省略为单个。方法定义可以省略:function。而最大的特点就是属性名支持表达式[]了。在中括号中可以写入js表达式,表达式的计算结果即为属性名。如上面的自定义变量namePro。

Object.assign

熟悉jQuery的应该都知道知道用$.extend()来复制对象,es6提供了类似的方法Object.assign(),用法也和jQuery差不多。

var obj={  name:'peter',  sayHi(){    console.log('Hi')  }}var o1=Object.assign({},obj);o1.age=18;var o2=Object.assign({},obj);o2.age=19;console.log(obj);console.log(o1);console.log(o2);

set 和 Map

学过Java的同学肯定对着两种数据结构不陌生。

Set:包含的值均是唯一的,没有相同的值。

var s=new Set([1,1,2,3]);s.add(3);s.add(4);console.log(s)//1,2,3,4

常用方法:

  • add(value):添加某个值,返回Set结构本身。
  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
  • has(value):返回一个布尔值,表示该值是否为Set的成员。

Map:键值对组成的对象。

var a='a';var m=new Map([    [a,1],    ['b','2']  ])m.set('c',3);console.log(m.get(a))   //1console.log(m.get('c')) //3

常用方法:

  • set(key,value):添加一个新的成员,如果key已存在,则会用新值替换旧值,返回Map本身。
  • get(key):获取key对应的value,不存在则返回undefined。
  • has(key):判断Map中是否有此key,返回布尔值。
  • delete(key):删除key对应的成员,返回布尔值。

公用方法和属性

  • size:返回成员数量。
  • clear():清除所有成员,没有返回值。
  • keys():返回一个键名的遍历器
  • values():返回一个键值的遍历器
  • entries():返回一个键值对的遍历器
  • forEach():使用回调函数遍历每个成员

类(class)

es6引入了类、静态这些概念,不禁感慨是否要迎来编程语言大一统!

class Animal{  constructor(x){    this.legs=x;    this.eyes=2;  }  static sayHi(){//静态方法    console.log('hi')  }  shout(msg){    console.log(msg)  }}var dog=new Animal(4);dog.shout('汪');//汪console.log(dog.legs)//4var snake=new Animal(0)snake.shout('嘶')//嘶console.log(snake.legs)//0Animal.sayHi()//dog.sayHi(); not a functionclass Dog extends Animal{  constructor(x,y){    super(x)//子类必须调用super,super代表父类的构造函数    this.color=y;  }  showColor(){    console.log(this.color)  }}var dog2=new Dog(4,'white')dog2.showColor()//白色console.log(dog.legs)//4 继承自父类

module(模块化)

前端模块化的思想由来已久,es6之前主要有AMD(require.js)/CMD和CommonJS(node.js)来规范js的模块化方案。下面就来介绍一下es6的模块化方案:
在es6中,export用于输出模块,import用于加载模块

  • export
//demo1export const hello = "hello";//等价于const hello = "hello";export {hello}

输出多个模块可以分开定义,一起输出

//demo2const hello = "hello";const fnc=function(){    console.log('peter')}export {hello as h,fnc}//hello as h表示将hello输出为h,即定义别名,加载模块时用h来加载//也可以输出对象或类let hello={    sayHi:'hi',    fnc(){        console.log('peter')    }}export {hello as h}
  • import

使用export的文件可以用import来加载,格式为 import xxx from 'js文件'

//对应上面的demo2import {h,fnc} from './hello_es6'//也可以写为let root=document.getElementById('root');root.innerHTML=h;fnc();//对象import {h as hello} from './hello_es6'//import也可使用as定义别名let root=document.getElementById('root');root.innerHTML=hello.sayHi;hello.fnc();

还有一种加载模式,分散导出,整体加载。

//对应demo2例一import * as h from './hello_es6'//可以理解为将hello_es6导出的东西放到h中去let root=document.getElementById('root');root.innerHTML=h.hello;h.fnc();
  • export default

输出一个默认值,导入时无需知道输出时的变量名,可以自定义名称,且无需用{}包裹。每个模块只能有一个默认值

//exportconst hello = "hello";export default hello;//importimport h from './hello_es6'let root=document.getElementById('root');root.innerHTML=h;

最后,无论是export还是import都只能写在文件的顶层模块,而不能写在其他代码块中,否则报错。

//错误示例{export {hello};}if(true){    import h from './hello_es6'}
0 0
原创粉丝点击