整理了ES6常用的一些语法,跟大家分享(promise、generator什么的还没有梳理清楚,后续再更新。。。)

1⃣️ 变量声明-let 与 const

(首先关于测试结果:这里有个小问题,如果用let/const声明的变量,在控制台调试的话,第一次输出结果后,第二次如果你还想用,要么把代码放入编辑器中,再打开浏览器看结果,要么就把变量名更改重新输入结果,否则是会报错的)
  let与const的作用与var 类似,都是用来声明变量但是在实际应用中,它俩有各自的特殊用途

  (注意:ES6里let和const没有变量的提升,一定要声明后再使用,但代码编译成ES5之后,变量提升依旧存在)

  先举个栗子

var name = 'aaron';

if(true) {
var name = 'peter';
console.log(name); // peter
} console.log(name); //peter

  我们可以看到,使用var声明的变量,两次输出结果都是peter,那是因为ES5里只有全局作用域和函数作用域,没有块级作用域,那么我们怎么才能让它两次打印的结果分别是aaron 和 peter呢? 现在let就可以派上用场了  

  改造一下上面的栗子

let name = 'aaron';

if(true) {
let name = 'peter';
console.log(name); // peter
} console.log(name); //aaron

  现在可以看到,两次的结果已经不相同了,let实际上为JavaScript新增了块级作用域。用它所声明的变量,只在let命令所在的代码块内有效。

  下面再来看一发关于关于for循环的栗子,问题就是用来计数的循环变量泄露为全局变量,会对我们的一些操作带来很大的影响,话不多说,来看栗子

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

  原本我们的需求是 a[6](),结果可以输出6,但无论我们写的是a[i](),最终输出的结果都是10,因为for循环结束之后,i的值已经变成了10,而i又是全局变量,当函数之行的时候,首先在函数体内部没有i这么一个变量,所以它会去上一级作用域去寻找,本栗中它的上一级作用域就是全局作用域,所以也就找到了已经变为10的全局变量i,所以a[i]();无论你[]内写0~9哪个数字,最终输出结果都是10;

  在没有ES6之前,如果我们想让它的输出就过就是6,就要使用到闭包(闭包这东西,个人的理解,用大白话说就是把你想要实现功能的方法,外面再给它包一个函数。内部return你要实现功能的方法,由于函数的作用域,这样可以避免变量泄露变成全局变量,从而带来一些我们不想看到的结果)

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

  讲真,这样很麻烦有没有?现在有了ES6 的let ,完全可以不用这么写了

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

  只是改了几个字母,var改成了let,已经实现了我们的需求,很方便有没有?!

  const也用来声明变量,但是声明的是常量。一旦声明,常量的值就不能改变。改变的话,浏览器会报错

  栗子

const A = 1;
A = 2; // Uncaught TypeError: Assignment to constant variable.

  针对const的这个特性,我们可以在引用第三方库的时,把需要声明的变量,用const来声明,这样可以避免未来不小心重命名而导致出现bug

const xxx = require('xxxxx');

注意:当值为基础数据类型时,那么这里的值,就是指值本身。
    而当值对应的为引用数据类型时,那么这里的值,则表示指向该对象的引用。这里需要注意,正因为该值为一个引用,只需要保证引用不变就可以,我们仍然可以改变该引用所指向的对象。

  栗子

const obj = {
a: 20,
b: 30
} obj.a = 30;
obj.c = 40; console.log(obj); // Object {a: 30, b: 30,c:40}
这种情况下只要不是直接覆盖obj的值,只改变属性什么的还是还可以

2⃣️模版字符串

使用 反引号``(键盘上esc下面那个键) 将整个字符串包裹起来,而在其中使用 ${} 来包裹一个变量或者一个表达式
// es5
var a = 20;
var b = 30;
var string = a + "+" + b + "=" + (a + b); // es6
const a = 20;
const b = 30;
const string = `${a}+${b}=${a+b}`;

 3⃣️解构(destructuring)赋值

  数组以序列号一一对应,这是一个有序的对应关系。
  对象根据属性名一一对应,这是一个无序的对应关系。

  为了更好的理解,直接上栗子吧
 数组的解构赋值
// es5
var arr = [1, 2, 3];
var a = arr[0];
var b = arr[1];
var c = arr[2]; // es6
const arr = [1, 2, 3];
const [a, b, c] = arr;
console.log(a,b,c) // 1,2,3
  对象的解构赋值
const MYOBJ = {
className: 'trigger-button',
loading: false,
clicked: true,
disabled: 'disabled'
}

现在我们想要取得其中的2个值:loading与clicked:

// es5
var loading = MYOBJ.loading;
var clicked = MYOBJ.clicked; // es6
const { loading, clicked } = MYOBJ;
console.log(loading);// false // 还可以给一个默认值,当props对象中找不到loading时,loading就等于该默认值
const { loadings = false, clicked } = MYOBJ;
console.log(loadings);// false

