4. 原型式继承
借助原型可基于已有的对象创建新对象。同时还不必因此创建自定义类型。
function object(o){ function F(){} F.prototype = o; return new F(); }
在object()函数内部,先创建了一个临时性的构造函数,然后将传入的对象作为这个构造函数的原型。最后返回这个临时类型的一个新实例。
从本质上讲,object()对传入其中的对象执行了一次浅复制。
var person = { name: "Bob", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = object(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var anotherPerson1 = object(person); anotherPerson1.name = "Linda"; anotherPerson1.friends.push("Barbie"); alert(person.name); //Bob alert(person.friends); //Shelby,Court,Van,Rob,Barbie
原型式继承要求必须有一个对象可以作为另一个对象的基础。如果有这么一个对象,就可以把它传递给object()函数,然后在根据具体需求对得到的对象加以修改。
在上面的例子中,可以作为另一个对象基础的是person对象,把它传入到object()函数中,该函数就会返回一个新对象。
这个新对象将person作为原型,所以它的原型中就包含一个一个基本类型值name和一个引用类型值friends。
实际上,这就相当于又创建了person对象的两个副本。
ECMAScript5通过新增Object.create()方法规范了原型式继承。这个方法接收两个参数。一个用作基础对象,一个为新对象定义额外属性(可选的)。
var person = { name: "Bob", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = Object.create(person); anotherPerson.name = "Greg"; anotherPerson.friends.push("Rob"); var anotherPerson1 = Object.create(person); anotherPerson1.name = "Linda"; anotherPerson1.friends.push("Barbie"); alert(person.name); //Bob alert(person.friends); //Shelby,Court,Van,Rob,Barbie
Object.create()方法的第二个参数 与 Object.defineProperties()方法的第二个参数格式相同:每个属性都是通过自己的描述符定义的。以这种方式指定的任何属性都会覆盖原型对象上的同名属性。
var person = { name: "Bob", friends: ["Shelby", "Court", "Van"] }; var anotherPerson = Object.create(person, { name: { value: "Greg" }, age: { value: 18 } }); alert(anotherPerson.name); //Greg alert(anotherPerson.age); //18 alert(person.name); //Bob