美文网首页
call apply bind.md

call apply bind.md

作者: 素瑾儿 | 来源:发表于2023-04-23 17:31 被阅读0次

> call、apply、bind的作用是改变函数运行时的this指向

## 关于this对象

this对象在运行时基于函数的执行环境绑定的,在非严格模式的全局环境中,this指向window,而当函数被作为某个对象的方法调用时,this等于那个对象,不过,匿名函数的执行环境具有全局性,因此其this对象通常指向window(严格模式下,在全局环境中,this指向undefined)。

## 异同

- call, apply, bind 第一个参数是要绑定给this的值,区别是传递的参数不同,call, bind后面传入的是一个参数列表,apply后面传入的是一个包含多个参数的数组 在非严格模式中当第一个参数为null,undefined的时候,默认指向window,严格模式下,默认指向undefined。

```js

  var person = {

    name: "tjj",

    age: 23

  };

  function say(job, hobby){

    console.log(this.name + ":" + this.age+ ":" + job + ":" + hobby);

  }

  say.call(person, "Teacher", "Swimming"); // tjj:25:Teacher:Swimming

  say.apply(person, ["Teacher", "Swimming"]); // tjj:25:Teacher:Swimming

  var sayPerson = say.bind(person, "Teacher", "Swimming");

  sayPerson(); // tjj:25:Teacher:Swimming

```

- bind方法与call/apply 最大的不同是前者返回一个绑定上下文的函数,后者则是直接执行了函数

```js

  var value = 2;

  var foo = {

      value: 1

  };

  function bar(name, age) {

      return {

        value: this.value,

        name: name,

        age: age

      }

  };

  bar.call(foo, "Jack", 20); // 直接执行了函数

  // {value: 1, name: "Jack", age: 20}

  var bindFoo1 = bar.bind(foo, "Jack", 20); // 返回一个函数

  bindFoo1();

  // {value: 1, name: "Jack", age: 20}

  var bindFoo2 = bar.bind(foo, "Jack"); // 返回一个函数,并且预设了第一个参数

  bindFoo2(20);

  // {value: 1, name: "Jack", age: 20}

  bindFoo2(40);

  // {value: 1, name: "Jack", age: 40}

```

## call的实现

## 使用场景

```js

  var nickname = "Kitty";

  function Person(name){

      this.nickname = name;

      this.distractedGreeting = function() {

          setTimeout(function(){

              console.log("Hello, my name is " + this.nickname);

          }, 500);

      }

  }

  var person = new Person('tjj');

  person.distractedGreeting();

  //Hello, my name is Kitty

```

这里输出的nickname是全局的,并不是我们创建的person 时传入的参数,因为setTimeout在全局环境中执行,所以this指向的是window(把this换成异步回调也是一样的,比如接口请求回调)

解决办法:

1. 缓存this 值

```js

  var nickname = "Kitty";

  function Person(name){

      this.nickname = name;

      this.distractedGreeting = function() {

      var self = this;

          setTimeout(function(){

              console.log("Hello, my name is " + self.nickname);

          }, 500);

      }

  }

  var person = new Person('tjj');

  person.distractedGreeting();

  // Hello, my name is tjj

```

2. 使用 bind

```js

  var nickname = "Kitty";

  function Person(name){

      this.nickname = name;

      this.distractedGreeting = function() {

          setTimeout(function(){

              console.log("Hello, my name is " + this.nickname);

          }.bind(this), 500);

      }

  }

  var person = new Person('tjj');

  person.distractedGreeting();

  // Hello, my name is tjj

```

- 其他用法:

```js

  Object.prototype.toString.call(obj) === '[object Array]'  // 判断数据类型

  Array.prototype.slice.call(arguments)  // 类数组转化为数组

  Math.max.apply(null, [1, 2, 3]) // 获取数据最大值

  Math.min.apply(null, [1, 2, 3]) // 获取数据最小值

  [].push.apply([1, 2], [3, 4]) // 数组追加

  // 继承

  function Person(name,age){

    // 这里的this都指向实例

    this.name = name

    this.age = age

    this.sayAge = function(){

        console.log(this.age)

    }

  }

  function Female(){

      Person.apply(this, arguments)//将父元素所有方法在这里执行一遍就继承了

  }

  var dot = new Female('Dot', 2)

```

相关文章

网友评论

      本文标题:call apply bind.md

      本文链接:https://www.haomeiwen.com/subject/dlknzhtx.html