call是一个方法,是函数的方法
- function fun() {
- console.log('hello, guoyu')
- }
- // call 可以调用函数
- fun.call() // 输出 hello, guoyu
- function fun() {
- console.log(this.name)
- }
-
- let cat = {
- name: '喵喵'
- }
- // 上面两段代码,一点关系没有
- // 但我们可以通过一个call就可以建立起他们的关系
- // call可以调用函数,call可以改变函数中的this
- // 让函数中的this指向这个cat对象,本身函数中的this是指向window/global的
- fun.call(cat) // 喵喵
看下面例子
- let dog = {
- name: '旺财',
- sayName: function() {
- console.log(`我是${this.name}`)
- }
- }
-
- let cat = {
- name: '喵喵'
- }
- dog.sayName() // 我是旺财
- function fun() {
- console.log(this.name)
- }
-
- let dog = {
- name: '旺财',
- sayName: function() {
- console.log(`我是${this.name}`)
- }
- }
-
- let cat = {
- name: '喵喵'
- }
- // dog.sayName() // 我是旺财
- // 如果我想实现喵喵怎么办,可是cat没有sayName这个方法啊
- // 可以使用call借用,让猫去用狗的方法
- dog.sayName.call(cat) // 我是喵喵
上面都是简单的,如果再难点呢,比如,狗子里再加个eat方法,带有其他参数。
- let dog = {
- name: '旺财',
- sayName: function() {
- console.log(`我是${this.name}`)
- },
- eat: function(food1, food2) {
- console.log(`${this.name}喜欢吃${food1}、${food2}`)
- }
- }
-
- let cat = {
- name: '喵喵'
- }
-
- dog.eat('骨头', '屎') //我喜欢吃骨头、屎
- // 如果猫想用这个方法呢, call的用法
- dog.eat.call(cat, '鱼', '老鼠') // 我喜欢吃鱼、老鼠
apply和call的用法几乎是一样的,call第二个参数开始是参数列表,apply只是把这些参数整到一个数组中
- let dog = {
- name: '旺财',
- sayName: function() {
- console.log(`我是${this.name}`)
- },
- eat: function(food1, food2) {
- console.log(`${this.name}喜欢吃${food1}、${food2}`)
- }
- }
-
- let cat = {
- name: '喵喵'
- }
-
- dog.eat('骨头', '屎') //我喜欢吃骨头、屎
- // 如果猫想用这个方法呢, call的用法
- dog.eat.call(cat, '鱼', '老鼠') // 我喜欢吃鱼、老鼠
- // 如果是apply,参数改成[数组]方式即可
- dog.eat.apply(cat, ['鱼', '老鼠'])
bind和call有点不同,call会调用比如前面的eat函数,bind不会,bind返回的是一个函数,还需要再手动调用一次 。
- let dog = {
- name: '旺财',
- sayName: function() {
- console.log(`我是${this.name}`)
- },
- eat: function(food1, food2) {
- console.log(`${this.name}喜欢吃${food1}、${food2}`)
- }
- }
-
- let cat = {
- name: '喵喵'
- }
-
- dog.eat('骨头', '屎') //我喜欢吃骨头、屎
- // 如果猫想用这个方法呢, call的用法
- dog.eat.call(cat, '鱼', '老鼠') // 我喜欢吃鱼、老鼠
- // 如果是apply,参数改成[数组]方式即可
- dog.eat.apply(cat, ['鱼', '老鼠'])
-
- const fun = dog.eat.bind(cat, '鱼', '老鼠')
- fun()
实现继承
- // 继承:子类可以使用父类的方法
- function Animal() {
- this.eat = function() {
- console.log('吃东西')
- }
- }
-
- let ani = new Animal()
- ani.eat() // 吃东西
-
- // 下面的代码和上面毫无关系,并没有形成继承关系
- function Cat () { }
- let cat = new Cat()
- cat.eat() // 肯定会报错
看看使用call方式实现继承
- // 继承:子类可以使用父类的方法
- function Animal() {
- // 自然而然这里的this也是指向小cat了----2
- // 那么this.eat 就是小cat.eat,那么小cat就有这个eat方法了
- this.eat = function() {
- console.log('吃东西')
- }
- }
-
- let ani = new Animal()
- ani.eat() // 吃东西
-
- // 如何才能让Cat继承Animal呢
- function Cat () {
- // Animal 是构造函数,它也是函数,就可以直接调call,就把this传进去
- // 已经实现了继承
- // 这里的this指向小cat----1
- Animal.call(this)
- }
- let cat = new Cat()
- cat.eat()
而且call还可以实现多重继承
- // 继承:子类可以使用父类的方法
- function Animal() {
- // 自然而然这里的this也是指向小cat了----2
- // 那么this.eat 就是小cat.eat,那么小cat就有这个eat方法了
- this.eat = function() {
- console.log('吃东西')
- }
- }
-
- function Bird() {
- this.fly = function() {
- console.log('I can fly')
- }
- }
-
- let ani = new Animal()
-
- // 如何才能让Cat继承Animal呢
- function Cat () {
- // Animal 是构造函数,它也是函数,就可以直接调call,就把this传进去
- // 已经实现了继承
- // 这里的this指向小cat----1
- Animal.call(this)
- Bird.call(this)
- }
- let cat = new Cat()
- cat.eat()
- cat.fly()