原型
显示原型-隐式原型
1.构造函数上有显示原型,往函数原型身上添加属性时,当函数的构造出来的对象在自身上找不到属性就会去原型上面找
Person.prototype.name = 'ok'
function Person() {
}
var person = new Person()
console.log(person.name)//输出ok
原型是函数function的一个属性,也是一个对象,可以说它定义了函数构造出来的对象的公共祖先,
通过该函数构造的对象,可以继承到该原型的属性和方法。
2. 引用对象上有隐式原型 _proto_ 也就是[[Prototype]](是同一个东西,只不过后者是谷歌浏览器的写法)
隐式原型跟显示原型的关系
引用对象的隐式原型其实就等于将它构造出来的那个函数的显示原型!
Person.prototype.age = 20
function Person() {
}
var person = new Person()
console.log(person.age)//输出20
person._proto_==Person.prototype(给的是引用地址)
其实一个对象在自己身上找不到该有的属性是时,就会去隐式原型上找,而隐式原型上的值就是在构造对象时函数将自己的显示原型的引用地址赋给它的。例如对象person上并没有name属性,所以去自己的隐式原型上找,而自己的隐式原型上面的引用地址就是自己的构造函数Person上的显示原型prototype,所以我们可以说当函数的构造出来的对象级在函数身上找不到属性时就会去构造函数的显示原型上面找
constructor
constructor也是对象上的一个属性 用来查看该对象的构造函数是谁
Person.prototype.name = 'ok'
function Person() {
}
var person = new Person()
console.log(person.name)//输出ok
person是Person构造出来的所以constructor的值是 f Person
原型链
- 定义:在原型链上加一个原型,再加一个原型.....把原型形成链,访问顺序也是依照这个链的顺序,叫做原型链,
-proto_就相当于链子节点。
我们来分析上面这张图!
f的__proto__指向Fo的显示原型,应为f是fo构造出来的,是它的构造器。
而Fo.prototype也是一个对象,它也有__proto__,而它的隐式原型当然指向它的构造函数的显示原型Foo.prototype,依次类推,但是很多人想这会不会陷入一个死循环。当然不会!应为最终点对象的隐式原型指向对象之父-Object的显示原型,应为所有对象的源头都是Object,而Object.prototype最终指向null。
所有的对象都有原型吗?
var obj=Object.creat(null)
这种方式构造出来的对象没有原型 .也没有办法加隐式原型,如果直接加就会被当成普通属性加上去
也没有继承Object.prototype,它可以用来创建纯净的对象
var obj = Object.create(null)
obj.__proto__ = 'ok'
console.log(obj);//[Object: null prototype] { ['__proto__']: 'ok' }
undefined/null也没有原型对象