·原型模式
我们创建的每一个函数都由一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有
实例共享的属性和方法。
如果按照字面意思来理解,那么prototype就是通过构造函数创建的那个对象实例的原型对象。使用原型对象的好处就是可以让所有对象实例共享它
所包含的属性和方法
// code示例
function Person(){} Person.prototype.name = ‘Nicholas‘; Person.prototype.age = 29; Person.prototype.job = "Software Engineer"; Person.prototype.sayName = function () { console.log(this.name); }; var person1 = new Person(); person1.sayName(); //Nicholas var person2 = new Person(); person2.sayName(); //Nicholas console.log(person1.sayName === person2.sayName); // true
理解原型对象:
1:无论什么时候,只要创建了一个新函数们就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。
2:在默认情况下,所有原型对象都会自动获得一个constructor属性,至于其它方法,则都是从Object继承来的。
3:当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。ECMAScript中管这个
指针叫[[Prototype]]
4: 要明确 [[Prototype]] 这个连接存在于实例与原型对象之间,而不是存在于实例与构造函数之间
示意图:
// 图片
对示意图的理解:
1:Person.prototype指向了原型对象。而Person.prototype.constructor又指回了Person
2:Person的每一个实例,都包含一个内部属性,该属性仅仅指向了Person.prototype
3:原型最初只包含constructor属性,而该属性也是共享的,因此可以通过对象实例访问
4:当代码读取某个对象的属性时,都会执行一次搜索,如果在实例中找到,则返回该属性。没有则在原型对象中查找
5:当为对象实例添加一个属性时,这个属性会屏蔽原型对象的同名属性;换句话说,添加这个属性只会阻止我们访问原型中的那个属性,但不会修改
那个属性。即使将这个属性设置为null,也只会在实例中设置这个属性,而不会恢复其指向原型的连接。
注意:所有实现都无法访问到[[Prototype]],那我们怎么得到一个对象的原型对象呢?
// 返回[[Prototype]]的值 console.log(Object.getPrototypeOf(person1) === Person.prototype); // true 使用Object.getPrototypeOf()返回的对象其实就是这个对象的原型,而这在利用原型实现继承的情况下是非常重要的
注意:我们如何得出一个属性是存在于实例中,还是存在于原型中。这个方法(不要忘了它是从Object继承来的)只在给定属性存在于对象实例中时,才会返回true
function Dog(){ } Dog.prototype.name = "tom"; var dog_a = new Dog(); console.log(dog_a.hasOwnProperty("name")); // false dog_a.name = "jack"; // 该实例重写了name属性 console.log(dog_a.hasOwnProperty("name")); // true
原文:https://www.cnblogs.com/cl94/p/11259420.html