构造函数的三大特点:
a:构造函数的函数名的第一个字母通常大写。
b:函数体内使用this
关键字,代表所要生成的对象实例。
c:生成对象的时候,必须使用new
命令来调用构造函数。
构造函数中的new
命令做了什么?
new
命令的作用,就是执行一个构造函数,并且返回一个对象实例。使用new
命令时,它后面的函数调用就不是正常的调用,而是依次执行下面的步骤。
a:创建一个空对象,作为将要返回的对象实例。
b:将空对象的原型指向了构造函数的prototype
属性。
c:将空对象赋值给构造函数内部的this
关键字。
d:开始执行构造函数内部的代码。
也就是说,构造函数内部,this
指向的是一个新生成的空对象,所有针对this
的操作,都会发生在这个空对象上。构造函数之所谓构造函数,意思是这个函数的目的就是操作一个空对象(即this
对象),将其构造为需要的样子。
注意事项:构造函数实际是一个函数,this指向的构造函数创建的实例对象。
构造函数中的return
//情景一
function Keith() {
this.height = 180;
return {
height: 200,
};
}
var boy = new Keith();
console.log(boy.height); //200
//情景二
function Keith() {
this.height = 100;
return 200;
}
var boy = new Keith();
console.log(boy.height); //100
解释:如果构造函数内部有return
语句,而且return
后面跟着一个复杂数据类型(对象,数组等),new
命令会返回return
语句指定的对象;如果return
语句后面跟着一个简单数据类型(字符串,布尔值,数字等),则会忽略return
语句,返回this
对象。
构造函数内super()函数的作用?
在ES6实现继承中会有constructor
构造函数,而实现继承的子类构造函数中必须先调用super()
方法,此处的super()
为父类的构造方法,而如果不调用,浏览器则会报错。报错原因是因为子类没有自己的 this
对象,而是继承父类的 this
对象,然后对其进行加工,而 super
就代表了父类的构造函数。super
虽然代表了父类 Person
的构造函数,但是返回的是子类 Son
的实例,即 super
内部的this
指的是 Son
。
实现一个new方法
(1)首先创建了一个新的空对象
(2)设置原型,将对象的原型设置为函数的 prototype
对象。
(3)让函数的 this
指向这个对象,执行构造函数的代码(为这个新对象添加属性)
(4)判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。
function myNew(fn, ...args) {
// 判断参数是否是一个函数
if (typeof fn !== "function") {
return console.error("type error");
}
// 创建一个对象,并将对象的原型绑定到构造函数的原型上
const obj = Object.create(fn.prototype);
const value = fn.apply(obj, args); // 调用构造函数,并且this绑定到obj上
// 如果构造函数有返回值,并且返回的是对象,就返回value ;否则返回obj
return value instanceof Object ? value : obj;
}