4⃣️展开运算符(spread operater)

   在ES6中用...来表示展开运算符,它可以将数组方法或者对象进行展开。上栗子

1.函数调用中使用展开运算符

  函数调用里,将一个数组展开成多个参数,我们会用到apply:

function test(a, b, c) { }
var args = [0, 1, 2];
test.apply(null, args);

  在ES6里可以这样写

function test(a,b,c) { }
var args = [0,1,2];
test(...args);

2.数组字面量中使用展开运算符

  有了ES6,我们可以直接加一个数组直接合并到另外一个数组当中

const arr1 = [1, 2, 3];
const arr2 = [...arr1, 10, 20, 30]; // 这样,arr2 就变成了[1, 2, 3, 10, 20, 30];

  展开运算符也可以用在push函数中,可以不用再用apply()函数来合并两个数组:

var arr1=['a','b','c'];
var arr2=['d','e'];
arr1.push(...arr2); //['a','b','c','d','e']

3.用于解构赋值

let [arg1,arg2,...arg3] = [1, 2, 3, 4];
arg1 //1
arg2 //2
arg3 //['3','4']

  注意:解构赋值中展开运算符只能用在最后,否则会报错

4.展开运算符可以将伪数组变成真正的数组

var list=document.querySelectorAll('div');
var arr=[..list];

  Object.prototype.toString.apply(list) // "[object NodeList]"
  Object.prototype.toString.apply(arr) // "[object Array]"

关于对象展开
好像目前ES6还不支持这样,现在这样写浏览器会报错,ES7草案里貌似有提到,所以对象展开这里先了解一下就好了
const obj1 = {
a: 1,
b: 2,
c: 3
} const obj2 = {
...obj1,
d: 4,
e: 5,
f: 6
} // 结果类似于 const obj2 = Object.assign({}, obj1, {d: 4,e:5,f:6})
扩展:Object.assign() 方法用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。 语法:Object.assign(target, 一个或多个sources)

5⃣️ arrow function箭头函数

  函数的快捷写法,不需要通过 function 关键字创建函数,并且还可以省略 return 关键字。(注意:箭头函数本身没有this,如果在箭头函数内使用this,这个this一定是它上级的this,再有就是箭头函数可以代替函数表达式,但代替不了函数声明,它还是需要声明才能使用的)。

 (parma)=>{expression},箭头函数根据parma个数的不同,写法上还可以做如下改变
() => { expression } // 零个参数用 () 表示
x => { expression } // 一个参数可以省略 ()
(x, y) => { expression } // 多参数不能省略 ()

注意: 在ES6中,会默认采用严格模式,因此this也不会自动指向window对象了,而箭头函数本身并没有this,因此this就只能是undefined,这一点,在使用的时候,一定要慎重慎重再慎重,不然踩了坑你都不知道自己错在哪!这种情况,如果你还想用this,就不要用使用箭头函数的写法。

  栗子

var person = {
name: 'tom',
getName: function() {
return this.name;
}
} // 用ES6的写法来重构上面的对象
const person = {
name: 'tom',
getName: () => this.name
} // 但是编译结果却是
var person = {
name: 'tom',
getName: function getName() {
return undefined.name;
}
};

对上面的代码稍作改动

const person = {
name: 'tom',
getName: function() {
return setTimeout(() => this.name, 1000);
}
} // 编译之后变成
var person = {
name: 'tom',
getName: function getName() {
var _this = this; // 使用了我们在es5时常用的方式保存this引用 return setTimeout(function () {
return _this.name;
}, 1000);
}
};

6⃣️函数参数的默认值

之前我们想要保证传入函数的参数有一个默认值,通常需要这么写
function add(x) {
var x = x || 20;
return x;
} console.log(add()); // 20

但这种方法是有缺陷的,比如说我们如果传入一个false

function add(x) {
var x = x || 20;
return x;
} console.log(add(false)); // 20

打印结果是20 而不是fasle,显然合格结果不是我们想要的,如果我们想要打印出false,就还要再做什么if判断等一些列操作,很麻烦,现在有了es6,我们可以很容易解决这个问题,下面我们来看一下es6的写法

function add(x = 20) {
return x ;
} console.log(add());// 20
console.log(add(false)); // false
可以看到,es6很容易就解决了这个问题。
7⃣️对象字面量({})扩展
ES6针对对象字面量做了许多简化语法的处理

1)精简属性:

const name = 'Jane';
const age = 20 // es6写法
const person = {
name,
age
} // es5写法
var person = {
name: name,
age: age
};

2)精简方法:

