1.前端ES新特性详解笔记

本文为拉勾网大前端高薪训练营第一期笔记


let const var

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

ps:mozilla解释真的是太详细了

var会提升到代码最前声明,但是不赋值
let不会

var会全局变量
let只会在块作用域里

const就是常量的let,必须在声明时赋值

数组解构

数组解构可以简化代码

对象解构

对象解构可以:anotherName换变量名

模板字符串

模板字符串方便拼接字符串和变量

带标签的模板字符串可以增加额外操作,不过最后return的拼接略显麻烦

字符串扩展方法

字符串的扩展方法includes startsWith endsWith,比较好用,不过lodash的这几个可以处理string undefined的情况

参数默认值

参数默认值function(a=1){}很方便处理空输入的情况

提取参数

剩余参数…rest便捷提取剩余参数,或者是便捷传递给后续模块

展开数组 同上

附加知识 call apply bind的区别

func.call apply bind
call和apply第一个传参是context,第二个有所不同call是依次,apply是array
bind是把function变成不立马执行,执行时用第一个传参当context

箭头函数

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

简写函数,x ⇒ x+1

Before arrow functions, every new function defined its own this value based on how the function was called

An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules. So while searching for this which is not present in the current scope, an arrow function ends up finding the this from its enclosing scope.

我的理解是()⇒{} 等效于(function(){}).bind(this),箭头函数的this在定义的时候决定,普通function的this是在执行时决定,setTimeout其实是window.setTimeout.bind(window, function(){}, 1000),导致这种时候this是window

有两种scope,global和local,local有两种function scope and block scope

function scope顾名思义,block scope就是{},这个里的const let传不出去

举例

for (var i=1; i<=5; i++) {
  setTimeout(function(){
    console.log("i: " + i);
  },i*1000);
}

拿到的是6 6 6 6 6,

解决方法是

IIFE:Immediately-invoked Function Expression

可以隔离变量,生成新的i

for (var i=1; i<=5; i++) {
  (function(i){
    setTimeout(function(){
      console.log("i: " + i);
    }, i*1000);
  })(i);
} // 1 2 3 4 5

或者

使用let,此时每个循环都有一个新的i

for (let i=1; i<=5; i++) {
  setTimeout(function(){
    console.log("i: " + i);
  }, i*1000);
}
// 1 2 3 4 5

支持rest parameters和default paraments

