原型和原型链

91 阅读2分钟

JavaScript深入之从原型到原型链

构造函数创建对象

先使用构造函数创建一个对象

function Person(){
}  
// Person是一个构造函数
var person = new Person()  
// new创建了一个实例对象person
person.name = 'jin';
console.log(person.name)  //jin
  • prototype

每一个函数都有一个prototype属性(prototype是函数才有的属性)

function Person(){
}
Person.prototype.name = 'jim'
var person1 = new Person();
var person2 = new Person();
console.log(person1.name) //jim
console.log(person2.name) //jim

总结:函数的prototype属性指向了一个对象,这个对象正是调用该构造函数而创建的实例的原型,也就是案例中person1和person2的原型

对原型的理解:每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型继承属性

构造函数与实例原型的关系

实例和实例原型的关系 也就是person 和Person.prototype之间的关系需要了解第二个属性 _ proto_

  • _ proto_ 这是每一个JavaScript对象(除了null)都具有的一个属性叫_ proto_ 这个属性会指向该对象的原型
function Person(){
}
var person = new Person();
console.log(person._proto_ === Person.prototype)  //true

于是我们更新一下关系图

既然实例对象和构造函数都可以指向原型,那么原型是否有属性指向构造函数或者是实例呢?

  • constructor 每一个原型都有一个constructor属性指向关联的构造函数
function Person(){
}
console.log(Person === Person.prototype.constructor) // true

于是在更新一下关系图:

综上

function Person(){
}
var person = new Person()
console.log(person._proto_ == Person.prototype)  //true
console.log(Person.prototype..constrctor == Person) // true
console.log(Object.getPrototypeOf(person)=== Person.prototype) //true

实例和原型

当读取实例的属性时,如果找不到,就会查找与对象关联的属性中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止

原型的原型

原型也是一个对象,既然是对象,那就可以用最原始的方式创建

var obj = new Object()
obj.name = 'jim';
console.log(obj.name) // jim

其实原型对象就是通过Object构造函数生成的结合之前所讲 ,实例的_proto_指向构造函数的prototype所以再次更新一下关系图

原型链

那Object.prototype的原型呢 是null

null代表没有对象。即该处不应该有值

console.log(Object.prototype._proto_ === null )  //true

所以Object.prototype._proto_的值为null 跟Object.prototype没有原型 是一个意思

补充

  • constructor
function Person(){
}
var person = new Person()
console.log(person.constructor === person) // true

当获取person.constructor时,其实person并没有constructor属性,当不能读取到constructor属性时会从person的原型也就是Person.prototype中读取,正好原型中有该属性 所以:

person.constructor === Person.prototype.constructor
  • proto 绝大多数浏览器都支持这个非标准的方法访问原型,但是它并不存在于Person.prototype,实际上它是来自于Object.prototype,与其说是一个属性 不如说是一个getter/setter 当使用Obj._proto_时,可以理解返回了Object.getPrototypeOf(obj)

学习篇 转载:冴羽大佬的博客