// es6写法
const person = {
name,
age,
getName() { // 只要不使用箭头函数,this就还是我们熟悉的this
return this.name
}
} // es5写法
var person = {
name: name,
age: age,
getName: function getName() {
return this.name;
}
};

3)属性名表达式:(这里有点儿恶心,经过几次代码测试,最终确定下面这样解释的话,可能会容易理解一些)

  在对象字面量中可以使用中括号作为属性,表示属性也能是一个变量了,而且这个变量的值还可以改变

const name = 'Jane';

const person = {
[name]: true,
['a'+'ge']: true
}
注意:上面的对象{}内写了两个[]属性 ,切记[]里面如果是一个变量的话,那么这个变量一定要是一个已经声明过的,否则结果就是undefined,[]如果是表达式,那么访问的时候,要向下面这样写
console.log(person['a'+'ge'])/console.log(person['age'])/console.log(oerson.age) // true
console.log(person[name]);// true  

注意:对象内用[变量]当作属性时,访问该属性只能用[]语法,对象内给这个属性赋什么值,它就会变成什么值,而且这个值也可以通过[]里面传入访问变量最初设置的值,也可以访问到,写就是说像下面这样写 和上面结果是一样的

 console.log(person['Jane']);  // true

对象的方法也可以这样写

let obj = {
['h'+'ello']() {
return 'hi';
}
};
console.log(obj.hello()); // hi

 8⃣️class、extend、super

class、extend、super这三个特性涉及了ES5中最令人头疼的的几个部分:构造函数继承原型...

ES6提供了更接近传统语言的写法,引入了Class(类)这个概念。新的class写法让对象原型的写法更加清晰、更像面向对象编程的语法,也更加通俗易懂。

新旧语法对比

 class

// ES5
// 构造函数
function Person(name, age) {
this.name = name;
this.age = age;
} // 原型方法
Person.prototype.getName = function() {
return this.name
} // ES6
class Person {
constructor(name, age) { // 构造函数
this.name = name;
this.age = age;
} getName() { // 原型方法
return this.name
}
}

上面代码首先用class定义了一个“类”,可以看到里面有一个constructor方法,这就是构造方法,而this关键字则代表实例对象。

简单地说,constructor内定义的方法和属性是实例对象自己的,而constructor外定义的方法和属性则是所有实例对象可以共享的。这个和ES5里的构造函数是差不多的意思,相当于把方法定义在构造函数里是私有的,而把方法定义到原型中,所有实例共享

extend继承

class Person {
constructor(name, age) {
this.name = name;
this.age = age;
} getName() {
return this.name
}
} // Student类继承Person类
class Student extends Person {
constructor(name, age, gender, classes) {
super(name, age);
this.gender = gender;
this.classes = classes;
} getGender() {
return this.gender;
}
}

Class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。上面定义了一个Cat类,该类通过extends关键字,继承了Animal类的所有属性和方法。

super关键字,它指代父类的实例(即父类的this对象)。子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后可以对其进行加工。如果不调用super方法,子类就得不到this对象。

关于 super,像上面的栗子

// 构造函数中
// es5写法
Person.call(this);
// es6写法 
super(name, age);

class、extend/super三者的综合实栗

class Animal {
constructor(){
this.type = 'animal'
}
says(say){
console.log(this.type + ' says ' + say)
}
} let animal = new Animal()
animal.says('hello') //animal says hello class Cat extends Animal {
constructor(){
super()
this.type = 'cat'
}
} let cat = new Cat()
cat.says('hello') //cat says hello

9⃣️模块的 Import 和 Export

import 用于引入模块,export 用于导出模块。

// 引入整个文件
import dva from 'dva'; // 引入函数(可以是一个或多个)
import { connect } from 'dva';
import { Link, Route } from 'dva/router'; // 引入全部并作为 github 对象
import * as github from './services/github'; // 导出默认
export default App;
// 部分导出,复合写法是 export { App } from './file';
  等价于import { App } from './file;export{App}

  

