开发环境搭建
-
安装babel-cli、babel-preset-env
-
根目录下配置.babelrc
{ "presets": ["env"] }复制代码
-
转换
babel xx.js -o xx.js复制代码
当然我们也可以借助webpack、gulp来实现转换
let、const
let关键字提供了除var以外另一种变量声明方式,可以将变量绑定到所在的任意作用域中(通常是{...}内部),换句话说,let为其声明的变量隐式地劫持了所在的块级作用域。
{ let bar = 2}console.log(bar) //ReferenceError复制代码
let进行的声明不会在作用域中进行提升
{ console.log(bar) //ReferenceError let bar = 2}复制代码
let不允许重复命名
let bar = 2let bar = 3 // error复制代码
let循环
for (let i=0; i<3; i++) { console.log(i) } console.log(i) // ReferenceError /*let不仅将i绑定到for循环块中,并重新绑定到循环的每一迭代中,确保上一个循环迭代结束时的值重新赋值*/复制代码
const 同样可以创建块级作用域,但是之后任何试图修改的操作都会报错
const bar = 2bar = 4 // ReferenceError复制代码
变量的解构赋值(模式匹配)
数组:元素按次序排列,变量取值由位置决定
let [a, b, c] = [1, 2, 3] // a-1, b-2, c-3let [a, ...b] = [1, 2, 3] // a-1, b-[2, 3]复制代码
对象:变量名必须和属性名相同
let {foo, bar} = {foo: 1, bar: 2} // foo-1, bar-2复制代码
字符串
const [a, b, c, d, e] = 'devin' // a-d, b-e, c-v, d-i, e-nlet {length: len} = 'devin' // len-5 length属性复制代码
函数
function foo([x, y]) { do sth } foo([1, 2])复制代码
扩展运算符和rest运算符
扩展运算符
let arr1 = [1, 2, 3]let arr2 = [...arr1]console.log(arr2) // [1, 2, 3]let {x, y, ...z} = {x: 1, y: 2, a: 3, b: 4} // x-1, y-2, z-{a: 3, b: 4}复制代码
rest运算符
function foo (...arg) { console.log(arg.length)}foo(1, 2, 3) // 3复制代码
字符串扩展
模版字符串
const name = 'welllee'console.log(`hello ${name}, how r u ?`) // hello welllee, how r u ?复制代码
字符串遍历
const name = 'welllee'for (let item of name) {console.log(item)} // w e l l l e e// 补充for...of1.区别于forEach(),可以正确响应return, break, continue2.遍历map, set对象(需解构) for (let [key, value] of xxx) {console.log(key, value)} 3.不支持普通对象(使用Object.keys()) for (let key of Object.keys(xxx)) { console.log(key, xxx[key]) }复制代码
at
'welllee'.at(1) // e 类似charAt()复制代码
includes 查找字符串
'welllee'.includes('w') // true 类似indexOf()复制代码
startsWith & endsWith 开头&结尾是否存在xxx
'welllee'.startsWith('w') // true'welllee'.endsWith('e') // true复制代码
repeat 复制字符串
'welllee'.repeat(2) // wellleewellee复制代码
数值的扩展
Number.isFinite() 数字验证
Number.isNaN() NaN验证
Number.parseInt() 整型转换
Number.parseFloat() 浮点型转换
Number.isInteger() 数值是否为整数
Math.trunc() 去除小数部分,返回整数部分
Math.sign() 判断一个数是整数,负数,还是0。正数返回+1,负数返回-1,0返回0, -0返回-0,其他返回NaN
数组的扩展
Array.from() 将伪数组转为数组
还可以用[].slice.call()复制代码
Array.of() 将一组值专为数组
Array.of(1, 2, 3) // [1, 2, 3]复制代码
find() 找出数组中的成员
[1, 2, 3].find((value, index, array) => { return value > 1}) // 2找到后就return,停止查找复制代码
fill(value, start, end) 使用给定值填充数组
[1, 2, 3].fill('a', 1, 2) // [1, 'a', 3]复制代码
entries()键值对遍历、keys()键名遍历、 values()键值遍历
for (let [index, elem] of ['a', 'b'].entries()) { console.log(index, elem) // 0 'a', 1 'b'}for (let index of ['a', 'b'].keys()) { console.log(index) // 0, 1}for (let elem of ['a', 'b'].values()) { console.log(elem) // 'a', 'b'}复制代码
数组的空位
forEach(), filter(), every() 和some()都会跳过空位map()会跳过空位,但会保留这个值join()和toString()会将空位视为undefined,而undefined和null会被处理成空字符串复制代码
函数的扩展
默认参数
function foo (a, b = 1) { return a + b}foo(1) // 2复制代码
扩展运算符和rest运算符(上文已提及)
主动抛出错误
{ throw new Error('出错啦~')}复制代码
严格模式
'use strict'在严格模式下使用默认参数会报错复制代码
获取需要传递参数的个数
function foo (a, b) {do sth}foo.length // 2复制代码
箭头函数
const foo = (a, b) => a + bfoo (1, 2) // 3(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用Rest参数代替。(4)不可以使用yield命令,因此箭头函数不能用作Generator函数。复制代码
对象的扩展
Object.is(val1, val2) 比较两个值是否相等
let a = {xx: 1}let b = {xx: 1}console.log(Object.is(a.xx, b.xx)) // true复制代码
Object.assign() 对象的合并,实行的是浅拷贝
let a = {xx: 1}let b = Object.assign({}, a)console.log(b) // {xx: 1}复制代码
Object.keys() object.values() object.entries()
参考上文数组的遍历复制代码
set & map
set类似于数组,但是成员的值都是唯一的,可以用来数组去重,set本身是一个构造函数,用来生产set数据结构。
数组去重复
const item =new Set([1,2,3,3]) console.log([...item]) // [1,2,3]复制代码
set属性:
Set.prototype.constructorSet.prototype.size复制代码
set方法:
add() delete() has() clear()复制代码
遍历:
keys() values() entries() 复制代码
map类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。
可以使用扩展运算符(...)将Map转换为数组,反过来,将数组传入 Map 构造函数,就可以转为 Map了。
map方法:
set(key,value)get(key)delete(key)has(key)clear()复制代码
遍历:
keys() values() entries() forEach()复制代码
symbol
1.symbol可以用symbol函数生成,可以作为对象的属性名使用,保证不会与其他属性重名
let a = Symbol()let b = Symbol()let obj = { [a] : 'no 1'}obj[b] = 'no 2'复制代码
2.symbol函数可以接受一个字符串作为参数
let s = Symbol('a')let q = Symbol('a')console.log(s === q) // false复制代码
3.symbol值不能与其他类型的值进行运算,但是可以转为bool值
4.symbol作为属性名,不会被for-in,for-of遍历得到,不会被 object.keys(),json.stringify() object.getOwnPropertyNames()返回,但是可以通过object.getOwnPropertySymbols()方法获取对象的所有symbol 属性名
类
class People { constructor (name) { //构造函数 this.name = name } say () { //方法 console.log('xxx') }}继承class Student extends People { constructor () { }}复制代码
promise
一个容器,保存着未来才会结束的事件
promise构造函数接受一个函数作为参数,该函数的两个参数(resolve,reject)也是函数
resolve 将promise对象状态从未完成到成功,reject将promise对象状态从未完成到失败
function test (val) { return new Promise(function (resolve, reject) { if (条件) { resolve(结果) } else { reject(错误) } })} test('xxx').then(res => {//})复制代码
generator
由function*来定义,除了return 语句,还可以用yield返回多次
直接调用generator仅仅是创建了一个generator对象,并没有去执行它
执行它有2个方法:
-
不断的调用next(),每次遇到yield就返回一个对象{value:,done:true/false},当done的值是true就是返回return的值
-
for....of循环迭代generator对象的方法
function* fib(max) { var t, a=0, b=1, n=1; while (n < max) { yield a; t = a +b; a = b; b =t; n ++; } return a; } for (let x of fib(5)) { console.log(x) // 0, 1, 1, 2, 3 }复制代码
用Proxy进行预处理
var target = { name: 'xxx' }; var handler = { get: function(target, key) { console.log(`${key} 被读取`); return target[key]; }, set: function(target, key, value) { console.log(`${key} 被设置为 ${value}`); target[key] = value; } } var aaa = new Proxy(target, handler) aaa.name // name被读取 'xxx' aaa.name = 'welllee' // name被设置为welllee 'welllee' 补充:vuejs 数据双向绑定原理复制代码
严格模式
变量必须声明后再使用
函数的参数不能有同名属性,否则报错
不能使用with语句
不能对只读属性赋值,否则报错
不能使用前缀0表示八进制数,否则报错
不能删除不可删除的属性,否则报错
不能删除变量delete prop,会报错,只能删除属性delete global[prop]
eval不会在它的外层作用域引入变量
eval和arguments不能被重新赋值
arguments不会自动反映函数参数的变化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局对象
不能使用fn.caller和fn.arguments获取函数调用的堆栈
增加了保留字(比如protected、static和interface)