You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
function Animal(){
this.type = 'animal;'
}
function Cat(name, color){
this.name = name
this.color = color
//这里用call,个人觉得更好些
Animall.call(this)
}
var cat = new Cat('po', 'orange')
console.log(cat.type) //animal
function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
extend(Cat,Animal);
var cat1 = new Cat('po' 'orange');
alert(cat1.eat()); // animal eat
这里Child.uber = Parent.prototype的意思类似于__proto__。
拷贝继承
这里还有一种简单粗暴的方式
function extend2(Child, Parent) {
var p = Parent.prototype;
var c = Child.prototype;
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
}
function Animal(){}
Animal.prototype.eat = function(){ console.log('animal eat') }
extend2(Cat, Animal);
var cat1 = new Cat('po' 'orange');
alert(cat1.eat()); // animal eat
直接遍历父类的原型,一个个复制到子类原型上即可。
感慨一下,大佬还是大佬呀。。。:smile:
The text was updated successfully, but these errors were encountered:
学习一波阮一峰的博客 戳这里 👍
博客中是自己的理解,以及对大佬描述不清楚的地方进行了修正,也算是自己的一个再(xiao)产(tu)出(cao)吧
上一篇:JavaScript面向对象之一(封装)
构造函数进行继承
先来看个简单的:
创建了一个Animal和Cat构造函数,然后在Cat里面调用Animal的构造函数,在将Cat实例化,就可以访问到Animal的属性了。
这个例子显然有问题,放在第一个就是用来找茬的。
什么问题呢?假如我想使用在Animal上的公共方法,像这样
Animal.prototype.eat = function(){ console.log('animal eat') }
,用cat.eat()
是访问不到的。为什么呢?因为我们Cat和Animal的原型根本就没有关联起来呀。你看看咱们上面的代码,那个地方关联过?
使用原型进行继承
那下面我们就将两者的原型关联起来试试看
这种方法好!可以拿到属性和方法,一举两得。但是,这里有个陷阱(keng)!!!
Cat.prototype = new Animal()
之后,我们的Cat.prototype里面的所有方法都消失了!这是怎么回事?因为new,new做了四件事,这里再次回顾一下:看到了吗?new会使用一个空对象并且将其返回。这样一来我们的Cat.prototype就被清空了(包括自身的constructor)。所以我们需要自己多做一件事
Cat.prototype.constructor = Cat
。如果我们不这样做,那么Cat.prototype的构造函数会是什么?我们在去看看new做的第二件事,这个空对象指向了Animal.prototype,所以Cat.prototype自身如果没有constructor属性的话就会去Animal.prototype上面去找。
Cat.prototype.constructor === Animal //true
所以,如果我们替换了prototype,需要手动去纠正它。
直接继承prototype
既然上面这种方法有坑,而且的的确确让你很容易漏掉,那我们改进一下:
既然我们想从Animal.prototype上面那东西,直接从上面拿不就行了?而且我还机智的填了上面会出现的坑。同时结果也是我想要的。
但是!!我们的Cat.prototype和Animal.prototype指向的是同一个原型,这会导致我在Cat.prototype上做了什么事,会同时发生在Animal.prototype上。这是为什么呢?MDZZ,这两个就是同一个东西呀,原型是堆中一块内存,Cat和Animal都指向这块内存,操作的是同一个东西,怎么会不影响?
与此同时,自以为聪明的填坑
Cat.prototype.constructor = Cat
,此时的Cat和Animal的原型是同一个,修改了constructor之后,导致Animal的constructor变成了Cat。这种方法果断PASS。。。利用空对象作为中介
我们使用中间对象进行过度,巧妙的将Cat.prototype和Animal.prototype解耦,这样就不会出现问题了。仔细观察会发现这个和new做的事情有异曲同工之处。
我们进行封装一下在使用
这里
Child.uber = Parent.prototype
的意思类似于__proto__
。拷贝继承
这里还有一种简单粗暴的方式
直接遍历父类的原型,一个个复制到子类原型上即可。
感慨一下,大佬还是大佬呀。。。:smile:
The text was updated successfully, but these errors were encountered: