Description
call实现继承
call这里call的意思就是把animal的方法应用到cat这个对象身上,也就是animal的属性创建到了cat里面,所以cat就继承了animal的方法
function animal(a, b) {
this.type = 'animal'
this.behavior = function () {
console.log(this.type + " is running")
}
}
function cat(a, b) {
this.name = 'wsscat'
//这里call的意思就是把animal的方法应用到cat这个对象身上
//所以cat就继承了animal的方法
animal.call(this);
}
console.log(new cat())
call实现多重继承
当然我们可以继承多个构造函数,这就是多重继承
function animal(a, b) {
this.type = 'animal'
this.behavior = function () {
console.log(this.type + " is running")
}
}
function wsscat(a, b) {
this.age = 0
}
function cat(a, b) {
this.name = 'wsscat'
//这里call的意思就是把animal的方法应用到cat这个对象身上
//所以cat就继承了animal的方法
animal.call(this);
wsscat.call(this);
}
console.log(new cat())
只要在cat的构造函数中有多个call就可以,此时的cat继承了wsscat和animal
apply和call的区别
其实apply和call这两个方法基本上是差不多的,区别在于call的第二个参数可以是任意类型,而apply的第二个参数必须是数组,也可以是arguments(即传给构造函数的参数)
例如我们把上面的代码稍微改一下,如果此时我在new构造函数cat的时候传入参数new cat('wsscat','cute')
我们的cat能接收arguments,但是如果此时继承是animal.call(this)
,没有给call传第二个参数的时候,生成的对象中type的值就会是undefined,所以为了让这个值能够让animal接收,我们可以在animal中传入第二个参数animal.call(this,type)
function animal(type) {
this.type = type
this.behavior = function () {
console.log(this.type + " is running")
}
}
function cat(name, type) {
this.name = name
//这里call的意思就是把animal的方法应用到cat这个对象身上
//所以cat就继承了animal的方法
//animal.call(this);//type undefined
//animal.call(this,type);//type cute
//animal.call(this,arguments[1]);//type cute
//animal.call(this,arguments);//type ['wsscat','cute']
animal.apply(this, arguments) //type: wsscat
}
console.log(new cat('wsscat', 'cute'))
这里用apply就很方便,因为arguments是数组,可以全部传给animal,而call就要一个个地传过去
- animal.call(this);//type undefined
- animal.call(this,type);//type cute
- animal.call(this,arguments[1]);//type cute
- animal.call(this,arguments);//type ['wsscat','cute']
- animal.apply(this,arguments)//type: wsscat
继承的优化
如果构造函数this绑定太多属性(比如一些共同方法),在实例化后会造成浪费,为此我们一般会使用原型链来优化,但是使用原型链之后我们的apply和call的继承方法就会失效
为此我们一般使用混合的写法,使用原型链和(apply或者call)方法进行继承
具体两句话
让子的原型链指向父的实例(父实例化的对象)
cat.prototype = new animal();
让父的属性创建在子的this上
animal.call(this, type)
整体代码如下,那么就会让父原型链的属性和this上的属性都得到继承
function animal(type) {
this.type = type
this.behavior = function () {
console.log(this.type + " is running")
}
}
animal.prototype.action = function () {
console.log("running")
}
function cat(name, type) {
this.name = name
animal.call(this, type)
}
cat.prototype = new animal();
console.log(new cat('wsscat', 'cute'));
(new cat('wsscat')).action() //running
Activity
[-]Javascript中的apply和call[/-][+]Javascript中的apply和call继承[/+]Wbiokr commentedon Dec 9, 2016
handsome
AlixWang commentedon Dec 18, 2016
very good
GuojunYin commentedon Feb 8, 2017
gooood
fenqiang4952 commentedon Feb 12, 2017
学到了!!
BadWaka commentedon Feb 15, 2017
厉害了!
webstermobile commentedon Feb 17, 2017
apply和call的区别这个里面
使用apply后 输出的type不正确啊
animal.apply(this,arguments)//type: wsscat
console.log(new cat('wsscat','cute'))//type应该是cute才对
zhenghuahou commentedon Feb 17, 2017
console.log(new cat('wsscat','cute'))//type应该是wsscat才对,因为调用的时候 animal.apply(this,arguments),apply传递了this,arguments值为'wsscat','cute'这个2个值
WuYifanX commentedon Mar 6, 2017
最后一种的话,animal执行了2次,所以可能性能有缺陷;
可以试试看Object.create()的方法,基本上还是比较主流的方法;
当然如果ES6的话会更清晰点,因为规范了继承的操作
lonelycheng commentedon Mar 22, 2017
good
Thinking80s commentedon Jun 13, 2017
让我想到这个题目jawil/blog#16
jiao852jiujiu commentedon Jun 17, 2017
不错不错~
Bshuai commentedon Jun 20, 2017
棒棒哒
sunnymask commentedon Jul 27, 2017
good
kokpapa commentedon Sep 5, 2017
学到了~
xialei520 commentedon Dec 1, 2017
you are a good boy!
ilovcoding commentedon Jan 14, 2018
很强
wangyusha commentedon Jan 15, 2018