题外话:先用构造函数构造一个实例对象
var log=console.log.bind(console)
function Person(){ //创建一个构造函数
}
var person1=new Person() //构造一个实例对象person1
person1.name='张三'
log(person1.name)//张三
// 每个函数都有一个prototype属性,这是函数特有的属性
Person.prototype.name='李四'
var person2=new Person()
log(person2.name)//李四
这个prototype就等于创建实例对象的原型也就是person1和person2的属性__proto__
每一个JavaScript对象(除了 null )都具有的一个属性,叫__proto__,这个属性会指向该对象的原型。
log(person1.__proto__===Person.prototype)//true
log(person2.__proto__===Person.prototype)//true
再看几个公式:
var 对象 = new 函数()
对象.__proto__ === 对象的构造函数.prototype
// 推论
var number = new Number()
number.__proto__ = Number.prototype
var object = new Object()
object.__proto__ = Object.prototype
var function = new Function()
function.__proto__ = Function.prototype
// 另外,所有函数都是由 Function 构造出来的,所以
Number.__proto__ = Function.prototype // 因为 Number 是函数,是 Function 的实例
Object.__proto__ = Function.prototype // 因为 Object 是函数,是 Function 的实例
Function.__proto__ == Function.prototye // 因为 Function 是函数,是 Function 的实例!
__proto__(隐式原型)与prototype(显式原型)的定义:
prototype:一个函数在创建之后都会拥有一个名为prototype的属性,这个属性指向以当前函数作为构造函数构造出来的对象的原型对象。
__proto:__是每个对象都有的一个属性
区别:
__proto__是每个对象都有的一个属性,而prototype是函数才会有(函数也有__proto__)的属性。
__proto__指向的是当前对象的原型对象,而prototype指向它的构造函数的原型对象。
作用:
1、肯定是为了继承!
2、prototype用来实现基于原型的继承与属性的共享。
3、__proto__就构成了我们常说的原型链,同样用于实现基于原型的继承。
关系:
当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。
举个例子:
Person.prototype.name='李四'
var person2=new Person()
log(person2.name) //李四
person2.name='张三'
log(person2.name)//张三
delete person2.name
log(person2.name) //李四
如何原型上没有定义name属性呢,是不是就找不到了?
当然不是,因为原型也是一个对象,既然是对象就按对象分方式来查找。
请看:
1、f1和f2这两个对象的属性__proto__,指向构造函数(Foo)的原型对象(当前对象的原型对象)。
2、构造函数Foo()原型属性Foo.prototype指向了原型对象(prototype指向它的构造函数的原型对象)。
其它:
1、原型对象的__proto__指向它的构造函数的原型对象。
2、原型对象也有一个属性,叫做constructor,这个属性包含了一个指针,指回原构造函数。
// constructor
log(Person===person1.constructor)//true
log(Person===person2.constructor)//true
注意:上面的代码中person1和person2均没有constructor属性,它们会去Person的prototype上去找
log(Person.prototype.constructor===person2.constructor)//true
3、Object.prototype的__proto__属性指向null。