ES6中常用特性

1,028 阅读3分钟

wecom-temp.jpg

1. ECMAscript2015 共有三种作用域

  • 全局作用域
  • 函数作用域
  • 块级作用域(新增)

2. 变量声明: let const

  • let const 都是块级作用域,let是变量,const是常量
var element = [{},{},{}]
for (var i = 0; i < element.length; i++){
	element[i].onclick = function () {
  	console.log(i)
  }
}
element[2].onclick()

// 通过 闭包
var element = [{},{},{}]
for (var i = 0; i < element.length; i++){
	element[i].onclick = (function (i) {
  	return function () {
    	console.log(i)
    }
  }){i}
}
element[2].onclick()

// 通过 let 块级作用域
var element = [{}, {}, {}]
for(let i = 0; i < element.length; i++) {
  // let定义的变量是块级作用域
  element[i].onclick = function () {
    console.log(i)
  }
}
element[2].onclick() // 2
  • let const 不会变量提升
console.log(foo) // undefined
var foo = 'jal'

console.log(foo2) // ReferenceError
let foo2 = 'jal'
  • const 值类型 不可更改 引用类型可增加属性
const arr = [1,2,3]
arr.push(4)

const arr1 = [1,2,3]
arr1 = []

const str = '123'
str = '4576'

3. 数组的解构

方括号 [] 中的变量按顺序匹配数组元素

// 传统方式
const arr = [1, 2, 3]
const a = arr[0]
const b = arr[1]
const c = arr[2]
console.log(a, b ,c) // 1 2 3

// 数组解构方式
const [a, b, c] = arr
console.log(a, b ,c) // 1 2 3

const [, , c] = arr
console.log(c) // 3

const [a, ...c] = arr // 三个点解构只能用于最后一个位置
console.log(c) // [ 2, 3 ]

const [a, b, c, d] = arr
console.log(d) // undefined

const [a, b, c = 123, d = 'defaultValue'] = arr
console.log(c, d) // 3 defaultValue


const path = 'a/b' 
const [, , b] = path.split('/')
console.log(b) // b

4. 对象的解构

const obj = {name: 'yibo', age: 22}
const {name} = obj
console.log(name) // yibo

const {name: objName, sex = 'boy'} = obj
console.log(objName, sex) // yibo boy

5. 模板字符串

const name = 'yibo'
const str = `this is ${name}`
console.log(str)

6. 模板字符串标签函数

const name = 'tom'
const gender = true

function myTagFunc (str, name, gender) {
  console.log(str, name, gender)  // [ 'hey, ', ' is a ', '.' ] tom true
  return str[0] + name + str[1] + gender + str[2]
}

const result = myTagFunc`hey, ${name} is a ${gender}.`
console.log(result) // hey, tom is a true.

7. 字符串方法

  • includes()
  • startsWith()
  • endsWith()

8. 函数默认值

// 带有默认值的参数要放在最后
function foo (enble = true) {
	console.log(enable)
}

foo(true)  // true
foo(false) // fasle
foo() // true

9. 剩余参数

剩余参数只能出现在形参的最后一位,而且只能使用一次

// ES5 之前用 arguments 接受剩余参数
function foo () {
	console.log(arguments)
}

// ES6 之后 可以使用 剩余参数 。。。 去接受,但是只能出现在形参最后一位, 而且只能使用一次
function foo (...args) {
	console.log(args)
}

foo(1,2,3) // [1,2,3]

10. 展开数组

const arr = ['foo', 'bar', 'baz']

console.log.apply(console, arr) // foo bar baz
console.log(...arr) // foo bar baz

11. 箭头函数

const inc = n => n + 1
console.log(inc(1)) // 2

const sum = (a, b) => {
	return a + b 
}
console.log(sum(1,2))
  • 箭头函数不会改变this指向,this为上层作用域的this(声明箭头函数所在的this指向)
const parson = {
	name: 'tom',
  sayHi: function () {
  	console.log(`hi, my name is ${this.name}`)
  },
  sayHiAnyc: function (){
  	setTimeout(function(){
    	console.log(`sayHiAsync: hi my name ins ${this.name}`)
    })
  },
	say: () => {
  	console.log(`hi my name is ${this.name}`)
  },
	sayHiAsync2: () => {
  	setTimeout(()=>{
    	console.log(`sayHiAsync2: hi my name is ${this.name}`)
    })
  }
}

12. 对象字面量增强

  • 属性名和属性值相同时,可以省略,只写属性名

  • 对象方法可以直接写函数形式,method(){} a: function () { }

  • 使用方括号的方式计算动态属性名

const bar = 111
const obj = {
	foo: 123,
  // bar: bar 
  bar,
  // method:function(){
  // 	console.log(`method: ${this}`)
  // },
  methods(){ // 直接写方法 同上面的冒号属性
  	console.log(`method: ${this}`)
  }
  [Math.radom()]:123 // 计算属性名
}

13. 对象扩展方法

  • Object.assign(target,source): 将多个源对象中的属性赋值到一个目标对象中
// Object.assign 用第二个参数的对象属性覆盖第一个参数的对象,返回结果为第一个对象
const source1 = {
	a: 'aaa',
  b: 'bbb'
}

const source2 = {
	a:'source2a',
  c:'ccc'
}

const target = {
	a:'targeta',
  b:'targetb'
}

const result = Object.assign(target,source1,source2)
console.log(result)
function fun(obj) {
    // obj.name = 'function.obj'
    // console.log(obj)
    const funObj = Object.assign({}, obj)
    funObj.name = 'function.obj'
    console.log(funObj)
}

