原型(prototype)
Javascript 规定,每一个构造函数都有一个
prototype
属性,指向另一个对象。 这个对象的所有属性和方法,都会被构造函数的实例继承。这也就意味着,我们可以把所有对象实例需要共享的属性和方法直接定义在
prototype
对象上。
function Person (name, age) {
this.name = name
this.age = age
}
console.log(Person.prototype)
Person.prototype.type = 'human'
Person.prototype.sayName = function () {
console.log(this.name)
}
var p1 = new Person(...)
var p2 = new Person(...)
console.log(p1.sayName === p2.sayName) // => true
这时所有实例的
type
属性和 sayName()
方法, 其实都是同一个内存地址,指向 prototype
对象,因此就提高了运行效率。原型链
了解了 构造函数-实例-原型对象 三者之间的关系后,接下来我们来解释一下为什么实例对象可以访问原型对象中的成员。
每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性
-
搜索首先从对象实例本身开始
-
如果在实例中找到了具有给定名字的属性,则返回该属性的值
-
如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性
-
如果在原型对象中找到了这个属性,则返回该属性的值
也就是说,在我们调用
person1.sayName()
的时候,会先后执行两次搜索:-
首先,解析器会问:“实例 person1 有 sayName 属性吗?”答:“没有。
-
”然后,它继续搜索,再问:“ person1 的原型有 sayName 属性吗?”答:“有。
-
”于是,它就读取那个保存在原型对象中的函数。
-
当我们调用 person2.sayName() 时,将会重现相同的搜索过程,得到相同的结果。
而这正是多个对象实例共享原型所保存的属性和方法的基本原理。
总结:
-
先在自己身上找,找到即返回
-
自己身上找不到,则沿着原型链向上查找,找到即返回
-
如果一直到原型链的末端还没有找到,则返回
undefined
- 还没有人评论,欢迎说说您的想法!