面向对象编程
构造函数
构造函数用于创建特定类型的对象,如Object和Array等。以函数的形式为自己的对象类型定义属性和方法。
1.this指向新对象;
2.每个对象都具有constructor属性,用于标识对象的“类型”。如:
jerry.constructor == Mouse
jerry instanceof Mouse (利用instanceof操作符判断对象“类型”更为可靠)
3.所有对象都会直接或间接的继承Object.prototype,即所有对象都是Object的实例。
构造函数的问题与原型继承
构造函数的问题
同一构造函数的实例会创建自己的方法(Function实例)。
但是,同一个方法应该是完成相同的任务,没有必要创建多个相同的方法。如果对构造函数进行改进,将其中的方法放入到全局中能够解决创建多个相同方法的问题,但也会产生新的问题——导致作用域混乱以及不方便管理,即构造函数方法被定义为全局函数,只有构造函数创建的对象才能调用。
这个新的问题解决方法为利用原型模式将构造函数的方法定义在原型对象上;
构造函数与原型继承结合的优点
利用构造函数构建对象结构,从语义上较为清晰的表达对象结构。
利用构造函数原型扩展,能方便的为该构造函数所创建的对象进行基于原型的扩展。
利用构造函数还可以进行基于原型对象的继承
原型继承
构造函数、原型和实例的关系:
每个构造函数都有一个原型对象。
原型有一个属性指回构造函数
实例有一个内部指针[[Prototype]]指向原型。
例如:
当对象原型是另一个构造函数的实例时,如此迭代就形成了原型链。
但该原型链存在以下问题:
1.当实例对继承而来的属性进行修改时,由于该属性是对原型属性的引用,所以会影响创建的全部实例
2.子类型在实例化时不能向父类型传递参数
盗用构造函数
在子类构造函数中调用父类构造函数,并将子类当前实例只定为构造函数的上下文(this)。
但也存在问题:无法访问父类原型上定义的方法
Animal.prototype.show = function () {
console.log(this.colors, this.type);
};
let m2 = new Mouse(“Miney”, 9); m2.show();——无法访问
问题解决:原型链与盗用构造函数的组合