什么是构造函数?
通过new关键字调用的函数就是构造函数,构造函数首字母建议大写
构造调用和普通调用
首先我们知道构造函数也是可以当普通函数一样调用的,那么它们之间有什么区别呢?
直接看代码
function Fn(name){
this.name = name
return name
}
const q = Fn('普通调用')
const w = new Fn('构造调用')
console.log(q,w);
可以看到,普通调用是直接将函数Fn的返回值返回给q,而构造调用是把函数Fn当作一个类,把创造的实例返回给w,也就是说w是Fn通过new生成的实例化对象
new做了什么?
- 创建一个空对象,如果有实参,就把实参传给形参
- 该对象的隐式原型属性会指向构造函数的原型对象
this.__proto__ = Person.prototype
- 声明this,这个新对象的this会绑定到函数调用的this
- 会默认返回当前的实例对象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
}
如何判断一个对象是否属于一个类(构造函数)?
- instanceof:判断构造函数的
prototype是否出现在对象的原型链上 - 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
// }