Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Javascript中的apply和call继承 #56

Closed
Wscats opened this issue Sep 24, 2016 · 17 comments
Closed

Javascript中的apply和call继承 #56

Wscats opened this issue Sep 24, 2016 · 17 comments
Labels

Comments

@Wscats
Copy link
Owner

Wscats commented Sep 24, 2016

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

@Wscats Wscats changed the title Javascript中的apply和call Javascript中的apply和call继承 Sep 25, 2016
@Wscats Wscats added the notes label Sep 26, 2016
@Wbiokr
Copy link

Wbiokr commented Dec 9, 2016

handsome

@AlixWang
Copy link

very good

@GuojunYin
Copy link

gooood

@fenqiang4952
Copy link

学到了!!

@BadWaka
Copy link

BadWaka commented Feb 15, 2017

厉害了!

@webstermobile
Copy link

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

@zhenghuahou
Copy link

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

@WuYifanX
Copy link

WuYifanX commented Mar 6, 2017

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

@lonelycheng
Copy link

good

@Thinking80s
Copy link

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

@jiao852jiujiu
Copy link

不错不错~

@Bshuai
Copy link

Bshuai commented Jun 20, 2017

棒棒哒

@sunnymask
Copy link

good

@kokpapa
Copy link

kokpapa commented Sep 5, 2017

学到了~

@xialei520
Copy link

you are a good boy!

@ilovcoding
Copy link

很强

@wangyusha
Copy link

``

@Wscats Wscats closed this as completed Aug 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests