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代表父母自己)