Skip to content

Javascript中的apply和call继承 #56

Closed
@Wscats

Description

@Wscats
Owner

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())

qq 20160924165406

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())

qq20160925-0

只要在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

qq20160925-1

Activity

changed the title [-]Javascript中的apply和call[/-] [+]Javascript中的apply和call继承[/+] on Sep 25, 2016
Wbiokr

Wbiokr commented on Dec 9, 2016

@Wbiokr

handsome

AlixWang

AlixWang commented on Dec 18, 2016

@AlixWang

very good

GuojunYin

GuojunYin commented on Feb 8, 2017

@GuojunYin

gooood

fenqiang4952

fenqiang4952 commented on Feb 12, 2017

@fenqiang4952

学到了!!

BadWaka

BadWaka commented on Feb 15, 2017

@BadWaka

厉害了!

webstermobile

webstermobile commented on Feb 17, 2017

@webstermobile

apply和call的区别这个里面
使用apply后 输出的type不正确啊
animal.apply(this,arguments)//type: wsscat
console.log(new cat('wsscat','cute'))//type应该是cute才对

zhenghuahou

zhenghuahou commented on Feb 17, 2017

@zhenghuahou

console.log(new cat('wsscat','cute'))//type应该是wsscat才对,因为调用的时候 animal.apply(this,arguments),apply传递了this,arguments值为'wsscat','cute'这个2个值

WuYifanX

WuYifanX commented on Mar 6, 2017

@WuYifanX

最后一种的话,animal执行了2次,所以可能性能有缺陷;
可以试试看Object.create()的方法,基本上还是比较主流的方法;
当然如果ES6的话会更清晰点,因为规范了继承的操作

lonelycheng

lonelycheng commented on Mar 22, 2017

@lonelycheng

good

Thinking80s

Thinking80s commented on Jun 13, 2017

@Thinking80s

让我想到这个题目jawil/blog#16

jiao852jiujiu

jiao852jiujiu commented on Jun 17, 2017

@jiao852jiujiu

不错不错~

Bshuai

Bshuai commented on Jun 20, 2017

@Bshuai

棒棒哒

sunnymask

sunnymask commented on Jul 27, 2017

@sunnymask

good

kokpapa

kokpapa commented on Sep 5, 2017

@kokpapa

学到了~

xialei520

xialei520 commented on Dec 1, 2017

@xialei520

you are a good boy!

ilovcoding

ilovcoding commented on Jan 14, 2018

@ilovcoding

很强

wangyusha

wangyusha commented on Jan 15, 2018

@wangyusha

``

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Thinking80s@zhenghuahou@AlixWang@fenqiang4952@lonelycheng

        Issue actions

          Javascript中的apply和call继承 · Issue #56 · Wscats/articles