(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { 
statements }

Destructuring within the parameter list is also supported

var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;

箭头函数不允许call apply传入this,会无视掉

没有arguments,想用的话用剩余参数

var f = (…args) => args[0] + n;

对象字面量增强

一些定义key的简写

const bar = ‘345’

const obj = {
bar,
// 方法可以省略 : function
method1 () {
},
[bar]: 123
}

Object.assign()

const result = Object.assign(target, source1, source2)

可以用于对象浅拷贝

Object.is() 高级版的===,解决一些===都判断不出来的情况

  // +0 === -0               // => true
  // NaN === NaN             // => false
  // Object.is(+0, -0)       // => false
  // Object.is(NaN, NaN)     // => true

Proxy给对象增加监视

getPrototypeOf: Object.getPrototypeOf()

setPrototypeOf: Object.setProtoTypeOf()

isExtensible: Object.isExtensible()

preventExtensions: Object.preventExtensions()

getOwnPropertyDescriptor: ObjectgetOwnPropertyDescriptor()

defineProperty: Object.defineProperty()

has: in operator

get: getting property values

set: setting property values

deleteProperty: delete operator

ownKeys: Object.getOwnPropertyName and Object.getOwnPropertySymbols

apply: function call

construct: new operator

Reflect

Reflect.apply(target, thisArgument, argumentsList)
//Calls a target function with arguments as specified by the argumentsList parameter.

Reflect.construct(target, argumentsList[, newTarget])
//The new operator as a function. Equivalent to calling new target(…argumentsList).

Reflect.defineProperty(target, propertyKey, attributes)
//Similar to Object.defineProperty(). Returns a Boolean that is true if the property was successfully defined.

Reflect.deleteProperty(target, propertyKey)
//The delete operator as a function. Equivalent to calling delete target[propertyKey].

Reflect.get(target, propertyKey[, receiver])
//Returns the value of the property. Works like getting a property from an object (target[propertyKey]) as a function.

Reflect.getOwnPropertyDescriptor(target, propertyKey)
//Similar to Object.getOwnPropertyDescriptor(). Returns a property descriptor of the given property if it exists on the object, undefined otherwise.

Reflect.getPrototypeOf(target)
//Same as Object.getPrototypeOf().

Reflect.has(target, propertyKey)
//Returns a Boolean indicating whether the target has the property. Either as own or inherited. Works like the in operator as a function.

Reflect.isExtensible(target)
//Same as Object.isExtensible(). Returns a Boolean that is true if the target is extensible.

extensible指的是can new properties be added to an object

Make object not extensible

Object.preventExtensions(), Object.seal(), or Object.freeze().

freeze完全不能修改,seal只是不能增加和删除property

Reflect.ownKeys(target)
//Returns an array of the target object’s own (not inherited) property keys.

Reflect.preventExtensions(target)
//Similar to Object.preventExtensions(). Returns a Boolean that is true if the update was successful.

Reflect.set(target, propertyKey, value[, receiver])
//A function that assigns values to properties. Returns a Boolean that is true if the update was successful.

Reflect.setPrototypeOf(target, prototype)
//A function that sets the prototype of an object. Returns a Boolean that is true if the update was successful.

promise解决传统异步编程中回调函数嵌套过深的问题

Set

add clear delete entries forEach has keys values [@@iterator]()

const mySet = new Set();
const setIter = mySet[Symbol.iterator]()
console.log(setIter.next().value)

Set to Array

const arr = []

Array.from(new Set(arr))

[…new Set(arr)]

Symbol

Symbol 两个 Symbol 永远不会相等,除非是Symbol.for(true) === Symbol.for(‘true’) 或者是Symbol.for(‘foo’) === Symbol.for(‘foo’)

const symbol = Symbol(‘foo’)

遍历数据结构

for in,Object.keys(), JSON.stringify()都拿不到symbol key,只有Object.getOwnPropertySymbols(obj)能拿到

for用于array, for in用于object,将来都用for of

需要注意的是for of用于Map的时候每次拿到的是[key, value]

普通obj不能用for of

//便捷写法
// for (const [key, value] of m) {
//   console.log(key, value)
// }

只有Iterable的数据类型才能for of

Iterable是指实现了[Symbol.iterator]的数据类型

Iterator是return next的那个function

const obj = {
  store: ['foo', 'bar', 'baz'],

  [Symbol.iterator]: function () {
    let index = 0

    return {
      next: ()=>{
        const result = {
          value: this.store[index],
          done: index >= this.store.length
        }
        index++
        return result
      }
    }
  }
}

实现迭代器接口的意义是统一遍历接口,外部不需要考虑内部数据结构

生成器Generator

Generator yield是惰性抽一次动一次,return是直接结束

ES2016新元素

ES2016增加了

  • 数组的includes

arr.includes(‘foo’)

  • 指数运算符

2 ** 10 === Math.pow(2, 10)

ES2017新元素

  • Object.values(obj)

Object.entries(obj),用这个转一次就能for of了

for (const [key, value] of Object.entries(obj)) {
   console.log(key, value)
 }
  • Object.getOwnPropertyDescriptors拿到是完整的描述信息
// const p1 = {
//   firstName: 'Lei',
//   lastName: 'Wang',
//   get fullName () {
//     return this.firstName + ' ' + this.lastName
//   }
// }

// // console.log(p1.fullName)

// // const p2 = Object.assign({}, p1)

此时p2里fullName: 'Wang Lei’是一个key value,并不是getter function

  • string的padStart()和padEnd()

const name = ‘123’

name.padStart(10, ‘-’)

name.padEnd(5, 0)

  • 函数参数最后一个可以加逗号

本文为拉勾网大前端高薪训练营第一期笔记

你可能感兴趣的:(前端,ES2015)