JS查漏补缺——JavaScript的原型链

75 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第5天,点击查看活动详情

JavaScript原型链

从一个对象上获取属性,如果在当前对象中没有获取到就会去它的原型(proto)上面获取([get]操作)

var obj = {
	a: 1
}
// 原型链
obj.__proto__ = {
}
obj.__proto__.__proto__ = {
  b:2
}
console.log(obj.b) // 会沿着原型链依次往下找

那如果里面没有这个属性呢,这样不就会一直找下去了吗?

不会的,Object的原型链也是有尽头的

原型链的尽头——[Object: null prototype] {}

但我们打印Object.__proto__的日志的时候发现控制台打印出[Object: null prototype] {} ,就可以知道已经找到原型链的尽头了,再console.log(Object.__proto__.__proto__)控制台就会打印null

例1:有我们想要找的属性

var obj = {
	a: 1
}
// 原型链
obj.__proto__ = {
}
obj.__proto__.__proto__ = {
  b:2
}
console.log(obj.b) // 会沿着原型链依次往下找
// 这个例子原型链的尽头
console.log(obj.__proto__.__proto__.__proto__) //[Object: null prototype] {}
console.log(obj.__proto__.__proto__.__proto__.__proto__)//null

例2:没有我们想要找的属性

var obj = {
    a: 1
}

obj.__proto__ = {
}
console.log(obj.b) //undefined
console.log(obj.__proto__) //{}
console.log(obj.__proto__.__proto__) //[Object: null prototype] {}

总结:我们没有往obj的原型[proto]上额外去添加属性,那么它下一个原型[proto]就是原型链的尽头——[Object: null prototype] {}

例3:对于构造函数的原型链

function Person() {
 
}

console.log(Person.prototype.__proto__) //[Object: null prototype] {}
console.log(Person.prototype.__proto__.__proto__) //null

[Object: null prototype] {} 原型有什么特殊吗?

  • 特殊一:该对象有原型属性,但是它的原型属性已经指向的是null,也就是已经是顶层原型了;
  • 特殊二:该对象上有很多默认的属性和方法;

扩:__proto__和prototype的区别(更加详细的可去看上篇文章的内容)

本来是没有__proto__这个东西的,是浏览器加的,就是为了让你能找到一个实例的构造函数的原型

__proto__代表指针和prototype代表主体,prototype.__proto__指向下一个prototype

(例:__proto__指向父母,prototype代表父母自己)