美文网首页
JS:构造函数总结

JS:构造函数总结

作者: limengzhe | 来源:发表于2021-08-30 19:31 被阅读0次

    本文首发于 JS:构造函数总结

    什么是构造函数?

    构造函数(Constructor)的创建方式和普通函数一样。但通常首字母进行大写,用于和普通函数区分。

    但是当一个函数创建好以后,我们并不知道它是不是构造函数(即使函数名的首字母为大写)。只有当它以 new 操作符来调用的时候,我们才能说它是一个构造函数。

    // 这是一个通用的默认构造函数类 Car
    function Car(make, model, year) {
      this.make = make
      this.model = model
      this.year = year
    }
    
    // 分配给 beetle 的一个新的 Car 对象引用
    let beetle = new Car("Volkswagen", "Beetle", 1938)
    
    console.log(beetle.model) // expected output: "Beetle"
    

    构造函数属于被实例化的特定类对象

    构造函数属于被实例化的特定类对象,所以它的函数名同时也是它的类名。

    上面代码中的 Car() 是一个构造函数,Car 既是它的函数名,也是它的类名。

    将构造函数 Car 转换为类声明如下:

    class Car {
      constructor(make, model, year) {
        this.make = make
        this.model = model
        this.year = year
      }
    }
    

    构造函数的作用

    构造函数的作用是新建实例对象,并且给实例对象内的成员(属性或方法)赋值。

    在我们需要创建大量同一类型的对象时,这些对象都具有某些属性或方法,如果我们直接通过变量加字面量的形式进行赋值,会产生很多重复的代码。而当我们将这些对象抽象为一个类时,创建一个构造函数,就可以实现代码复用。

    // 通过变量加字面量的形式依次进行赋值
    let beetle = { make: "Volkswagen", model: "Beetle", year: "1938" }
    let porsche911 = { make: "Porsche", model: "Porsche 911", year: "1963" }
    let accord = { make: "Accord", model: "Honda", year: "1976" }
    
    // 通过构造函数的形式进行赋值
    let beetle = new Car("Volkswagen", "Beetle", 1938)
    let porsche911 = new Car("Porsche", "Porsche 911", 1963)
    let accord = new Car("Accord", "Honda", 1976)
    

    this 来设置对象内的属性或方法

    function Car(make, model, year) {
      this.make = make
      this.model = model
      this.year = year
      this.introduce = function () {
        alert(`I'm the ${model}. I'm from ${make}. I was made in ${year}.`)
      }
    }
    

    通过 new 操作符进行调用

    要调用构造函数,请使用 new 操作符将新的对象引用分配给一个变量/常量。

    let beetle = new Car("Volkswagen", "Beetle", 1938)
    

    构造函数的执行过程

    • 当以 new 操作符调用某一个构造函数时,构造函数会立刻在堆内存中创建一个新的内存空间,并将这个内存空间的地址赋值给 this

    • 执行函数体内的代码,当构造函数执行完毕,会将 this 赋值给一个新的实例 instance,并返回 instance

    • 当调用结束时,instance 就是我们所需要的新的对象。

    构造函数的返回值

    默认情况下,构造函数的返回值是 this,即新创建的对象。

    // 这是一个通用的默认构造函数类 Car
    function Car(make, model, year) {
      this.make = make
      this.model = model
      this.year = year
    }
    
    // 分配给 beetle 的一个新的 Car 对象引用
    let beetle = new Car("Volkswagen", "Beetle", 1938)
    
    console.log(beetle) // expected output: { make: 'Volkswagen', model: 'Beetle', year: '1938' }
    

    特殊情况下,构造函数可以返回一个指定的值。

    function Car(make, model, year) {
      this.make = make
      this.model = model
      this.year = year
      return {
        name: `${make} ${model} ${year}`,
      }
    }
    
    let beetle = new Car("Volkswagen", "Beetle", 1938)
    
    console.log(beetle) // expected output: { name: 'Volkswagen Beetle 1938' }
    

    构造函数的继承

    通过 callapply 方法

    function Car(make, model, year) {
      this.make = make
      this.model = model
      this.year = year
    }
    
    function Wheel(make, model, year) {
      Car.call(this, make, model, year)
      this.wheels = 4
    }
    
    let beetle = new Wheel("Volkswagen", "Beetle", 1938)
    
    console.log(beetle.wheels) // expected output: 4
    

    通过 prototype 属性

    function Car(make, model, year) {
      this.make = make
      this.model = model
      this.year = year
    }
    
    function Wheel() {
      this.wheels = 4
    }
    
    // 将 Wheel 的原型对象赋值给 Car 的原型对象
    Car.prototype = new Wheel()
    // 纠正继承链
    Car.prototype.constructor = Car
    
    let beetle = new Car("Volkswagen", "Beetle", 1938)
    
    console.log(beetle.wheels) // expected output: 4
    

    构造函数(Constructor)和类(Class)的区别

    构造函数是一个普通的函数。在 ES6 之前,我们习惯用构造函数去创建一个类。不过后来 ES6 定义了 Class 关键字,它可以理解为是构造函数的一个语法糖,可以让我们更加方便地创建一个类。

    class Car {
      constructor(make, model, year) {
        this.make = make
        this.model = model
        this.year = year
      }
    }
    

    类只能使用 new 操作符调用,否则会报错。

    class Car {
      constructor(make, model, year) {
        this.make = make
        this.model = model
        this.year = year
      }
    }
    // 报错
    Car(make, model, year) // typeError: Class constructor Car cannot be invoked without 'new'
    

    class 可以通过 extends 关键字很方便的实现继承

    class Car {
      constructor(make, model, year) {
        this.make = make
        this.model = model
        this.year = year
      }
    }
    
    class Beetle extends Car {
      constructor(make, model, year) {
        // super 用于访问和调用一个对象的父对象上的函数
        // 传递给 super 的参数会被传递给父类的构造函数
        super(make, model, year)
        // super() 只能在使用 this 之前调用
        this.wheels = 4
      }
    }
    
    let myBeetle = new Beetle("volkswagen", "beetle", 1967)
    
    console.log(myBeetle) // expected output: Beetle {make: "volkswagen", model: "beetle", year: 1967, wheels: 4}
    

    相关文章

      网友评论

          本文标题:JS:构造函数总结

          本文链接:https://www.haomeiwen.com/subject/ghsoiltx.html