JavaScript继承(二)——借用构造函数

JavaScript继承(一)——原型链中提出原型链继承的两个问题:一是原型的数据共享问题,二是创建子类型的实例时,不能向父类型的构造函数中传递参数。这两个问题的根源还是在于使用原型模式创建对象,可以参考JavaScript创建对象(三)——原型模式。本篇文章来讨论一下这两个问题的解决方案——借用构造函数继承。

借用构造函数也被称为伪造对象或经典继承。这种技术的基本思想相当简单,即在子类型构造函数的内部调用父类型构造函数。在Javascript中,从本质上来讲,我们声明的函数不过是Function类型在特定执行环境中执行代码的实例,因此可以通过使用apply方法在创建子类型的对象时,把子类型的执行环境传递给父类型。

首先我们来看下apply的用法,如下代码所示:

var nums = {
  n1: 10,
  n2: 8
}

function sum(a, b) {
  console.log(this);
  console.log(arguments);
}
sum(2, 4);//this: window 。 arguments:[2, 4]
sum.apply(nums, [2, 4]);//this: nums 。 argument:[2, 4]

直接调用sum时,函数sum中的this指代的是调用sum的执行环境的变量对象,即全局变量对象window,使用sum.apply的形式调用,第一个参数传的nums,第二个参数传的数组,那么sum在执行时,this指的就是numsarguments指的就是传入的参数数组。

明白了apply的用法,下面我们来看借用构造函数继承,如代码所示:

function Human(){
  this.colors = ['yellow', 'white', 'black'];
}
function Person(){
  Human.apply(this);
}
var p1 = new Person();
p1.colors.push('brone');
console.log(p1.colors);//["yellow", "white", "black", "brone"]

var p2 = new Person();
console.log(p2.colors);//["yellow", "white", "black"]

Human中声明了一个数组colorsPerson中使用apply的方式调用Human,并把this传递给Human,以实现Person继承Human,当执行new Person()时,函数Person中的this指的就是新创建出的对象,接着就会传递到Human,于是这个新对象上就有了colors属性,实现了继承的效果,通过这种方式,每次创建对象时,子类型中都生成了父类型中定义的属性的一个副本,没有共享属性,也就不存在数据共享的问题了。

另外,对于在子类型构造函数中向超类型构造函数传递参数的问题来看以下示例:

function Human(){
  this.name = arguments[0];
}
function Person(name){
  Human.apply(this, arguments);
  //重新定义子类型的属性,防止被父类型覆盖
  this.age = 18;
}
var p1 = new Person('Bob');
console.log(p1.name);//Bob
console.log(p1.age);//18

创建Person的实例时传递了一个参数Bob,在构造函数中通过apply的方式又将参数传递给了Human,在Human中进行赋值操作实际上就是给新创建的实例设置name属性。为了防止子类型的属性被重写,可以在调用超类型的构造函数之后再添加应该在子类型中定义的特有的属性。

如果仅仅是借用构造函数,那么也将无法避免构造函数模式存在的问题——方法都在构造函数中定义,因此函数复用就无从谈起了。而且,在超类型的原型中定义的方法,对子类型而言也是不可见的,因为整个过程中并没有创建超类型的对象,根据原型链的特征,自然也就无法使用超类型的原型,结果继承链上的所有类型都只能使用构造函数模式创建对象。考虑到这些问题,借用构造函数继承的技术也是很少使用的。

读者也许已经想到可以组合使用构造函数和原型链继承,就像组合使用构造函数模式和原型模式创建对象一样,那么下一篇文章就来谈谈组合继承。

转载于:https://my.oschina.net/bob1900/blog/3003856

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值