1. 构造函数创建对象
我们先使用构造函数创建一个对象
function Person() {}
let person = new Person()
person.name = 'xuexi'
console.log(person.name)// xuexi
这个例子里面Person是构造函数, 通过new Person创建一个实例
2. prototype
每个函数都一个prototype的属性:
function Person() {}
Person.name = 'xuexi'
let person1 = new Person()
let person2 = new Person()
console.log(person1.name) // xuexi
console.log(person2.name) // xuexi
函数的prototype属性指向一个对象, 这个对象正是调用这个构造函数而创建的实例对象, 也就是person1和person2的实例.
什么是原型呢? 你可以理解为: 每一个js对象(null除外)创建的时候都会与之关联另一个对象, 这个对象就是我们所说的原型, 每一个对象都会从原型上继承属性.
3. proto
每一个js对象(null除外),都有一个属性__proto__ , 这个属性指向该对象的原型
function Person() {}
let person = new Person()
console.log(Person.prototype === person.__proto__) // true
4. constructor
一个原型会指向一个构造函数, 每个原型都会有一个constructor属性指向该构造函数
function Person() {}
console.log(Person === Person.prototype.constructor) // true
所以可以得到
function Person() {}
var person = new Person()
console.log(Person === Person.prototype.constructor) // true
console.log(Person.prototype === person.__proto__) // true
5. 实例与原型
当读取实例的属性时, 如果找不到, 就会查找与对象关联的原型中的属性, 如果还找不到, 就去找原型的原型, 一直找到最顶层.
function Person() {}
Person.prototype.name = 'xuexi'
var person = new Person()
person.name = 'haohao'
console.log(person.name) // haohao
delete person.name
console.log(person.name) // xuexi
当我们删除person.name的属性的时候, 在去打印这个属性, 它自己是没有这个属性的, 就会去找它自己的原型, 从原型上查找到name为xuexi
6. 原型的原型
如果原型上没找到?原型的原型又是什么?
var obj = new Object()
obj.name = 'xuexi'
console.log(obj.name) // xuexi
其实原型就是通过Object构造函数生成的.
7. 原型链
那么Object.prototype的原型呢?
答案是: null
// 打印下结果
console.log(Object.prototype.__proto__ === null) // true
所以查找到Object.prototype的时候就可以停止查找了;