文章目录
什么是构造函数?
所谓构造函数,就是提供一个生成对象的模板,并描述对象的基本结构的函数。
构造函数的特点
- 一个构造函数,可以生成多个对象,每个对象都有相同的结构。
- 对于JS中的任何一个普通函数,当用
new
关键字来调用时,它就是构造函数。可见一个函数是否是构造函数与其定义无关,与调用方式有关。 - 通常默契地将构造函数名首字母大写,来表示该函数以后希望被作构造函数来使用
作用:构造新对象,设置对象的属性和方法
内置构造函数
ECMAScript提供了多个内置构造函数,如 Boolean 、Number、String、Date、Array、Object。
注意:Math是内置对象并不是内置构造函数
const obj = new Object();
const arr = new Array();
ECMAScript也允许自定义构造函数
- 构造函数一般首字母会大写,为了和普通函数区分
- 一个构造函数可以通过new创建多个实例对象
- 创建构造函数时,里面的属性和方法前必须加this,this就表示当前运行时的对象(创建出来的实例)
eg1
function Person(name, height) {
this.name = name;
this.height = height;
this.bark = function (fs) {
return fs;
};
}
var boy = new Person("Keith", 180);
console.log(boy); //Person {name: 'Keith', height: 180, bark: ƒ}
console.log(boy.constructor); //f Person(){} //整个构造函数原型
console.log(boy.bark(8)); //8
console.log(boy.name); //'Keith'
console.log(boy.height); //180
eg2
function Cat1(name) {
this.name = name;
console.log(this); //this指向cat3实例
}
var cat3 = new Cat1("kk");
console.log(cat3); //Cat1 {name: 'kk'}
一、构造函数的返回值
1.1、构造函数不需要return 就可以返回结果(默认return出去this)
function Dog() {
this.name = "贝贝";
this.bark = function () {
console.log("汪汪汪");
};
}
var d1 = new Dog();
console.log(d1); //Dog {name: '贝贝', bark: ƒ}
1.2、return一个基本数据类型,结果不变(还是return出去this)
function Dog() {
this.name = "贝贝";
this.bark = function () {
console.log("汪汪汪");
};
return 0;
}
var d1 = new Dog();
console.log(d1); //Dog {name: '贝贝', bark: ƒ}
1.3、return一个引用数据类型,返回引用数据类型
eg1
function Dog() {
this.name = "贝贝";
this.bark = function () {
console.log("汪汪汪");
};
return [];
}
var d1 = new Dog();
console.log(d1); // []
eg2
function Dog() {
this.name = "贝贝";
this.bark = function () {
console.log("汪汪汪");
};
return {
name: "张三",
};
}
var d1 = new Dog();
console.log(d1); // {name:'张三'}
二、构造函数的原理(new之后发生了什么?)
官方解释:
- 创建一个空的简单JavaScript对象(即{});
- 为步骤1新创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象 ;
- 将步骤1新创建的对象作为this的上下文 ;
- 如果该函数没有返回对象,则返回this。
咱们的总结:
1、自从用
new
调用函数后,JS引擎就会在内存中创建一个空对象{}
,const newObj = {};
2、将新对象newObj的__proto__
属性链接至构造函数的原型对象newObj.__proto__ = FunctionName.prototype
3、构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)this = newObj
4、执行构造函数内部代码;
5、如果该函数没有返回对象,则默认返回this。
eg
function Person(name, age) {
this.name = name;
this.age = age;
this.eating = function() {
console.log(this.name + ' is eating');
}
}
const p1 = new Person('zs', 12);
//-------------------------------------------------
/*实际JS引擎帮助我们实现的操作*/
const newObj = {};
newObj.__proto__ = Person.prototype;
this = newObj;
this.name = name;
this.age = age;
this.eating = function() {
console.log(this.name + ' is eating');
}
return newObj;
构造函数中的this指向,指向构造出来的实例对象
三、在构造函数原型对象上绑定方法节省空间
采用构造函数的确可以批量创建对象,那么构造函数有什么缺点吗?有的。
由于每次函数调用都会创建新的对象,对象中的函数也会创建多份,对于函数而言创建多份没有必要,能不能共用一个函数呢?
function Person(name, age) {
this.name = name;
this.age = age;
}
const p1 = new Person("zs", 12);
// 在函数原型上添加方法
Person.prototype.eating = function () {
console.log(this.name + " is eating"); // zs is eating
return 5;
};
console.log(p1.eating()); //5
将方法转移到构造函数原型上来定义后,对于实例对象
p1
,依然可以调用eating
方法。因为:调用p1
的eating
方法时,如果p1
对象没有该方法,会去p1
对象的原型__proto__
找
因为在构造p1
时,绑定的原型:p1.__proto__ = Person.prototype
,所以可以找p1.__proto__.eating