1、prototype
参考文章:http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html
prototype是每个函数都有的属性,这个属性指向函数的原型对象,默认这个对象会获得一个consturctor属性,另外这个属性也可以指向其他属性和方法,这样通过这个函数实例化的所有对象可以共享它指向的属性和方法,每次调用构造函数创建一个新实例,这个实例内部有个[[Prototype]]指针,这个指针可以通过__proto__访问,实例的__proto__等于构造函数的prototype属性。关系图如下:
更详细的例子:
//有关prototype和__proto__
let Person = function(){}
Person.prototype.sayName = function(){
console.log(this.name)
}
Person.prototype.name = 'Nicholas'
Person.prototype.age = 29
Person.prototype.job = 'Software Engineer'
let p1 = new Person()
let p2 = new Person()
//声明之后,构造函数就有了一个与之关联的原型对象prototype
console.log(typeof Person.prototype)
console.log(Person.prototype) //Person { sayName: [Function], name: 'Nicholas', age: 29, job: 'Software Engineer' }
console.log(Person.prototype === p1.__proto__)//true
console.log(p1.__proto__ === p2.__proto__)//true
//构造函数有一个prototype属性引用其原型对象,而这个原型对象也有一个constructor属性,引用构造函数,换句话说:两者循环引用
console.log(p1.__proto__.constructor === Person)//true
//正常的原型链都终止于Object的原型对象,Object的原型的原型是null或者undefined
console.log(Person.prototype.__proto__ === Object.prototype)//true
console.log(Person.prototype.__proto__ === Object.prototype)//true
console.log(Person.prototype.__proto__.prototype)//undefined
//可以用instanceof检查实例的原型链中是否包含指定构造函数的原型
console.log(p1 instanceof Person)//true
console.log(p2 instanceof Object) //true
console.log(Person.prototype instanceof Object) // true
console.log(Person.prototype.isPrototypeOf(p1))// true
console.log(Object.getPrototypeOf(p1) === Person.prototype)// true
console.log(Object.getPrototypeOf(p1).name)//Nicholas