js原型
有如如下代码:
class Person {
constructor(name) {
this.name = name
}
hello() {
console.log('hello')
}
}
class Student extends Person {
constructor(name, score) {
super(name)
this.score = score
}
introduce() {
console.log(`我是${this.name},考了${this.score}分。`)
}
}
const student = new Student('maple', 99)
console.log('student:', student)
student.introduce()
student.hello()
如上所示代码,运行结果如下:
student: Student {name: "maple", score: 99}
我是maple,考了99分。
hello
从第22行代码打印结果可以看出来,student
对象并没有打印出 introduce()
方法,但是第23行代码的结果可以看出来是可以通过 student
对象调用的!
如果该代码是在浏览器控制台中运行,那么你会发现这个打印的结果是可以展开的,如下所示:
展开之后,有个 __proto__
属性(该属性每个对象都有),里面就可以找到 introduce()
方法。
我们把这个 __proto__
属性叫做student
对象的隐式原型。
当我们在一个对象中找一个属性或者方法时,在当前的对象上找不到,那么就会到它的隐式原型上去找。
这就是为什么student
对象没有 introduce()
方法依然可以调用的原因,因为它的隐式原型上有这个方法。
我们可以通过 student.__proto__
的方式访问它
我们知道,student
对象是类 Student 实例化后得到的。
通过 Student.prototype
可以访问类 Student 的原型。
我们把这个 prototype
属性叫做 Student 类的显式原型。
对象的隐式原型的值 等于 其对应构造函数的显式原型的值。
也就是 student.__proto__
和 Student.prototype
是相等的。
再说最后的结果,student.hello()
是成功执行出结果的。
首先,student
在自身找不到 hello()
方法,那么进一步到隐式原型 __proto__
中查找,但是还是没找到。就这么停止了吗?不!刚说了对象的隐式原型的值 等于 其对应构造函数的显式原型的值。也就是 student.__proto__
指向了 Student.prototype
,两者是相等的。
而Student.prototype
也是一个对象,是对象,就有 __proto__
属性,那么这里继续到Student.prototype
中的 __proto__
中查找,最后在 Student.prototype
的 __proto__
中查找到了 hello()
方法,因此可以调用。
总的来说,当一个属性或者方法在 student
对象中找不到,那么就会到 student
对象原型上去找,还找不到,就会到 student
对象原型的原型上继续找。
这种一层层通过 __proto__
组成的链子一样的路径中查找的过程中,这条链子,就叫做原型链。
当然不是无限制的一直查找下去的,最多查找到对象的最顶层 Object
。在 Object.prototype
中找不到就到Object.prototype.__proto__
中继续找,而此时它的隐式原型 __proto__
值为 null 。
本文系作者 @枫雨 原创发布在枫林幻境站点。未经许可,禁止转载。
全部评论 6
我要赚钱
Google Chrome Windows 10jiyouzhan
FireFox Windows 7芭比
Google Chrome Windows 10鸟叔
Google Chrome Windows 7Rivalsa
Google Chrome Android枫雨
Google Chrome Windows 10