JS:向构造函数的原型prototype中添加方法

在下面的Person构造函数中,为每一个对象都添加了一个sayName方法,下面代码中sayName方法是在构造函数内部创建的,也就是构造函数每执行一次,就会创建一个新的sayName方法,(执行1000次就会创建1000次方法),也就是所有实例的sayName方法都是唯一的,这完全没有必要。(console.log(per1.sayName == per2.sayName)为false)

// 创建一个Person构造函数
function Person(name,age,sex){
// 向对象中添加属性
	this.name = name;
	this.age = age;
	this.sex = sex;
	// 向对象中添加一个sayName方法
	this.sayName = function(){
		console.log("我叫"+this.name);
	}
}
// 创建Person对象的实例
var per1 = new Person("翠花",17,"女");
var per2 = new Person("熊大",19,"男");
per1.sayName(); // 输出:我叫翠花
per2.sayName(); // 输出:我叫熊大
console.log(per1.sayName == per2.sayName); // false

向构造函数的原型prototype中添加方法
此方法可以很好的解决以上的问题。
我们所创建的每一个函数,解析器都会向函数中添加一个属性prototype。
这个属性对应着一个对象,这个对象就是我们所谓的原型对象。
但如果函数作为普通函数调用prototype没有任何作用,当通过构造函数调用时,它所创建的对象中都会有一个隐含的属性,指向该构造函数的原型对象,可以通过__proto__来访问该属性(__proto__就是那个隐含的属性),

function Person(){
}
// 该对象中有一个隐含属性__proto__,指向构造函数Person的原型对象prototype,因此判断两个会返回true
var per = new Person();
var per2 = new Person();
console.log(per.__proto__ == Person.prototype); // true
console.log(per2.__proto__ == Person.prototype); // true

说白了,原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象。
因此,我们可以将对象中共有的内容,统一设置到原型对象prototype中,优化后代码如下:

function Person(name,age,sex){
	this.name = name;
	this.age = age;
	this.sex = sex;
}
// 向Person构造函数的原型中添加sayName方法
Person.prototype.sayName = function(){
     console.log("我叫"+this.name);
}
var per1 = new Person("翠花",17,"女");
var per2 = new Person("熊大",19,"男");
per1.sayName(); 
per2.sayName(); 
console.log(per1.sayName == per2.sayName);  // true

prototype原理:当我们访问对象的一个属性或方法时,会先在自身寻找,如果有则直接使用,如果没有则去原型对象中寻找,如果找到直接使用。
因此之后在创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中。


版权声明:本文为weixin_46682277原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。