call,bind,apply的用法和区别

65 阅读2分钟

call

call会调用函数,并且会修改this的指向。
call的用法:

func.call(thisArg, arg1, arg2, ...);   
其中:
  func:要调用的函数。
  thisArg:在func函数体内使用的this值。
  arg1, arg2, ...:传递给func函数的参数列表。`

call的示例

  • call调用函数示例
function f1(){
   console.log(this);//正常情况下this指向window
}
f1.call();
//会输出window;
  • call改变了this的指向
function f1(){
    console.log(this.name)
 };
 let person={
    name:'夏明'
 };
 f1.call(person);
 //输出夏明;
  • call来传递参数
let person={
  name:'小明',
  sayName(age){
     console.log(`我的名字叫:${this.name},我今年${age}岁了`)
  }
};
let child={
  name:'小红'
}
person.sayName.call(child,18)
//输出:我的名字叫:小红,我今年18岁了

apply

会调用函数,参数的写法与call不一致,apply() 方法接受一个参数数组,而不是单个参数列表。
apply的用法:

func.apply(thisArg, [arg1, arg2, ...]);   
其中:
  func:要调用的函数。
  thisArg:在func函数体内使用的this值。
  arg1, arg2, ...:传递给func函数的参数数组。`

bind

bind:不会调用函数,会改变this的指向,会将函数进行返回;

let person={
  name:'小明',
  sayName(age){
     console.log(`我的名字叫:${this.name},我今年${age}岁了`)
  }
};
let child={
  name:'小红'
}
person.sayName.call(child,18)
//输出:我的名字叫:小红,我今年18岁了
等价于==================================
let person={
  name:'小明',
  sayName(age){
     console.log(`我的名字叫:${this.name},我今年${age}岁了`)
  }
};
let child={
  name:'小红'
}
let fn2=person.sayName.bind(child,18);
fn2();

在bpmn中,多次使用call来进行继承,例如在BaseModeler.js中文件夹中:

export default function BaseModeler(options) {
  //通过call来让baseModeler继承baseViewer的属性和方法
  //使BaseModeler可以使用baseViewer中的属性和方法。
  BaseViewer.call(this, options);
  //添加 导入解析完成事件的监听,在解析正常时处理和保存元素的id
  this.on('import.parse.complete', function(event) {
    if (!event.error) {
      this._collectIds(event.definitions, event.elementsById);
    }
  }, this);
  //添加 销毁事件的监听,在画布销毁时清空保存的元素ids
  this.on('diagram.destroy', function() {
    this.get('moddle').ids.clear();
  }, this);
}