伪类
当一个函数对象被创建的时候,Function构造器产生的函数对象会运行类型这样一些代码:
this.prototype={constructor:this};
新函数对象被赋予一个prototype属性,并且其值包含一个constructor属性且属性值为该新函数对象。 当使用new关键字去调用一个函数时,将修改函数的执行方式。 大致会执行以下几个过程:
- 创建一个新对象,继承自函数对象的原型(重点,继承非函数对象本身而是它的原型)
- 调用函数,绑定this到新对象上。(apply方法)
- 返回新对象
伪类方式的继承是通过定义一个构造函数以及替换prototype来实现的。
以下代码实现伪类继承 定义Person类构造函数以及定义getName方法
var Person= function (name) {
this.name=name;
}
Person.prototype.getName=function(){
return this.name;
}
定义学生类构造函数并继承Person获得getName方法
var Student=function(name,num){
this.name=name;
this.num=num;
}
Student.prototype=new Person();
Student.prototype.getNum= function () {
return this.num;
}
这种继承方式,所有属性可以被随意修改,并且无法访问父类的方法。
原型
基于原型的继承更为简单。使用对象字面量创建一个对象,其他对象可以直接通过prototype即可完成继承。
函数化
前两种继承方式都存在属性对外可见的问题,而利用模块模式可以避免这种缺陷。通常需要以下几个步骤:
- 创建一个对象可以(可以使用包括new、对象字面量等任何方式)。
- 选择性的定义私有变量和方法(通过var)。
- 给新对象扩充方法,这些方法拥有特权访问参数以及第二步定义的私有变量。
- 返回新对象。
下面代码使用这种方式实现继承
var person= function (pro) {
var that={};
that.getName=function(){
return pro.name;
}
return that;
}
var student=function(pro){
var that=person(pro);
that.getNum= function () {
return pro.num;
}
return that;
}
这种方式还避免原型方式需要重写构造函数的麻烦,我们只需要调用父类构造函数,然后专注差异部分的创建。
这种继承方式还可以调用父类的方法。