JS构造函数详解

什么是构造函数?

所谓构造函数,就是提供一个生成对象的模板,并描述对象的基本结构的函数。

构造函数的特点

  • 一个构造函数,可以生成多个对象,每个对象都有相同的结构。
  • 对于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之后发生了什么?)

官方解释:

  1. 创建一个空的简单JavaScript对象(即{});
  2. 为步骤1新创建的对象添加属性__proto__,将该属性链接至构造函数的原型对象 ;
  3. 将步骤1新创建的对象作为this的上下文 ;
  4. 如果该函数没有返回对象,则返回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方法。因为:调用p1eating方法时,如果p1对象没有该方法,会去p1对象的原型__proto__
因为在构造p1时,绑定的原型:p1.__proto__ = Person.prototype,所以可以找p1.__proto__.eating

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值