单身狗和动物的故事 —— Javascript继承

闲话少叙,继续讲单身狗的故事。

动物,单身狗

function Animal(){
    this.type = "动物";
}
function Dog(name) {
    this.type = '动物';
    this.name = name;
}

我们知道,单身狗是一种动物,那么工厂怎么来表示这种继承关系呢?

1. 进化方式1(构造函数绑定)

function Animal(){
    this.type = "动物";
}
function Dog(name) {
    Animal.call(this); // Animal.apply(this); 也可以
    this.name = name;
}

var dog = new Dog('单身狗');
console.log(dog.name, dog.type); // 单身狗 动物

2. 进化方式2(prototype模式)

前提知识:
原型链继承方式最终表达为:

var dog = new Dog();
// 获得父类和爷爷类方法如下
dog.__proto__.__proto__.__proto__;
2.1 那么 __proto__ 这个是怎么来的呢?
// 实例的__proto__是引用构造函数的prototype
dog.__proto__ === Dog.prototype; // true

按照上面代码的逻辑父类应该怎么继承就变成了这样:

Dog.prototype.__proto__ === Animal.prototype; // true

那么怎样达到上面代码的效果呢?

Dog.prototype = new Animal();

这种方式有什么问题?
每个prototype都有一个constructor,指向构造方法本身:

Dog.prototype.constructor === Dog; // true

执行以上代码后就变成了:

Dog.prototype.constructor === Animal; // true

这样就破坏了构造方法的基本结构。
为什么会变成这样?
实际上调用方法内部是这样执行的:
1.先在Dog.prototype上查找 constructor 属性,实际上没找到;
2.再在Dog.prototype 的原型链查找上一级原型是否含有这个属性 Dog.prototype.__proto__.constructor
3.发现有一个叫做 constructor 的属性,然后返回这个属性。

怎么解决?

// 加一句
Dog.prototype.constructor = Dog;

完整版:

Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
var dog = new Dog();

完美!

2.2 思考另外一种方法
// 是否可以这样实现子类继承父类?
Dog.prototype = Animal.prototype;
Dog.prototype.constructor = Dog;
var dog = new Dog();

测试:

Animal.prototype.constructor === Dog; // true

问题:
改掉了父类的构造方法。

2.3 终极继承大法!
var F = function(){};
F.prototype = Animal.prototype;
Dog.prototype = new F();
Dog.prototype.constructor = Dog;

优点:
节能环保

3. 彩蛋

new Dog() 被执行时干的活:
1. Dog 方法内创建一个对象, this指向这个对象;
2. this.__proto__ = Dog.prototype
3. 执行 Dog方法内的逻辑;
4. 方法最后一定返回一个对象。分以下几种情况

  1. 如果没有 return ,则返回 this
  2. 如果有 return,且 return 返回的是一个js的原始数据,方法返回 this。反之,方法返回 return 关键字后面的对象。
var self;
function foo(){
    self = this;
    this.name='a';
} 
foo.prototype.getName = function() {
    return this.name;
}

var f = new foo();
console.log(f === self);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值