javascript prototypes,prototype chain

247 阅读1分钟

原型

javaScript对它创建的每一个对象,都会设置一个内部属性(.__proto__),指向它的原型对象(.prototype)。

这个原型对象(.prototype)包含了一个新创建的对象所必须包含的成员列表。它不同于类,类定义了创建对象的过程,而原型对象为所有对象实例共享,因此这些对象实例也共享原型对象的成员。

var a = ['a1', 'a2', 'a3'];
var b = ['b1', 'b2', 'b3'];
a.__proto__ === b.__proto__; //true
a.__proto__ === Array.prototype; // true

如上,一旦创建了一个内置对象(Array, Object)的实例, 它们自动会拥有一个Array实例作为原型。

javascript引擎在用object.xxx来访问对象实例的时候,首先会查找对象的实例成员(对象上定义的)。如果没有,会查找其原型成员(原型对象上继承来的),如果还是没有会一直上溯到Object.prototype,最后还是没有找到就会返回undefined.

var book = { title: "book1", desc: "book1 desc"};
book.toString(); //"[object Object]" 
book.toString === Object.prototype.toString; //true
book.hasOwnProperty("toString"); //false

如上,book对象本身并没有toString方法,实际调用了原型对象上的方法。Tip

"toString" in book; // true

原型链

除了对象原型,你可以自己创建构造函数原型.

funcion Book(title, desc){
    this.title = title;
    this.desc = desc; 
}
Book.prototype.sayName = function(){
    return this.name;
}
var book1 = new Book('book1', 'book1 desc');
var book2 = new Book('book2', 'book2 desc');
// 原型链
// book1 --> Book.prototype --> Object.prototype --> null
book1.__proto__ === Book.prototype;//true
Book.__proto__ = Object.prototype;//true

这两个Book实例共享同一个原型链,他们有着各自的属性,而其他部分都继承自原型。

Tip: .方法搜索时,javascript引擎会深入原型链查找对象成员,因此对象在原型链位置越深,找到它越慢。