原型
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引擎会深入原型链查找对象成员,因此对象在原型链位置越深,找到它越慢。