const obj = {
    name: 'global obj'
}

fun(obj)
console.log(obj)
  • Object.is 对===的比较,+0不等于-0, NAN等于NAN
console.log(
  0 === false, // false
  0 == false, // true
  +0 ===-0, // true
  NaN === NaN, // false
  Object.is(+0, -0), // false
  Object.is(NaN, NaN) // true
)

14. 代理对像

ES5中有一个Object.defineProperty,Vue2就是通过这个实现数据双向绑定

ES6提供了Proxy,可以监视对象的读写过程,Vue3.0通过Proxy实现数据绑定

// 监视对象中某个属性的读写
const person = {
    name: 'zoe',
    age: 18
}
person.abvc 
// 第一个参数是需要代理的对象
const personProxy = new Proxy(person, {
    // 监听获取属性
    // target 所监听的对象, property 外接访问的属性名
    // return 作为外接访问的返回值
    get(target, property) {
        // console.log(target, property);
        // return 1
        return property in target ? target[property] : 'umderfind'
    },
    // set 监听设置属性
    set(target, property, value) {
        if(property === 'age') {
            if(!Number.isInteger(value)) {
                throw Error(`${value} is not init`)
            }
        }
        target[property] = value
        console.log(target, property, value);
    }
})
personProxy.age = 10
console.log(personProxy.name);

15.Object.definrProperty 与 Proxy 的区别

  • defineProperty 只能监视属性的读写,proxy 能监视到更多对象操作,例如delet 或者 对象方法的调用
const person = {
    name: 'zoe',
    age: 18
}

const personProty = new Proxy(person,{
    deleteProperty(target, property){
        console.log(target, property);
        delete target[property]
    }
})

delete personProty.age
console.log(personProty);

// =======================================
  • 对数组更好的支持
const list = [1,2,3,4]
const listProxy = new Proxy(list,{
    set(target,property,value) {
        target[property] = value
        console.log(target,property,value);
        return true
    }
})
listProxy.push(5)
  • proxy 是以非侵入的方式监管了对象的读写

16. Set 数据结构

  • 类似数组一样的结构,但是set 结构中的成员是不重复的

  • add() 用于增加set 数据,可以链式调用

  • size 获取 set 数据解构的长度

  • has ()判断集合是否存在某个特定的值

  • delete ()用于删除集合中某个特定的值

  • clear()清除集合中的数据

const s = new Set()

s.add(1).add(2).add(3)
console.log(s);
console.log(s.has(1));
s.delete(1)
console.log(s);
s.clear()
console.log(s);

// 常用于数组去重
const arr = [1,1,2,2,3,3,4]
// const result = Array.from( new Set(arr))
const result = [...new Set(arr)]
console.log(result);

17.Map 数据结构

  • 当我门为对象增加属性时,如果属性不是字符串格式的,我们对象内部会调用toString 方法 将键转换成字符串作为键值

  • 键值对集合,用来映射两个任意键值对之间的关系

  • Set () 设置数据

  • Get () 获取数据

  • Has () 判断某个键是否存在

  • Delete () 删除某个键

  • Clear () 清空所有的键值

// const obj = {}
// obj[true] = '123'
// obj[123] = '123'
// obj[{a: 1}] = '123'

// console.log(Object.keys(obj)); // 此时 对象作为键时 出现问题 [ '123', 'true', '[object Object]' ]

const m = new Map()
const tom = {name: 'tom'}
m.set(tom, '123')
console.log(m);
console.log(m.get(tom));
console.log(m.has(tom));
  • map 和对象的区别就是

  • map 可以使用任意数据结构作为键

  • 对象只能用字符串作为键

18. Symbol 数据结构,一种全新的原始数据类型

  • 表示独一无二的值
  • 为对象添加独一无二的属性名
  • 设置对象的私有属性成员
 const s = Symbol()
 console.log(typeof s);

 // 创建的每个值都是唯一的
 console.log(Symbol() === Symbol());

 // 允许传递一个字符串,作为symbol 对象的描述文本
 console.log(Symbol('a'));
 console.log(Symbol('b'));
 console.log(Symbol('c'));
 console.log(Symbol('d'));

 // 对象可以使用 symbol 属性作为对象的属性值
 const obj = {}
 obj[Symbol()] = '123'
 obj[Symbol()] = '345'
 console.log(obj);

 // 也可以使用对象字面量形式 直接在对象中使用symbol 作为我们对象的属性名
 const obj = {
     [Symbol()]: 123
 }
 console.log(obj);

// 模拟对象的私有成员
// a.js============
 const name = Symbol()
 const person = {
     [name]: 123,
     say() {
         console.log(this[name]);
     }
 }

// b.js============
 console.log(person[Symbol()]); // underfind
 person.say()

19. For of

const arr = [1,2,3]
for (const item of arr) {
  console.log(item) // 1,2,3
}

arr.forEach(item =>{
  console.log(item) // 1,2,3
})

// for of 比 forEach 的好处是 for of 可以随时终止循环
// forEach 是无法终止遍历的
for (const item of arr) {
  console.log(item)
  if(item > 10) {
    break
  }
}

// set map 都可以使用for of 遍历
const s= new Set([1,2])
for (const item of s) {
  console.log(item) // 1, 2
}

const m = new Map()
m.set('a',123)
m.set('b',123)
for(const item of m) {
  console.log(item) // [a,123],[b,123]
}
// 配合数组结构方式
for(const [key, value] of m) {
  console.log(key, value)
}

// for of 不能遍历对象 因为对象是不可迭代的
const obj = {a:123, b:345}
for(const item of obj) {
  console.log(item) // 此时会报错
}