[](()2.基础铺垫
JavaScript
所有的对象本质上都是通过new 函数
创建的,包括对象字面量的形式定义对象(相当于new Object()
的语法糖)。
- 所有的函数本质上都是通过
new Function
创建的,包括Object
、Array
等
- 所有的函数都是对象。
[](()3. prototype
每个函数都有一个属性prototype
,它就是原型,默认情况下它是一个普通Object
对象,这个对象是调用该构造函数所创建的实例的原型。
[](()4. contructor属性
JavaScript
同样存在由原型指向构造函数的属性:constructor
,即Func.prototype.constructor --> Func
[](()5. __proto__
JavaScript
中所有对象(除了null
)都具有一个__proto__
属性,该属性指向该对象的原型。
function User() {}
var u1 = new User();
// u1.proto -> User.prototype
console.log(u1.proto === User.prototype) // true
显而易见,实例的__proto__
属性指向了构造函数的原型,那么多个实例的__proto__
会指向同一个原型吗?
var u2 = new User();
console.log(u1.proto === u2.proto) // true
其实学到这里就可以产生一些骚想法了,多个实例的__proto__
都指向构造函数的原型,那么实例如果能通过一种方式,访问原型上的方法,属性等,就可以实现继承的效果。
我们继续更新一下原型与原型链的关系图:
![在这里插入图片描述](https://img-blog.csdnimg.cn/ce26e887ac474250af075d930e862e7d.png?x-oss 《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】 -process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA5oiY5Zy65bCP5YyF,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center)
[](()6. 原型链
实例对象在查找属性时,如果查找不到,就会沿着__proto__
去与对象关联的原型上查找,如果还查找不到,就去找原型的原型,直至查到最顶层,这也就是原型链的概念。
就借助面试题,举几个原型链的例子:
[](()6.1举例
u1.sayHello()
:
u1
上是没有sayHello
方法的,因此访问u1.__proto__(User.prototype)
,成功访问到sayHello
方法
u2.toString()
u2,User.prototype
都没有toString
方法,User.prototype
也是一个普通对象,因此继续寻找User.prototype.__proto__(Object.prototype)
,成功调用到toString
方法
[](()7. 提高升华
学完上面那些,大多数面试题都可以做出来了,例如下面这种
function A() {}
function B(a) {
this.a = a;
}
function C(a) {
if (a) {
this.a = a;
}
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log(new A().a); //1
console.log(new B().a); //undefined
console.log(new C(2).a); //2
但距离解决文章的最初的面试题还欠缺些什么,比如Function.__proto__ === Object.__proto__、Function.prototype.__proto__ === Object.prototype.__proto__
等,接着我们来一一攻克它。
[](()7.1 Objcet.__proto__
、 Object.prototype
、Object.prototype.__proto__
-
Object
是构造函数,在第二部分我们讲过所有的函数都是通过new Function
创建了,因此Object
相当于Function
的实例,即Object.__proto__ --> Function.prototype
。 -
Object.prototype
是Object
构造函数的原型,处于原型链的顶端,Object.prototype.__proto__
已经没有可以指向的上层原型,因此其值为null
// 总结:
Object.proto --> Function.prototype
Object.prototype.proto --> null