详解constructor、prototype、__proto__

constructor:保存自己构造函数引用的属性

1.可以通过对象.constructor拿到创建该实例对象的构造函数。
2.对象由函数创建,函数都是Function对象实例。

function Person() {...}
console.log(Person.constructor) // 输出结果:[Function: Function]
console.log(Function.constructor) // 输出结果:[Function: Function]
console.log(Object.constructor) // 输出结果:[Function: Function]

prototype对象:用于放某同一类型实例的共享属性和方法,实质上是为了内存着想。

1.原型对象就是实例对象自己构造函数内的prototype对象。
2.

function Person() {...}
let person1 = new Person();
let person2 = new Person();

现在我们想给Person类的实例对象(person1、person2)添加效果相同的方法:

person1.sayHello = function() {
    console.log('Hello!')
}
person2.sayHello = function() {
    console.log('Hello!')
}
console.log(person1.sayHello === person2.sayHello) // false,它们不是同一个方法,各自占有内存

如果这时候有千千万万个实例对象,上面的添加方法代码冗余 且会占用很多内存,没有必要,于是prototype就出来解决这个问题了。当需要为大量实例添加相同效果的方法时,可以将方法存放在prototype对象中,并将该prototype对象放在这些实例的构造函数上,达到共享、公用的效果。

Person.prototype.sayHello = function() {
    console.log('Hello!')
}
console.log(person1.sayHello === person2.sayHello) // true,同一个方法

3.new Person( )出来的千千万万个实例中如果都有constructor属性,并且都指向创建自己的构造函数,那岂不又出现了上述问题:实例对象们都拥有一个效果相同但却都各自占用一部分内存的属性?所以实例对象的constructor属性被当做共享属性放在原型对象(prototype对象)中,prototype对象放在这些实例的构造函数上

proto

1.前面我们讲的内容可以用下面这个图来表示:我们发现一个问题:有的时候我们需要更改共享方法(prototype对象中的方法)这个时候就需要得到prototype 但是你看下面的图 你怎么得到prototype对象呢?
在这里插入图片描述
此时__proto__应运而生,每个实例对象都有一个__proto__属性,指向构造函数的prototype对象:

  1. 实例对象.__ proto__ = 创建自己的构造函数内部的prototype(原型对象)
  2. 实例对象.__ proto__.constructor = 创建自己的构造函数

2.实例对象.constructor 等于 实例对象.__ proto__.constructor?
是的。当在一个实例对象上找不到某个属性时,JS就会去它的原型对象上找是否有相关的共享属性或方法
3.prototype也是个对象,它肯定也有个__proto__指向他的构造函数的原型对象

function Person() {...}
let person1 = new Person();

以上代码的指向如图所示:
在这里插入图片描述
由此可见:
(1)所有函数的__proto__指向Function函数的prototype对象
(2)Object函数是所有对象通过原型链追溯到最根的构造函数。
(3)Object函数的prototype中的__proto__指向null:为什么Object函数不能像Function函数一样让__proto__属性指向自己的prototype?如果指向自己的prototype,那当找不到某一属性时沿着原型链寻找的时候就会进入死循环,所以必须指向null

原型链

在这里插入图片描述
左边的图:Function函数因为是个特殊的例子,它的构造函数就是自己,所以__proto__属性也指向自己的prototype对象;但它的特殊性并不影响它的prototype对象依然不出意外的是Object函数的实例
右边的图:这个理解起来就很难受,因为Object函数和别的函数一样也是Function函数的实例,所以它的__proto__属性毫无例外地是指向Function函数的prototype对象,但是问题是Function函数中的prototype本身又是Object函数的实例对象,所以Function函数中的prototype对象中的__proto__属性就指向Object函数的prototype对象

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值