JS创建对象方法(2)

原型模式:
先来看一个例子吧

function Person(){

}
Person.prototype.name = “saw”;
Person.prototype.age = “22”;
Person.prototype.job = “no”;
Person.prototype.sayName = function(){
  alert(this.name);
}
var person1 = new Person();
person1.sayName(); //saw
var person2 = new Person();
person2.sayName(); //saw
alert(person1.sayName == person2.sayName); //true

看完代码,我们来理解一下原型的概念
(1)原型对象
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype(原型)属性,这个属性指向函数的原型对象。在默认情况下,所有的原型对象都会自动获得一个constructor(构造函数)属性,这个属性是一个指向prototype属性所在的函数的指针。

console.log(Person.prototype.constructor == Person) //true

下面这张图详细的描述了原型对象的概念
这里写图片描述

(2)、修改实例属性值并不会改变原型中的属性值

function Person(){

}
Person.prototype.name = "saw";
Person.prototype.age = "22";
Person.prototype.job = "no";
Person.prototype.sayName = function(){
 alert(this.name);
}
var person1 = new Person();
person1.sayName(); //saw
var person2 = new Person();
person2.sayName(); //saw
alert(person1.sayName == person2.sayName); //true
console.log(Person.prototype.constructor == Person) //true
console.log(person1.proto === Person.prototype);

person1.name = 'AwsuEver'
console.log(person1.name); //AwsuEver
console.log(person2.name); //saw

从上面代码可以看出来,当我们改变person1.name的时候,并没有改变Person.prototype.name,这是因为我们在定义person1.name = ‘AwsuEver’ 的时候只是在person1的实例中添加这个属性,而这个和原型中的属性重名了,而我们在console.log(person1.name)的时候会先找实例中是否有这个name属性,没有才会去原型中找,实例的查找优先级高于原型,导致了实例中的name属性屏蔽了原型中的属性,只是屏蔽并没有修改。

当我们使用delete删除实例中的name属性后就会恢复name属性与原型的链接,如下代码:

function Person(){

}
Person.prototype.name = "saw";
Person.prototype.age = "22";
Person.prototype.job = "no";
Person.prototype.sayName = function(){
 alert(this.name);
}
var person1 = new Person();
person1.sayName(); //saw
var person2 = new Person();
person2.sayName(); //saw
alert(person1.sayName == person2.sayName); //true
console.log(Person.prototype.constructor == Person) //true
console.log(person1.proto === Person.prototype);

person1.name = 'AwsuEver'
console.log(person1.name); //AwsuEver
console.log(person2.name); //saw

delete person1.name;
console.log(person1.name); //saw
console.log(person2.name); //saw

(3)使用hasOwnProperty检查属性是否来自原型

function Person(){

}
Person.prototype.name = "saw";
Person.prototype.age = "22";
Person.prototype.job = "no";
Person.prototype.sayName = function(){
 alert(this.name);
}
var person1 = new Person();
person1.sayName(); //saw
var person2 = new Person();
person2.sayName(); //saw
alert(person1.sayName == person2.sayName); //true
console.log(Person.prototype.constructor == Person) //true
console.log(person1.proto === Person.prototype);

person1.name = 'AwsuEver'
console.log(person1.name); //AwsuEver
console.log(person1.hasOwnProperty('name')); // true 属性来自实例
console.log(person2.name); //saw

delete person1.name;
console.log(person1.name); //saw
console.log(person1.hasOwnProperty('name')); // true 属性来自实例
console.log(person2.name); //saw

以上内容节选自JavaScript高级程序设计,若需要了解详细内容,可参考该书。

猜你喜欢

转载自blog.csdn.net/qq_40856225/article/details/82421915