对象的继承

构造函数的毛病

面向对象编程很重要的一个方面,就是对象的继承。A 对象通过继承 B 对象,就能间接领有 B 对象的所有属性和办法

function Cat(name, color) {  this.name = name;  this.color = color;  this.meow = function () {    console.log('喵喵');  };}var cat1 = new Cat('大毛', '红色');var cat2 = new Cat('二毛', '彩色');cat1.meow === cat2.meow// false

cat1cat2是同一个构造函数的两个实例,它们都具备meow办法。因为meow办法是生成在每个实例对象下面,所以两个实例就生成了两次。也就是说,每新建一个实例,就会新建一个meow办法。这既没有必要,又节约系统资源,因为所有meow办法都是同样的行为,齐全应该共享。

prototype 属性的作用

每个函数都有一个prototype属性,指向一个对象。

function f() {}typeof f.prototype // "object"

原型对象的属性不是实例对象本身的属性。只有批改原型对象,变动就立即会体现在所有实例对象上。

Animal.prototype.color = 'yellow';cat1.color // "yellow"cat2.color // "yellow"

原型链

Object.prototype的原型是nullnull没有任何属性和办法,也没有本人的原型。因而,原型链的止境就是null

Object.getPrototypeOf(Object.prototype)// null

如果让构造函数的prototype属性指向一个数组,就意味着实例对象能够调用数组办法。

var MyArray = function () {};MyArray.prototype = new Array();MyArray.prototype.constructor = MyArray;var mine = new MyArray();mine.push(1, 2, 3);mine.length // 3mine instanceof Array // true

constructor 属性

prototype对象有一个constructor属性,默认指向prototype对象所在的构造函数。

function P() {}P.prototype.constructor === P // true

因为constructor属性定义在prototype对象下面,意味着能够被所有实例对象继承。

function P() {}var p = new P();p.constructor === P // truep.constructor === P.prototype.constructor // truep.hasOwnProperty('constructor') // false

nstanceof 运算符 #

instanceof运算符返回一个布尔值,示意对象是否为某个构造函数的实例。

var v = new Vehicle();v instanceof Vehicle // true