JavaScript中构造函数总结

769 阅读2分钟

什么是构造函数?

通过new关键字调用的函数就是构造函数,构造函数首字母建议大写

构造调用和普通调用

首先我们知道构造函数也是可以当普通函数一样调用的,那么它们之间有什么区别呢?

直接看代码

function Fn(name){  
    this.name = name
    return name
}
const q = Fn('普通调用')
const w = new Fn('构造调用')
console.log(q,w);

普通调用和构造调用.jpg

可以看到,普通调用是直接将函数Fn的返回值返回给q,而构造调用是把函数Fn当作一个类,把创造的实例返回给w,也就是说w是Fn通过new生成的实例化对象

new做了什么?

  1. 创建一个空对象,如果有实参,就把实参传给形参
  2. 该对象的隐式原型属性会指向构造函数的原型对象
    • this.__proto__ = Person.prototype
  3. 声明this,这个新对象的this会绑定到函数调用的this
  4. 会默认返回当前的实例对象this
    • 如果返回值不是对象数据类型,会自动返回this
    • 如果返回值是对象数据类型,会返回该对象,不会返回this

手写new

代码演示

 function myNew(fn){
     // 判断第一个参数是不是函数
     if(typeof fn !=="function"){
        alert('myNew方法的第一个参数必须是function')
    }
    // 创建一个空对象
    let obj = {}
    // 创建一个数组去接收arguments(除第一个参数)
    const args = Array.prototype.slice.call(arguments,1)
    // 让该对象的隐式原型属性指向构造函数的原型对象
    obj.__proto__ = fn.prototype
    // 改变构造函数的this指向,指向这个新对象
    fn.apply(obj,args)
    return obj
}

如何判断一个对象是否属于一个类(构造函数)?

  1. instanceof:判断构造函数的prototype是否出现在对象的原型链上
  2. constructor:实例会沿着原型链找到构造函数的原型对象,而原型对象上呢会有一个constructor属性指向其构造函数 代码演示
function Person(name){
    this.name = name
}
var obj = new Person('李华')
console.log(obj instanceof Person) // true
console.log(obj.constuctor) // ƒ Person(name){
                            //  this.name = name
                            // }

涉及到原型以及原型链的问题有什么不懂的可以看这里