这段时间在逆战班学习了面向对象相关内容,其中关于构造函数的两种语法我这里说一下。
1.ES5构造函数语法
(1)什么是构造函数呢?
构造函数就是一种专门用于生成对象的函数,通过构造函数生成的对象称为实例化对象。
(2)ES5构造函数语法
先看代码:
function CrtObj(name,age,sex,addr){// 在构造函数中,使用大驼峰命名法与普通函数区分
// 在构造函数中,使用this,来指代对象
// 这个对象,就是我们使用构造函数,生成的实例化对象
// 定义属性
// 给实例化对象,添加name属性,属性值是输入的name参数
this.name = name;
this.age = age;
this.sex = sex;
this.addr = addr;
// 定义方法
this.funAll = function(){
console.log(this.name,this.age,this.sex,this.addr )
}
this.funNameAge = function(){
console.log(this.name,this.age)
}
this.funSexAddr = function(){
console.log(this.sex,this.addr )
}
}
// 通过自定义构造函数来生对象,实例化对象
// 调用执行构造函数时,都必须要和new 关键词一起使用
const obj1 = new CrtObj('张三',18,'男','北京');
console.log(obj1);
// 调用 对象/实例化对象 中的方法
obj1.funAll();
obj1.funNameAge();
obj1.funSexAddr();
构造函数实际上就是把很多属性和方法封装在一个函数中,通过new关键词生成实例化对象,再通过对象的操作就可以调用属性和方法。
注:需要注意一个小问题,就是通过一个构造函数生成的实例化对象,其中的方法都是相同的,但是地址却不同,会占用过多的内存
const obj2 = new CrtObj(‘张三’,18,‘男’,‘北京’);
const obj3 = new CrtObj(‘李四’,19,‘女’,‘上海’);
const obj4 = new CrtObj(‘王五’,20,‘不详’,‘火星’);
我通过这个构造函数生成不同的三个实例化对象,可以看到其中的属性是相同的,属性值可能不同,我定义方法的程序是完全相同,那么下面就输出两个对象调用相同方法的比较
console.log( obj1.funAll == obj2.funAll );
可以看到输出的结果是false,因此明明是同一个方法,却会分别占用内存,其解决办法就是通过原型对象来解决,我这里简单写一下语法:
function CrtObj2(name, age, sex, addr) {
// 定义属性
this.name = name;
this.age = age;
this.sex = sex;
this.addr = addr;
}
// 在构造函数的 prototype 属性中,来定义实例化对象的方法
CrtObj2.prototype.fun = function(){
console.log(this.name, this.age, this.sex, this.addr);
}
const obj4 = new CrtObj2('张三',18,'男','北京');
const obj5 = new CrtObj2('李四',19,'女','上海');
console.log( obj4.fun === obj5.fun );
这里的输出结果是true,内存地址是相同的了。
(3)原型属性和原型对象
每一个函数都天生有一个prototype属性,称为原型对象,是一个专门用来存储数据、函数的空间,而每一个对象,天生有一个_prto_属性,称为原型属性,我们实例化对象的原型属性指向创建它的构造函数的原型对象。
因此上述代码中我将方法存储在构造函数的原型对象中,那么它生成的所有实例化对象调用方法时都会通过_proto_找到这个构造函数prototype属性中存储的方法。从而解决了上述小问题。
2.ES6构造函数语法
ES6中,新增了class类语法形式,它的作用和原理与ES5语法是完全相同的,只是语法形式不同而已。具体看下代码:
// 1,ES5语法
function Fun1(name,age){
this.name = name;
this.age = age;
}
Fun1.prototype.f1 = function(){
console.log(this.name , this.age);
}
// 2,ES6语法 class
class Fun2{
constructor(name,age){
this.name = name;
this.age = age;
}
f2(){
console.log(this.name , this.age);
}
}
const obj1 = new Fun1('张三',18);
const obj2 = new Fun2('李四',20);
这样一对比可以看出是非常相似了。
ES6语法的特点:(1)声明构造函数是通过class类声明的
(2)传参与定义属性是写在constructor构造器中的
(3)方法不需要写上prototype单词,甚至不需要写function关键词,然而这只是ES6语法帮我们给补上了而已,本质还是一样的
(4)最后一样通过new关键词生成实例化对象。