js中的构造函数是什么?

219 阅读3分钟

构造函数概念✨

在 JavaScript 中,任何的函数都可以作为构造函数存在,之所以有构造函数与普通函数之分,主要从功能上进行区别的,构造函数具有以下特点

1.习惯上首字母大写

2.使用new关键字进行调用

3.构造函数用来新建实例对象

4.内部用this来构造属性和方法

5.构造函数在被调用之后会马上创建一个新对象,并将该对象作为返回值返回

6.具有prototype

构造函数和普通函数的区别👀

1.调用方式和命名

  • 普通函数:通常小写,直接调用方法名
  • 构造函数:通常首字母大写,需要使用new关键词调用
// 普通函数:
function person() {}
person()
// 构造函数:
function Person() {}
const p = new Person()

2.this指向

  • 普通函数:严格模式下this表示为undefined,非严格模式下this指向window
  • 构造函数:this指向新创建对象的实例
// 普通函数 非严格模式
function person() {
    console.log('this === window?', this === window)
}
person() // true
"use strict";
// 普通函数 严格模式
function person() {
    console.log('this?', this)
}
person() //undefined
// 构造函数
function Person(city) {
    this.city = city
    console.log('this指向:', this);
}
const c1 = new Person('杭州') // this指向: Person {city: '杭州'}
const c2 = new Person('北京') // this指向: Person {city: '北京'}

3.return区别

  • 普通函数:一般都带return,有值就返回return后面的值,没有值或者没有写return就返回undefined
  • 构造函数:一般不需要return。如果返回基本类型,return语句可以忽略。如果返回引用类型,会直接返回引用类型本身。
// 普通函数
function person() {
    return 'abc'
}
console.log(person()); // 'abc'
// 构造函数 返回基本类型
function Person(name) {
    this.name = name;
    return 'abc' // 基本类型自动忽略这行
}
const p = new Person('jayshen')
console.log(p); // Person {name: 'jayshen'}

// 构造函数 返回应用类型
function Person(name) {
    this.name = name;
     return {
        name: 'abc'
    } 
}
const p = new Person('jayshen')
console.log(p); // {name: 'abc'}

new操作符做了什么❓

我们先来手动实现一个new

1.创建了一个新的空对象

2.设置原型,将对象的原型设置为函数的prototype对象

3.调用函数,this指向新创建的对象

4.返回新创建的对象(判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象)

function objectFactory() {
    let newObj = null
    // 获取第一个参数,既传入的构造函数
    let Constructor = Array.prototype.shift.call(arguments); // or let Constructor = [].shift.call(arguments) 
    let result = null
    if (typeof Constructor === 'function') {
        // 创建一个空对象
        newObj = Object.create(Constructor.prototype)
        // 使用 apply,改变构造函数 this 的指向到新建的对象,这样 obj 就可以访问到构造函数中的属性
        result = Constructor.apply(newObj, arguments)
        // 判断返回对象
        let flag = result && typeof result === 'object'
        return flag ? result : newObj
    }
}

function person(name, age) {
    this.name = name
    this.age = age
}

const p = objectFactory(person, 'JayShen', 18) // 等同于操作符new
console.log(p)

箭头函数能否使用new调用❓

从上面一系列操作可以看出,箭头函数肯定是不可以使用new调用的,原因:

1.箭头函数根本没有自己的this!导致内部的this就是外层代码块的this,最外层就是window,也不能使用call()apply()bind() 去改变this的指向。构造函数的this永远指向被他实例化出来的对象,但是箭头函数无法对创建出来的实例进行this绑定。

2.没有原型prototype,就没有super用于访问原型属性。

3.箭头函数和new搭配会报错!(最直接)

1652261177(1).jpg