介绍

在js中,每个函数的原型都指向Function.prototype对象(js基于原型链的继承)。因此,每个函数都会有apply,call,和bind方法,这些方法继承于Function。

它们的作用是一样的,都是用来改变函数中this的指向。

使用方法

apply的用法可以表示如下:

A.apply(B, [x, y, z]);

此方法可以改变函数A的this指向,使之指向函数B。第二个参数传的是一个函数参数列表的数组形式。

call的用法和apply差不多,就只有传参方式不一样。类似于这样 :

A.apply(B, x, y, z)

可以把多个参数分开来传,而不是像apply一样,需要把所有参数放到一个数组里边传进来。

bind的传参方式和call一样,只不过它的不同之处是,apply和call方法调用之后会立即执行,而bind方法调用之后会返回一个新的函数,它并不会立即执行,需要我们手动执行。

举例

var name = "佚名";
var age = 20;
//global.name
//global.age var p1 = {
name: "张三",
age: 12,
func: function(){
console.log(`姓名:${this.name},年龄:${this.age}`)
}
} var p2 = {
name: "李四",
age: 15
} p1.func(); //姓名:张三,年龄:12
p1.func.call(); //姓名:佚名,年龄:20
p1.func.apply(p2); //姓名:李四,年龄:15
p1.func.bind(p2)(); //姓名:李四,年龄:15
  1. 当直接调用p1.func方法时,this指向的是当前p1这个对象,因此name和age都是它本身对象的属性值。
  2. 当使用call方法,传入的第一个参数为空时,在浏览器环境下,this指向window;在node环境下,this指向global。读者可自行把name和age改为global.name和global.age验证一下。
  3. 使用apply方法时,把p2传进去,相当于把函数的this指向p2对象,因此,此时打印出来的属性都是p2对象的属性
  4. 使用bind方法时,会生成一个新的函数对象,因此需要手动执行一下这个函数(即在函数末尾加个括号执行)。

总结

例子讲完,call,apply和bind的区别就已经很清楚了。它们就是为了改变this的上下文而存在。因此,有时候你会看到这样的用法。为了不改变this的指向,通常会在函数后边加上bind(this),如下

function f(){}.bind(this)

这样的话,就不会出现莫名其妙的this指向问题了。明明我想在函数里边调用此函数所属对象的某个属性时,为什么用this却访问不到呢。(写js的新手肯定会遇到过这种问题)

其实,从es6开始,已经支持箭头函数了,我建议大家用箭头函数,就不会出现this指向的问题了。

另外,使用call,apply还可以实现函数的继承。在es6的class没有出现之前,就需要借助它们来实现继承关系。

js中call、apply和bind到底有什么区别?的更多相关文章

  1. js中call、apply、bind到底有什么区别?bind返回的方法还能修改this指向吗?

     壹 ❀ 引 同事最近在看angularjs源码,被源码中各种bind,apply弄的晕头转向:于是他问我,你知道apply,call与bind的区别吗?我说apply与call是函数应用,指定thi ...

  2. JS中的apply,call,bind深入理解

    在Javascript中,Function是一种对象.Function对象中的this指向决定于函数被调用的方式.使用apply,call 与 bind 均可以改变函数对象中this的指向,在说区别之 ...

  3. js的call,apply,bind的使用与区别

    在原生js中会有三个很常见的函数,call,apply,bind 他们的作用就是改变当前函数的this指针, 但是细微来说他们还是有不同的. 1)call,apply都是执行某一函数,发现this有变 ...

  4. js中的apply与call的用法与区别

    call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向.call 和 apply二者的作用完全一样,只是接受参数的 ...

  5. 深入理解js中的apply、call、bind

    概述 js中的apply,call都是为了改变某个函数运行时的上下文环境而存在的,即改变函数内部的this指向. apply() apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作 ...

  6. js 中call,apply,bind的区别

    call.apply.bind方法的共同点与区别: apply.call.bind 三者都是用来改变函数的this对象的指向: apply.call.bind 三者都可以利用后续参数传参: bind ...

  7. java中的NIO和IO到底是什么区别?20个问题告诉你答案

    摘要:NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多. 本文分享自华为云社区<jav ...

  8. js中的text(),html() ,val()的区别

    js中的text(),html() ,val()的区别 text(),html() ,val()三个方法用于html元素的存值和取值,但是他们各有特点,text()用于html元素文本内容的存取,ht ...

  9. 浅谈JS中的!=、== 、!==、===的用法和区别 JS中Null与Undefined的区别 读取XML文件 获取路径的方式 C#中Cookie,Session,Application的用法与区别? c#反射 抽象工厂

    浅谈JS中的!=.== .!==.===的用法和区别   var num = 1;     var str = '1';     var test = 1;     test == num  //tr ...

随机推荐

  1. Kubernetes的Service运行原理

    一.为什么Servcie能定位到Pod 因为Pod的IP是不固定的,所以Kubernetes需要Service,除此之外它还可以在多个Pod间负载均衡 Service的访问入口,其实是宿主机的kube ...

  2. std::is_same

    两个一样的类型会返回true bool isInt = std::is_same<int, int>::value; //为true std::cout << std::is_ ...

  3. 小白学 Python(8):基础流程控制(下)

    人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...

  4. vue 列表的排序过渡 shuffle遇到的问题

    内部的实现,Vue 使用了一个叫 FLIP 简单的动画队列使用 transforms 将元素从之前的位置平滑过渡新的位置 需要注意的是使用 FLIP 过渡的元素不能设置为 display: inlin ...

  5. accesskey附上一些实例

    HTML accesskey属性与web自定义键盘快捷访问 本文地址:http://www.zhangxinxu.com/wordpress/?p=6142 可能很多小伙伴都不知道,我们只要在HTML ...

  6. text文本样式二

    text-transform样式用于将元素的字母全都变成大小 letter-spacing设置字符之间的间距 <html> <head> <style type=&quo ...

  7. NOIP201605玩具谜题-解题报告

    NOIP201605玩具谜题-解题报告                                                                         2019-11- ...

  8. 在虚拟机上的关于NFS网络文件系统

    小知识: NFS(Network Files System)即网络文件系统,NFS文件系统协议允许网络中的主机通过TCP/IP协议进行资源共享,NFS客户端可以像使用本地资源一样读写远端NFS服务端的 ...

  9. emacs考场短配置

    (set-background-color "gray15") (set-foreground-color "gray") ;;设置颜色 (global-set ...

  10. Django学习day3——Django的简单使用

    开始一个项目 切换到django的虚拟环境中 执行: django-admin startproject mysite 创建第一个django项目mysite django生成的目录如下: E:. └ ...