ES6入门

1. let、const,用法和var一样

1. 作用域不同

function fn(){
  if(true){
    console.log(a)
  }else{
    var a 
  }
}

fn()  //undefined,因为var a变量提升了

var除了在函数里是局部变量,在其它地方声明都是全局变量。
用let来声明变量,只在自己所在的代码块内有效。

//例1
{
  let a = 10;
  var b = 1;
  {
    console.log(a)    
    //a is not defined,a既不会跑到外面,也不会到里面来
  }
}
a // a is not defined.
b // 1

//例2
for (let i = 0; i < 3; i++) {
  let i = 'abc';  //这个i和上面的数字i不互相影响
  console.log(i);
}
// abc
// abc
// abc
  1. const
    声明一个变量只能赋值一次,且必须在声明的时候赋值
    const a = 1
    a = 2 //报错
    const b;   //报错
    

3. let、const不会变量提升!

  1. 面试题1
var a = 1
function fn(){
    console.log(a)
}
a = 2
fn()  //2
  1. 面试题2
for(var i=0;i

不管点第几个都会输出liTags.length,可以改成下面这样

for(let i=0;i

这样点第几个就输出几

2. 解构赋值

  • 交换两个变量的值

    let a = 1;
    let b = 2;  //这里必须加分号,下面的方括号会自动往前提一行
    [a,b] = [b,a]
    
  • 对象

    //es5
    let options = response.options
    let method = options.method;
    //es6
    let {method} = options
    //es6,下面一行等于上面es5的两行
    let {options:{method}} = response; 
    
  • 若是用在函数里:

    function name1(response){
      let {human:{name2}} = response;  
      console.log(name2)
    }
    
    //简化为下面,直接把这个当参数可以省略response
    function({human:{name2}}){}
    

    奇异写法:

    function name1(response){
      let {human: man='default'} = response;  
      console.log(man)
      //等于重命名human,man === response.human
      //default是默认值
    }
    
  • 默认参数

    let [a=1,b=2] = [23]
    //前面写的是默认值,若后面没有则用默认值
    // a === 23, b === 2
    
    let [a, ,b] = [1,2,3]
    //a === 1, b === 3
    

3. 对象里的函数

//es5 
object{
  go: function(){
  }
}

//es6
object{
  go(){
  }
}

4. ...语法(部分移动端不支持)

function sum(...numbers){console.log('numbers',numbers)}
sum(1,2,3,4)  
//[1,2,3,4],numbers是一个真正的数组

function sum(message,...numbers){console.log('numbers',numbers)}
sum('hello',1,2,3,4)  
//[1,2,3,4],numbers代表除第一个外的所有参数
//三个点的那一项必须在最后一位
  • 拷贝(只有根属性是深拷贝)
var a = {name: 'pyz'};
var b = {c1:1, c2:2 ,c3:3}
var c  ={...a,...b}  //相当于存了a和b里的所有属性
//c === {name: 'pyz', c1: 1, c2: 2, c3: 3}

//若不写...,则相当于给c里存了两个对象
c = {a,b}

//合并a和b
var a = {apple: 1,ban: 2}
var b = {ban: 1,curry: 3}
var c = {...a,...b}

这个语法能把伪数组变为真数组

function a() { 
    let args = [...arguments]
    console.log(args)
} 

还能进行展开操作

let array = [1,2,3,4,5];
let [,,...array2] = array;
array2  //[3,4,5]

let array3 = [0 , ...array , 6];
array3 //[0,1,2,3,4,5,6]

5. 将伪数组变为数组

let args = Array.from(arguments)  
//把伪数组变成真数组,还可以用[...arguments]

Array.from({length:4})
//[undefined,undefined,undefined,undefined]
  • 面试题
function x(n,fill){
  let a = Array.from({length: n})
  return a.map(v=>fill)
}

x(6,6)
//[6,6,6,6,6,6]

还可以用fill

function x(n,fill){
  return Array.from({length: n}).fill(fill)

}
//把数组所有位置都替换成6

let a = [1,2,3]
a.fill(7,1)
//把1后面的替换成1

6. 新字符串


这个字符串支持回车,之前的不能回车,结果包含4个回车。

  • 还可以插值

  • 函数后接新字符串
let name = 'p'
let person = 'y'
function fn(){
  console.log(arguments)
}
fn`${name}可以${person}`

这个功能在react的style-component库用到了!

7. Symbol

用来创建独一无二的值

let race = {
  神族: Symbol() , 人族: Symbol(), 虫族: Symbol()
}

race.神族 === race.人族  //false

8. 迭代器和发布器

  • 迭代器(es5)
function createIterator(items) {
    var i = 0;
    return {
        next: function() {
            var done = (i >= items.length);
            var value = !done ? items[i++] : undefined;
            return {
                done: done,
                value: value
            };
        }
    };
}
var iterator = createIterator([1, 2, 3]);
console.log(iterator.next()); // "{ value: 1, done: false }"
console.log(iterator.next()); // "{ value: 2, done: false }"
console.log(iterator.next()); // "{ value: 3, done: false }"
console.log(iterator.next()); // "{ value: undefined, done: true }"
  • 生成器(es6,是迭代器的语法糖)
function * 生成器(){
  let version = 0;
  while(true){
    version += 1
    yield version
  }
}

let a = 生成器()
a.next()  //{value: 1,done: false}
a.next()  //{value: 2,done: false}
  • for ... of
    数组可以迭代,对象不行,就因为没有Symbol.iterator
let a = [1,2,3]
a[Symbol.iterator]  //f()...

let o = {1:'a',2:'b'}
o[Symbol.iterator]  //undefined

若自己给对象添加Symbol.iterator属性,则对象也可以迭代,如下

o[Symbol.iterator] = function *(){
  let keys = Object.keys(object)
  for(let i=0;i

for ... of ...的用法

let a = [1,2,3]
for(let o of a){
  console.log(o)  
}
//1 2 3

9. 对象

  • Object.create(null)
let a = Object.create(null)
//创建一个新对象,里面没有Object.prototype 

若要使它指向Object的原型,可以想下面这样

let a = Object.create(Object.prototype)

这样就等价于a = {}a = new Object()
参数里写的东西会放进a的__proto__里

  • 对象的属性可以是变量
var name = 'a'
let o = {[name]:1}
//对象属性可以这样引用变量

var n = 1
let o = {
  [n*2]:123
}

o  //{2:123}
  • 新对象!可以自己控制对象读和写的操作
o = {
  _age: 18,
  get age(){return o._age},
  set age(value){ if(value<100){o._age = value}}
}

像下面这样写,这样可以使a==1&&a==2&&a==3为true

var i=0
Object.defineProperty(window,'a',{
  get(){
    i += 1
    return i
  }
})

a==1&&a==2&&a==3

若只给get()属性,则这个对象是只读的

o ={
    get name(){return '只读'}
}

o.name = 1
console.log(o.name)  //'只读',是无法改变的
  • Object.defineProperty()
    这个API可以将对象改造为新对象
let a = {a:'a',b:'b'}
Object.defineProperty(a,'x',{
  get(){},
  set(value){}
})

还可以定义对象为只读

Object.defineProperty(a,'name',{
  writeable: false,  //这个属性是只读的
  value: 'pyz',
  configurable: false  
  //无法再对这个对象里面的属性更改
  enumerable: false  //遍历时不会显示出来
})
  • Object.getPrototypeOf(a)
    获取一个对象的原型,相当于a.__proto__

  • Object.defineProperties()
    可以一次性定义多个

Object.defineProperty(a,{
  'name': {
    writeable: false,
    value: 'pyz',
    configurable: false  
    //无法再对这个对象里面的属性更改
    enumerable: false  //遍历时不会显示出来
  },
  'age':{
    value: 18
  }
})

vue的双向绑定就是靠这个API实现的!

  • Object.keys(a)
    这样会把a的属性作为一个数组返回

  • Object.entries(a)
    这样是把a的每个属性和值放在一个数组里,然后返回一个大数组里有很多小数组

  • Object.freeze()

let o = {a:1}
let o2 = Object.freeze(o)

这样o2的所有属性则不能被改动了

10. Symbol可以当作对象的key

10. 浅拷贝

  • Object.assign
let o  = {a:'a',b:'b',c:'c'}
let object = Object.assign({},o)
//这样o上所有属性就拷贝到object上了
//仅有根属性是深拷贝
  • ...
let o  = {a:'a',b:'b',c:'c'}
let object = {...o}
//和上面Object.assign一样

11. ES6模块化

  • index.html
 
//这里一定要写type=module
  • main.js
import module1 from './1.js'
import {say} from './2.js'

setTimeout(function(){
  module1()
},2000)
setTimeout(function(){
  module2()
},3000)
  • 1.js
let name = 'pyz'
let module1 = function(){
  console.log('name1:',name);
}
export default module1

用 export default 的方法导出,你在其他文件引用时就可以自定义名字

  • 2.js
let name = 'jpj'
let say = function(){
  console.log('name2:',name);
}
export {name,say}
export default say

这样导出时,引用可以import x,{name,say} from './2.js'
若导出的局部变量名重复了,可以如下这样

import {name as name1} from './1.js'
import {name as name2} from './2.js'
  • import * as all from './1.js'
    导入所有的,名字是all

12. 若浏览器不支持import语法,使用parcel

  1. npm init -y
  2. npm install -g parcel-bundler
  3. parcel index.html
  4. 访问给出的地址,parcel就已经帮你把es6新语法转化为IE支持的语法了

13. 类

class Person{
  constructor(name,age){  //自有属性
    this.name = name;
    this.age = age;
  }  //不用写逗号
  walk(){}
}

类可以继承

class Animal{
  constructor(species){
    this.species = species  
    this._race = '动物'
  }
  say(){
    console.log('我是动物')
  }
  get race(){  //读取race值
    return this._race
  }
  static die(){  
  //静态方法只能通过Animal.die()访问到
    console.log('灭绝')
  }
  set race(value){  
  //设置race值,如果没有set则不能改这个值
  //set里还可以加if(),来限制各种条件
    this._race = value
  }
}

class Person extends Animal{  //继承原型
  constructor(species,name,age){  
    super(species)  //继承自有属性
    this.name = name;
    this.age = age;
  }  //不用写逗号
  walk(){}
  say(){
    super.say()  //'我是动物'
    console.log('人')
  }
}

14. Promise

15. async/await

function takeLongTime() {
    return new Promise(resolve => {
        setTimeout(() => resolve(1), 1000);
    });
}

async function test() {
    let v = await takeLongTime();
    console.log(v);
    console.log(2)
}

test();

async/await必须和promise结合使用

16. Set

Set是一个对象,会自动去重

new Set([1,2,3,4,5,5,5,5])
//{1,2,3,4,5}

17. Map

Map也是对象,它可以把对象当作key,还可以用for...of...迭代!

let myMap = new Map()
let key = {}
let value = 1
myMap.set(key,value)  //key可以是对象

myMap.get(key)  //获得value

for(let i of myMap){
    console.log(i)  //会打印出key和value
}

for(let i of myMap.values){
    console.log(i)  ////会打印出value
}
for(let i of myMap.keys){
    console.log(i)  ////会打印出value
}
for(let i of myMap.entries){
    console.log(i)  ////会打印出value
}

myMap.forEach((value,key)=>{
})

18. weakSet

弱引用,没法读取对象里所有的值

19. weakMap

弱引用

20. 新API

  • fill
let a = ['a','b','c']
a.fill(3)  //[3,3,3]
a.fill(2,1)  //[3,2,2,]
  • find
a.find(item=>item===2)  //2

find查到第一个就返回,用filter可以查找所有

  • findIndex
let a= [3,3,3,2]
a.findIndex(item=>item===2)  //3
  • entries/keys/value
    可迭代对象
let a = [1,2,3]
let aa = a.values
a.next.value  //1
a.next.value  //2
a.next.value  //3
  • includs
let a = 'apple'
a.includes('ap')  //true
a.includes('b')  //false

a.indexof('a') >= 0也是一样的效果
a.search('a') >= 0也是一样的效果,但search可以用正则,a.search(/a/) >= 0

  • repeat
let s = 'a'
s.repeat(2)  //'aa'
  • Number.EPSILON
    JS可做到的最小误差
let i=0
while(Math.abs(i-1)
  • Number.isInteger
Number.isInteger(1)  //true
  • Number.isFinite
    判断是不是有限数字
  • Number.isNaN
    Number.isNaN(NaN) //true
    判断是不是NaN,还有一个老的是window.isNaN

你可能感兴趣的:(ES6入门)