-
变量提升 ES6 基础 - 最骚的就是你 - 博客园 (cnblogs.com)
代码编译成为了ES5之后,仍然会存在变量提升,因此这一点只需要我们记住即可。在实际使用中,也需要尽量避免使用变量提升的特性带来的负面影响。只有在面试题中,才会对变量提升不停的滥用。
使用ES6,我们需要全面使用let/const替换var,
我们常常使用let来声明一个值会被改变的变量,而使用const来声明一个值不会被改变的变量,也可以称之为常量。
-
箭头函数可以替换函数表达式,但是不能替换函数声明
箭头函数中,没有this。如果你在箭头函数中使用了this,那么该this一定就是外层的this。
也正是因为箭头函数中没有this,因此我们也就无从谈起用call/apply/bind来改变this指向。记住这个特性,能让你在react组件之间传值时少走无数弯路。
在ES6中,会默认采用严格模式,因此this也不会自动指向window对象了,而箭头函数本身并没有this,因此this就只能是undefined,这种情况,如果你还想用this,就不要用使用箭头函数的写法。
-
模板字符串
使用 `` 将整个字符串包裹起来,而在其中使用 ${} 来包裹一个变量或者一个表达式。
当然模板字符串还支持换行等强大的功能
-
解构语法
数组以序列号一一对应,这是一个有序的对应关系。 而对象根据属性名一一对应,这是一个无序的对应关系。
// 首先有这么一个对象 const props = { className: 'tiger-button', loading: false, clicked: true, disabled: 'disabled' } // es6 const { loading, clicked } = props; // 给一个默认值,当props对象中找不到loading时,loading就等于该默认值 const { loading = false, clicked } = props; // section1 import React, { Component } from 'react'; // section2 export { default } from './Button'; // section3 const { click, loading } = this.props; const { isCheck } = this.state; // more 任何获取对象属性值的场景都可以使用解析结构来减少我们的代码量 //另外,数组也有属于自己的解析结构。 // es6 const arr = [1, 2, 3]; const [a, b, c] = arr; // es5 var arr = [1, 2, 3]; var a = arr[0]; var b = arr[1]; var c = arr[2];
-
函数默认参数
ES5
function add(x, y) { var x = x || 20; var y = y || 30; return x + y; } console.log(add()); // 50
ES6
function add(x = 20, y = 30) { return x + y; } console.log(add()); ****************** const ButtonGroupProps = { size: 'normal', className: 'xxxx-button-group', borderColor: '#333' } export default function ButtonGroup(props = ButtonGroupProps) { ... ... }
-
展开运算符
数组用法
对象用法
const arr1 = [1, 2, 3]; const arr2 = [...arr1, 10, 20, 30]; // 这样,arr2 就变成了[1, 2, 3, 10, 20, 30]; 对象用法 const obj1 = { a: 1, b: 2, c: 3 } const obj2 = { ...obj1, d: 4, e: 5, f: 6 } // 结果类似于 const obj2 = Object.assign({}, obj1, {d: 4})
和解构语法一起用
展开运算符还常常运用在解析结构之中,例如我们在Raect封装组件的时候常常不确定props到底还有多少数据会传进来,就会利用展开运算符来处理剩余的数据。 // 这种方式在react中十分常用 const props = { size: 1, src: 'xxxx', mode: 'si' } const { size, ...others } = props; console.log(others) // 然后再利用暂开运算符传递给下一个元素,再以后封装react组件时会大量使用到这种方式,正在学习react的同学一定要搞懂这种使用方式 <button {...others} size={size} />
展开运算符还用在函数的参数中,来表示函数的不定参。只有放在最后才能作为函数的不定参,否则会报错。
// 所有参数之和 const add = (a, b, ...more) => { return more.reduce((m, n) => m + n) + a + b } console.log(add(1, 23, 1, 2, 3, 4, 5)) // 39
-
对象字面量 与 class
-
当属性与值的变量同名时。简写的语法糖{name,id}
-
export default暴露接口
const getName = () => person.name; const getAge = () => person.age; // commonJS的方式 module.exports = { getName, getAge } // ES6 modules的方式 export default { getName, getAge }
-
对象字面量写法中的方法也可以有简写方式
// es6 const person = { name, age, getName() { // 只要不使用箭头函数,this就还是我们熟悉的this return this.name } } // es5 var person = { name: name, age: age, getName: function getName() { return this.name; } };
-
在对象字面量中可以使用中括号作为属性,表示属性也能是一个变量了。
const name = 'Jane'; const age = 20 const person = { [name]: true, [age]: true } 在ant-design的源码实现中,就大量使用了这种方式来拼接当前元素的className,例如: let alertCls = classNames(prefixCls, { [`${prefixCls}-${type}`]: true, [`${prefixCls}-close`]: !this.state.closing, [`${prefixCls}-with-description`]: !!description, [`${prefixCls}-no-icon`]: !showIcon, [`${prefixCls}-banner`]: !!banner, }, className);
-
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 Person { constructor(name, age) { // 构造函数 this.name = name; this.age = age; } getName() { // 这种写法表示将方法添加到原型中 return this.name } static a = 20; // 等同于 Person.a = 20 c = 20; // 表示在构造函数中添加属性 在构造函数中等同于 this.c = 20 // 箭头函数的写法表示在构造函数中添加方法,在构造函数中等同于this.getAge = function() {} getAge = () => this.age }
-
继承 extends
在继承的构造函数中,我们必须如上面的例子那么调用一次super方法,它表示构造函数的继承,与ES5中利用call/apply继承构造函数是一样的功能。
super还可以直接调用父级的原型方法,
super.getName
继承在react中有大量的使用场景,许多组件都利用继承来创建。
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; } }
-
Promise
除了回调地狱之外,还有一个非常重要的需求:为了代码更加具有可读性和可维护性,我们需要将数据请求与数据处理明确的区分开来。
因此我们需要一个叫做Promise的东西,看上去变得更加复杂了。可是代码变得更加健壮,处理了错误输入的情况。
一、 Promise对象有三种状态,他们分别是:
-
pending: 等待中,或者进行中,表示还没有得到结果
-
resolved(Fulfilled): 已经完成,表示得到了我们想要的结果,可以继续往下执行
-
rejected: 也表示得到结果,但是由于结果并非我们所愿,因此拒绝执行
function want() { console.log('这是你想要执行的代码'); } function fn(want) { console.log('这里表示执行了一大堆各种代码'); // 返回Promise对象 return new Promise(function(resolve, reject) { if (typeof want == 'function') { resolve(want); } else { reject('TypeError: '+ want +'不是一个函数') } }) } fn(want).then(function(want) { want(); }) fn('1234').catch(function(err) { console.log(err); })
这三种状态不受外界影响,而且状态只能从pending改变为resolved或者rejected,并且不可逆。在Promise对象的构造函数中,将一个函数作为第一个参数。而这个函数,就是用来处理Promise的状态变化。
上面的resolve和reject都为一个函数,他们的作用分别是将状态修改为resolved和rejected。
二、then方法的执行结果也会返回一个Promise对象。因此我们可以进行then的链式执行,这也是解决回调地狱的主要方式。
then(null, function() {}) 就等同于catch(function() {})
function fn(num) { return new Promise(function(resolve, reject) { if (typeof num == 'number') { resolve(); } else { reject(); } }) .then(function() { console.log('参数是一个number值'); }) .then(null, function() { console.log('参数不是一个number值'); }) } fn('hahha'); fn(1234);
三、Promise中的数据传递
四、Promise.all
当有一个ajax请求,它的参数需要另外2个甚至更多请求都有返回结果之后才能确定,那么这个时候,就需要用到Promise.all来帮助我们应对这个场景。
Promise.all接收一个Promise对象组成的数组作为参数,当这个数组所有的Promise对象状态都变成resolved或者rejected的时候,它才会去调用then方法,
var url = 'https://hq.tigerbrokers.com/fundamental/finance_calendar/getType/2017-02-26/2017-06-10'; var url1 = 'https://hq.tigerbrokers.com/fundamental/finance_calendar/getType/2017-03-26/2017-06-10'; function renderAll() { return Promise.all([getJSON(url), getJSON(url1)]); } renderAll().then(function(value) { // 建议大家在浏览器中看看这里的value值 console.log(value); })
五、 Promise.race
与Promise.all相似的是,Promise.race都是以一个Promise对象组成的数组作为参数,不同的是,只要当数组中的其中一个Promsie状态变成resolved或者rejected时,就可以调用.then方法了。而传递给then方法的值也会有所不同,大家可以再浏览器中运行下面的例子与上面的例子进行对比。
function renderRace() { return Promise.race([getJSON(url), getJSON(url1)]); } renderRace().then(function(value) { console.log(value); })
作者:这波能反杀 链接:前端基础进阶(十五):透彻掌握Promise的使用,读这篇就够了 - 简书 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Git远程操作详解 | 涵月天-microzz.com | IT技术分享
-
模块Modules
ES6 模块不是对象,而是通过
export
命令显式指定输出的代码,再通过import
命令输入。// ES6模块 import { stat, exists, readFile } from 'fs';
上面代码的实质是从
fs
模块加载 3 个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。ES6 模块与 CommonJS 模块的差异
讨论 Node.js 加载 ES6 模块之前,必须了解 ES6 模块与 CommonJS 模块完全不同。
它们有三个重大差异。
-
CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。
-
CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
-
CommonJS 模块的
require()
是同步加载模块,ES6 模块的import
命令是异步加载,有一个独立的模块依赖的解析阶段。
第二个差异是因为 CommonJS 加载的是一个对象(即
module.exports
属性),该对象只有在脚本运行完才会生成。而 ES6 模块不是对象,它的对外接口只是一种静态定义,在代码静态解析阶段就会生成。 -
-
-