ES6入门的更多相关文章

  1. ES6入门笔记

    ES6入门笔记 02 Let&Const.md 增加了块级作用域. 常量 避免了变量提升 03 变量的解构赋值.md var [a, b, c] = [1, 2, 3]; var [[a,d] ...

  2. es6入门4--promise详解

    可以说每个前端开发者都无法避免解决异步问题,尤其是当处理了某个异步调用A后,又要紧接着处理其它逻辑,而最直观的做法就是通过回调函数(当然事件派发也可以)处理,比如: 请求A(function (请求响 ...

  3. es6入门3--箭头函数与形参等属性的拓展

    对函数拓展兴趣更大一点,优先看,前面字符串后面再说,那些API居多,会使用能记住部分就好. 一.函数参数可以使用默认值 1.默认值生效条件 在变量的解构赋值就提到了,函数参数可以使用默认值了.正常我们 ...

  4. Vue+koa2开发一款全栈小程序(1.课程介绍+2.ES6入门)

    1.课程介绍 1.课程概述 1.做什么? Vue+koa2开发一款全栈小程序 2.哪些功能? 个人中心.图书列表.图书详情.图书评论.个人评论列表 3.技术栈 小程序.Vue.js.koa2.koa- ...

  5. es6入门5--class类的基本用法

    在ES6之前,准确来说JavaScript语言并无类的概念,却有模拟类的做法.相比在类似java这类传统面向对象语言中通过类来生成实例,js则通过构造函数模拟类来生成实例. 这是因为在JS设计初期,作 ...

  6. es6入门6--数组拓展运算符,Array.from()基本用法

    本文只是作为ES6入门第九章学习笔记,在整理知识点的同时,会加入部分个人思考与解答,若想知道更详细的介绍,还请阅读阮一峰大神的ES6入门 一.拓展运算符 ES6中新增了拓展运算(...)三个点,它的作 ...

  7. ES6入门之let和const命令

    前言 大家好,我是一只流浪的kk,当你看到这边博客的时候,说明你已经进入了ES6学习的领域了,从本篇博客开始,我将会将自己学习到ES6的相关知识进行整理,方便大家参考和学习,那么我将带你进入第一节的内 ...

  8. ES6入门之变量的解构赋值(二)

    前言 在上一章 ES6入门之let和const命令中我们对ES6的相关语法已经有了初步了解,上一章中我们主要学习了三大部分的内容,let命令的使用,块级作用域,const命令的使用,那么从本篇博客将进 ...

  9. ES6入门十二:Module(模块化)

    webpack4打包配置babel7转码ES6 Module语法与API的使用 import() Module加载实现原理 Commonjs规范的模块与ES6模块的差异 ES6模块与Nodejs模块相 ...

  10. es6入门7--Set Map数据结构

    本文作为ES6入门第十三章的学习整理笔记,可能会包含少部分个人的理解推测,若想阅读更详细的介绍,还请阅读原文ES6入门 一.set数据结构 1.set不接受重复值 ES6新增了Set构造函数用于创建s ...

随机推荐

  1. 1821: [JSOI2010]Group 部落划分 Group

    1821: [JSOI2010]Group 部落划分 Group Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1308  Solved: 627[Su ...

  2. 【方法】Oracle用户密码含特殊字符时的登陆问题

    [方法]Oracle用户密码含特殊字符时的登陆问题 1.1  BLOG文档结构图 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它 ...

  3. 实现Unity编辑器模式下的旋转

    最近在做一个模型展示的项目,我的想法是根据滑动屏幕的x方向差值和Y方向的差值,来根据世界坐标下的X轴和Y轴进行旋转,但是实习时候总是有一些卡顿.在观察unity编辑器下的旋转之后,发现编辑器下的旋转非 ...

  4. ECSHOP info: Can't Connect MySQL Server(localhost:3306)!

    今天对服务器压力测试后,某个公司电脑的页面显示标题所示,别人电脑正常.故让她清理cookie.无效.重启MySQL后问题解决.

  5. java学习笔记----java入门

    java基础 一.java语言跨平台原理 1.什么是跨平台? 跨平台就是一个软件可以在不同的操作系统中运行,但是不需要对其修改.换句话说,java语言编写的软件在不做修改的情况下就能在不同的系统平台上 ...

  6. shell脚本监控目录下文件被篡改时报警

    思路: 目录下文件被篡改的几种可能: 1.被修改 2.被删除 3.新增文件 md5命令详解 参数: -b 以二进制模式读入文件内容 -t 以文本模式读入文件内容 -c 根据已生成的md5值,对现存文件 ...

  7. Alamofire源码解读系列(十一)之多表单(MultipartFormData)

    本篇讲解跟上传数据相关的多表单 前言 我相信应该有不少的开发者不明白多表单是怎么一回事,然而事实上,多表单确实很简单.试想一下,如果有多个不同类型的文件(png/txt/mp3/pdf等等)需要上传给 ...

  8. python+request+robot framework接口自动化测试

    python+requests实现接口的请求前篇已经介绍,还有不懂或者疑问的可以访问 python+request接口自动化框架 目前我们需要考虑的是如何实现关键字驱动实现接口自动化输出,通过关键字的 ...

  9. Oracle SQL 语言分类

     Oracle SQL语句分类 2008-06-17 11:15:25 分类: Linux * 2008/06/17  星期二*蒙昭良*环境:WindowsXP + Oracle10gR2*Oracl ...

  10. NTP时间服务器

    1. NTP简介 NTP(Network Time Protocol,网络时间协议)是用来使网络中的各个计算机时间同步的一种协议.它的用途是把计算机的时钟同步到世界协调时UTC,其精度在局域网内可达0 ...