JS内功修炼(es6篇) 之 let、const、arrow function、class

262 阅读2分钟

let、const变量声明

1.1 const可以用来声明一个常量 必须在声明时进行赋值操作,const声明的变量不能修改

// 在ES5中如何声明一个常量呢?
Object.defineProperty(window, name, {
    value: 'phil',
    writable: false
})
// ES6
const name = 'phil'
//当const声明的变量是一个引用类型的时候,则可以修改,因为引用类型指向的是内存地址,那么怎么实现引用类型的不可修改呢?
//核心api Object.freeze()
const obj = { name: 'phil', info:{ sex: 1, habby: [ 'singing', 'playing' ] } }
function deepFreeze( obj = {}) {
    Object.freeze(obj)
   (Reflect.ownKeys(obj) || []).forEach( item => {
       if( typeof obj[item] === 'object' && obj[item] !== null ){
           deepFreeze(obj[item])
       }
   })
}

1.2 const存在块级作用域,不会变量提升

const flag = true
if( flag ){
   const name = 'phil'
}
console.log(name) // undefined

1.3 dead zone(暂时性死区):js中const或者let先使用后声明导致报错的这种现象叫做暂时性死区。因为js是单线程的,报错后面的代码不会执行。

const flag = true
if( flag ){
   console.log(name) // Cannot access 'name' before initialization
   const name = 'phil'
}

2.1 let 可以只声明不赋值,但是不可以重复声明,不存在变量提升,有块级作用域。

使用原则:尽量使用const声明一个变量,当要去对这个变量进行再次赋值的时候,再去将const改成let。

Arrow Function

基本结构

  // ES5
  const sum = function(a, b) { 
      return a + b
  }
  // ES6
  const sum = (a, b) => a + b

箭头函数上下文场景---> this

1、dom操作cb

 <button id='btn'></button>
 const btn = document.querySelector('#btn')
 btn.addEventListener('click', () => {
    // 这样是不行的,因为拿不到this
    this.style.width ='100px' 
 })

2、类操作

   // 1.箭头函数不能作为构造函数 像下面这样使用箭头函数是不行的。
   const Person = (name, age) => {
      this.name = name
      this.age = age
   }
   // 2.无法定义原型方法 这样写原型方法也是不行的,无法访问到this
   Person.prototype.call = () => {
      console.log(`${this.name}`)
   }

箭头函数参数

  const sum = ( a, b ) => {
      console.log(arguments) // 报错:arguments is not defined
  }
  sum(1,2)

class

是ES6提供的一个语法糖

  // 在ES5中声明一个构造函数
  function Person(name, age) {
      this.name = name
      this.age = age
  }
  Person.prototype.call = function () {
     console.log('calling')
  }
  
  Person.say = function(){
      console.log('saying')
  }
  
  // 在ES6中使用class语法
  class Person {
      constructor(name, age) {
        this.name = name
        this.age = age
      }
      call() {
        console.log('calling')
      }
      
      // 静态方法 构造函数可以直接调用 无需通过实例来进行调用
      static say(){
          console.log('saying')
      }
  }

提问

1.1 class是什么类型?

console.log(typeof Person) // function

1.2 class是否有prototype?

console.log(Person.prototype) // 与es5中构造函数的prototype一致

1.3 class可以使用对象方法&属性么? --> 可以

console.log(Person.hasOwnProperty('name')) // true

1.4 在class中如何建立一个只读变量 一、通过闭包的方式实现

class Person {
  constructor(name, age) {
      this.name = name
      this.age = age
      let _status = false
      
      this.getStatus(){
         retrun _status
      }
    }
}

二、通过getter实现

class Person {
  constructor(name, age) {
    this._name = name
    this.age = age
  }
  get name() {
    return this._name
  }
}

三、通过static实现

class Person {
  #gender = 'male';
  constructor(name, age) {
    this._name = name
    this.age = age
  }
  get gender() {
    return this.#gender
  }
}
const p = new Person('phil', 25)

js - 继承

// ES5 实现继承
function Person(name, age) {
   this.name = name;
   this.age = age;
}
Person.prototype.call = function(){
   console.log('calling')
}

function Chinese(skin){
   this.skin = skin
}

Chinese.prototype = Person.prototype

// ES6实现继承 ---> 很明显 缩短了篇幅, 实现了相同的功能 所以说 class 是一个function 的语法糖。
class Person {
  constructor(name, age) {
      this.name = name;
      this.age = age
  }
  call(){
      console.log('calling')
  }
}

class Chinese extends Person {
    constructor(skin){
        super()
        this.skin = skin
    }
}

--------------------- 0724 end ---------------------------