JavaScript中原型和原型链

原型[prototype]:

为其他对象提供共享属性的对象。

每个函数都有一个原型(prototype)属性,这个属性是一个指针,指向一个对象,这个对象包含特定实例共享的一些属性和方法。

 

以例服人:

这个例子说明了原型对象是共享的,并且是一个指针,并且对象的实例中也有指向prototype指向对象的指针。

function Animal(name) {
    this.name = name || "动物";
}
Animal.prototype.runs = function() {
    console.log(this.name + ',跑起来了\n')
}
var dog = new Animal('小狗')
dog.runs()  //输出"小狗跑起来了"

// 下面增加的方法,dog对象可以使用吗?
Animal.prototype.hi = function() {console.log('hi')}
dog.hi() //输出"hi",说明原型属性是一个指针,指向一个共享对象,不管先添加的还是后添加的方法都能调用

//dog作为一个Animal实例,他的__proto__属性和Animal.prototype指向同一个对象,所以才可以使用原型的方法。
console.dir(dog) // 查看 dog.__proto__

// dog.__proto__  &  Animal.prototype
console.log(dog.__proto__ === Animal.prototype) //true,有相同的指针地址

 

原生构造函数的原型对象[不单函数有原型对象]

console.dir(Object.prototype)

console.dir(Array.prototype)

console.dir(String.prototype)

console.dir(Date.prototype)

 

再看一个__proto__  &  prototype的例子

var obj = { }
obj.toString()   // "[object Object]"

//obj 对象为什么有 toString 方法?

//因为 obj 对象是 Object 构造函数的实例,obj 对象的原型指针指向 Object.prototype 对象。console.log(obj.__proto__  === Object.prototype )

通过原型关系图理解:

 

再看一个函数的原型的例子

var obj = {name: 'jack'}
function getName() {
    console.log(this.name)
}

// 问题:Animal.call 方法来自哪?
getName.call(obj)  //来自Function对象

console.dir(getName)
console.log(getName.__proto__  === Function.prototype)  //true
console.log(Function.prototype.__proto__  === Object.prototype)  //true

通过原型关系图理解

原型继承:

function Animal() {
    this.name = '动物'
}

Animal.prototype.runs = function() {
    console.log(this.name + ',跑起来了\n')
    return this
}

function Bird() {
    this.name = '鸟'
}
Bird.prototype = new Animal()  //让Bird的原型等于Animal的实例,因为new Animal中有__proto__指向Animal.prototype的指向(沿着原型链寻找),此处也可以写为Bird.prototype = Animal.prototype
Bird.prototype.fly = function() {
    console.log(this.name + ',飞走了\n')
    return this
}

function Crow(name) {
    this.name = name || '乌鸦'
}
Crow.prototype = new Bird()
Crow.prototype.drink = function() {
    console.log(this.name + ',喝饱了水\n')
    return this
}

var crow = new Crow('一只可爱的小乌鸦')
crow.drink().runs().fly()

console.dir(crow)

输出结果:

 

 

原型总结:

每一个构造函数都有一个和其对应的原型对象。

构造函数的 prototype 属性和其实例对象的 “__proto__” 属性指向同一个对象。

某构造函数的所有实例对象,共享一份原型对象。

所有的对象都可以通过 “__proto__” 属性,最终连接到 Object.prototype 对象。

构造函数用 prototype 来定义原型的属性和方法,实例对象用 “__proto__” 来查找原型的属性和方法。

当查找一个对象的属性或方法时,JS引擎会向上遍历其原型链,直到找到给定名称的属性为止。如果最终在 Object.prototype 对象仍然没有找到此属性或方法,则返回 undefined 值。

posted @ 2015-02-05 17:54  leezhxing  阅读(342)  评论(0编辑  收藏  举报