每一个构造函数都有一个内置属性prototype,叫做显式原型属性,简称为显式原型
构造函数的prototype默认指向一个空的Object对象,而构造函数创建的对象的__proto__指向其构造函数的prototype
function Person(){}
const p = new Person()
p.proto === Person.prototype

Person.prototype instanceof Object

当【对象.属性】或【对象.方法】时,会先在对象自身查找,如果自身找不到,则会去自身的__proto__指向的原型对象上找
所以我们在定义类(构造函数)时,通常将实例方法定义在类(构造函数)的prototype属性上,即原型对象上。因为这样,创建对象就可以自动沿着__proto__找到原型对象上的方法。


原型链
===
原型链又叫做隐式原型链,因为原型对象本身也是一个对象,所以原型对象也有__proto__这个隐式原型属性,而原型对象默认是一个空的Object对象,所以原型对象的构造函数就是Object函数,所以原型对象的__proto__指向的是Object.prototype

而根据【对象.属性】,【对象.方法】的查找规则,如果对象在自身找不到某个属性或方法,则会沿着__proto__去原型对象上找,如果原型对象上也没有,则继续验证原型对象的__proto__去上一级原型对象的身上找,…,尽头就是Object.prototype这个原型对象,它的__proto__指向null。
这就解释了为什么所有对象都默认toString方法,因为所有对象能可以根据隐式原型链找到Object.prototype原型对象,而toString方法就是定义在Object.prototype上的。
这也解释了为什么对象访问一个不存在属性时会报错undefined,因为原型链的尽头是null,而null上没有任何属性,所以返回unedfined。
Function构造函数在原型链中的位置
====================
我们需要知道,在JS中函数也是一种对象,这里的函数包括构造函数,即构造函数也是一种对象,而函数对象的构造函数是谁呢?
它就是Function构造函数。我们可以人为function Array(){} ,function String(){} 这些对象,都是Function构造函数的实例。
const Person = new Function(‘name’,‘this.name = name’)
const p = new Person(‘张三’)
console.log§

所以Function可以理解为是所有函数对象的构造函数,函数对象的隐式原型属性指向了Function构造函数的显式原型

这也解释了为什么每个函数都可以调用call,apply,bind方法,因为这三个方法都是定义在Function.prototype上的
验证Object.__proto__ === Function.prototype

那么Function构造函数也是一个函数,即Function构造函数也是一个对象,那么Function.__proto__指向谁呢
其实也是指向它的构造函数的显式原型。
那么Function构造函数是谁构造的呢? 是它自己。
即 Function.__proto__ === Function.prototype


总结
==
任意对象的__proto__都指向自己构造函数的prototype
原型对象的__proto__也指向自己构造函数的prototype
构造函数的原型对象默认是空的Object对象
构造函数对象(包括Object()和Function())的构造函数都是Function,比较有代表性的是:
Object.__proto__ === Function.prototype
Function.__proto__ === Function.prototype
那么Function.prototype.__proto__指向谁呢,答案是Obejct.prototype

原型链在类继承中的应用
===========
假设现在有一个学生类,想继承人类。
则1、继承人类的属性 2、继承人类的方法
ES5中实现继承
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function() {
console.log(‘你好,我叫’ + this.name + ‘,今年’ + this.age + ‘岁了。’)
}
function Student(level, name, age) {
this.level = level
Person.call(this, name, age) // 实例属性继承
}
Student.prototype.sayLevel = function() {
console.log(‘我已经’ + this.level + ‘年级了。’)
}
Student.prototype.proto = Person.prototype // 实例方法继承
const stu = new Student(1, ‘张三’, 6)
stu.sayLevel()
stu.sayHi()
console.log(stu);

对应的原型链如下,原本Student.prototype.__proto__是指向Object.prototype
现在将Student.prototype.__proto__指向Person.prototype
这样stu实例依旧可以访问Object原型上方法,也可以访问Person原型上方法

另一种原型链继承方案是Student.prototype = new Person()
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function() {
console.log(‘你好,我叫’ + this.name + ‘,今年’ + this.age + ‘岁了。’)
}
function Student(level, name, age) {
this.level = level
Person.call(this, name, age) // 实例属性继承
}
Student.prototype = new Person() // 必须要先写,早于Student.protptype.xxx = function
Student.prototype.sayLevel = function() {
console.log(‘我已经’ + this.level + ‘年级了。’)
}
const stu = new Student(1, ‘张三’, 6)
stu.sayLevel()
stu.sayHi()
console.log(stu);

这种继承方案stu对象可以顺着隐式原型链访问到Person.prototype上的方法,完成方法继承,但是存在一个缺点,stu.__proto__原型对象是一个new Person()对象,那么new Person()对象的属性就会影响到所有的Student实例
我觉得:原型链继承单纯的用作方法继承,使用Vue的继承思路 vc.prototype.__proto__ === vm.prototype
就挺好的。
但是好像听说:ES6之前,程序员无法直接操作对象的隐式原型属性,现在ES6可以了
JS的四大继承方案
=========
1、原型继承:方法继承,Child.prototype === new Father() 或者 Child.prototype.__proto__ === Father.prototype
2、call继承: 属性继承
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
(img-c0EdvGOY-1715540752159)]
[外链图片转存中…(img-HyP9L3kb-1715540752160)]
[外链图片转存中…(img-O05KG4fx-1715540752160)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
3万+

被折叠的 条评论
为什么被折叠?



