构造函数与原型对象
一、构造函数
构造函数本身就是一个函数,只不过该函数是出于创建新对象的目的而创建的。构造函数与其他函数的唯一区别,就在于调用他们的方式不同。任何函数,只要通过new操作符来调用,那他就可以作为构造函数;而任何函数,如果不通过new操作符来调用,那它跟普通函数也没有什么两样。
// 当做构造函数调用
let person1 = new Person("Wang", 45, "Doctor");
person.sayName(); //Wang
// 作为普通函数调用
Person("Pan", 23, "Student"); //添加到window
window.sayName(); //Pan
像Object 和 Array属于原生构造函数,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。
自定义构造函数:
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
}
}
let person1 = new Person("Pan", 23, "Student");
let person2 = new Person("Wang", 45, "Doctor");
要创建person的实例,要使用new操作符。以new操作符调用Person的过程:
1.在内存中新创建一个对象。
2.这个新对象内部的[[Prototype]]特性被赋值为构造函数的prototype属性.
3.构造函数内部的this被赋值为这个新对象(即this指向新对象)。
4.执行构造函数内部代码(给新对象添加属性)。
5.如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。
按照惯例,构造函数始终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。
使用构造函数的主要问题,就是每个方法都要在每个实例上都创建一遍。
这个问题可以通过将函数定义放到构造函数外部解决。
function Person() {
this.name = name;
this.sayName = sayName;
}
//将sayName方法放在构造函数外面,就不会出现每个实例上都创建一遍的问题了。
//可以通过console.log(person1.sayName===person2.sayName);验证
function sayName() {
console.log(this.name);
}
let person1 = new Person('pan');
let person2 = new Person('wang');
person1.sayName();
person2.sayName();
二、原型
我们创建的每个函数都有一个prototype (原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由所有实例共享的属性和方法。
原型对象的理解:
无论什么时候,只要创建一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性是一个指向prototype属性所在函数的指针。
可以理解为构造函数通过prototype指向原型对象,原型对象通过constructor指向构造函数。原型对象中存储着属性可以被所有实例共享。
function Person() {}
Person.prototype.name = "Pan";
Person.prototype.sayName = function(){
console.log(this.name);
};
/*
*实例1
*通过[[Prototype]]指向原型对象中的属性和方法
*/
var person1 = new Person();
person1.sayName(); //Pan
/*
*实例2
*通过[[Prototype]]指向原型对象中的属性和方法
*/
var person2 = new Person();
person2.sayName(); //Pan
//person1.sayName和person2.sayName都指向的原型对象中的sayName方法.
console.log(person1.sayName === person2.sayName); //true
Person构造函数、原型属性与两个实例之间的关系:
person1和person2都包含一个内部属性,该属性只是指向了构造函数的属性Person.prototype,它们与构造函数并没有直接关系。构造函数和原型对象有直接关系。
本文地址:https://blog.csdn.net/pan_542pan11/article/details/109065246