Skip to content

原型与原型链

原型

什么是原型?

每一个js对象在创建的时候就会自动关联另一个对象,这个对象就是原型,每一个对象都会从原型"继承"属性

prototype

  • 每一个函数都有一个prototype属性
  • prototype 属性指向了一个对象,这个对象正是调用该构造函数而创建的实例的原型图片

示例

js
function Animal(){}
Animal.prototype.weight = 20

let dog1 = new Animal()
let dog2 = new Animal()
console.log(dog1.weight) // 20
console.log(dog2.weight) // 20

proto

  • 每一个js对象有一个__proto__属性
  • __proto__指向该对象的原型
  • __proto__ 绝大部分浏览器都支持这个非标准的方法访问原型,然而它并不存在于 Person.prototype 中,实际上,它是来自于 Object.prototype ,与其说是一个属性,不如说是一个 getter/setter,当使用 obj.__proto__ 时,可以理解成返回了 Object.getPrototypeOf(obj)。

图片

示例

js
function Animal(){ }
Animal.prototype.weight = 20

let dog1 = new Animal()
console.log(dog1.__proto__ === Animal.prototype) // true
// es5方法获取对象原型
console.log(Object.getPrototypeOf(dog1)===Animal.prototype) // true

constructor

  • 每个原型都有一个constructor属性
  • constructor属性指向关联的构造函数 图片

示例

js
function Animal(){ }

console.log(Animal === Animal.prototype.constructor) // true

let dog = new Animal()
// 从原型链上查找到的constructor属性
console.log(dog.constructor === Animal.prototype.constructor) // true
console.log(dog.constructor === Animal) // true

实例与原型

  • 读取实例属性时,实例上不存在时会从实例关联的原型中去查找
  • 如果原型中不存在,就去原型的原型查找,直到最后一层为止

示例

js
function Teacher() { }
Teacher.prototype.name = '老师'

function Student(name) {
    this.name = name + '同学'
}
Student.prototype = Object.create(Teacher.prototype)
Student.prototype.constructor = Student

let s1 = new Student('小明')
console.log(s1.name) // 小明同学
delete s1.name
console.log(s1.name) // 老师
console.log(s1.sex) // undefined

原型的原型

  • 原型也是一个对象,可以通过new Object()的方式创建
js
let obj = new Object()

function Animal(){}
let cat = new Animal()
// 实例对象的原型
console.log(cat.__proto__ === Animal.prototype) // true
// 原型的原型
console.log(Animal.prototype.__proto__ === Object.prototype) // true
// 实例对象的原型的原型
console.log(cat.__proto__.__proto__ === Object.prototype) // true

图片

原型链

相互关联的原型组成的链状结构就是原型链

图片

  • Object.prototype的原型为null
js
console.log(Object.prototype.__proto__ === null) // true
  • 当在原型链上查找到Object.prototype时停止查找