1. 每个函数都包含两个非继承而来的方法:call()方法和apply()方法。

2. 相同点:这两个方法的作用是一样的。

都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域。

一般来说,this总是指向调用某个方法的对象,但是使用call()和apply()方法时,就会改变this的指向。

不同点:接收参数的方式不同。

  • apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。

语法:apply([thisObj [,argArray] ]);,调用一个对象的一个方法,2另一个对象替换当前对象。

说明:如果argArray不是一个有效数组或不是arguments对象,那么将导致一个
TypeError,如果没有提供argArray和thisObj任何一个参数,那么Global对象将用作thisObj。

  • call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。

语法:call([thisObject[,arg1 [,arg2 [,...,argn]]]]);,应用某一对象的一个方法,用另一个对象替换当前对象。

说明: call方法可以用来代替另一个对象调用一个方法,call方法可以将一个函数的对象上下文从初始的上下文改变为thisObj指定的新对象,如果没有提供thisObj参数,那么Global对象被用于thisObj。

var a ={name : "Cherry",fn : function (a,b) {console.log( a + b)}}var b = a.fn;b.apply(a,[1,2])     // 3

var b = a.fn;b.call(a,1,2)       // 3

    var b = a.fn;b.bind(a,1,2)()

函数调用的方法一共有 4 种

  1. 作为一个函数调用
  2. 函数作为方法调用
  3. 使用构造函数调用函数
  4. 作为函数方法调用函数(call、apply)

作为一个函数调用

比如上面的 例 1: 例 1:

var name = "windowsName";function a() {var name = "Cherry";console.log(this.name);          // windowsNameconsole.log("inner:" + this);    // inner: Window}a();console.log("outer:" + this)         // outer: Window

这样一个最简单的函数,不属于任何一个对象,就是一个函数,这样的情况在 JavaScript 的在浏览器中的非严格模式默认是属于全局对象 window 的,在严格模式,就是 undefined。

但这是一个全局的函数,很容易产生命名冲突,所以不建议这样使用。

函数作为方法调用

所以说更多的情况是将函数作为对象的方法使用。比如例 2: 例 2:

var name = "windowsName";var a = {name: "Cherry",fn : function () {console.log(this.name);      // Cherry}}a.fn();

这里定义一个对象 a,对象 a 有一个属性(name)和一个方法(fn)。

然后对象 a 通过 . 方法调用了其中的 fn 方法。

然后我们一直记住的那句话“this 永远指向最后调用它的那个对象”,所以在 fn 中的 this 就是指向 a 的。

使用构造函数调用函数

如果函数调用前使用了 new 关键字, 则是调用了构造函数。 这看起来就像创建了新的函数,但实际上 JavaScript 函数是重新创建的对象:

// 构造函数:
function myFunction(arg1, arg2) {this.firstName = arg1;this.lastName  = arg2;
}// This    creates a new object
var a = new myFunction("Li","Cherry");
a.lastName;                             // 返回 "Cherry"

这就有要说另一个面试经典问题:new 的过程了,(ಥ_ಥ) 这里就简单的来看一下 new 的过程吧: 伪代码表示:

var a = new myFunction("Li","Cherry");new myFunction{var obj = {};obj.__proto__ = myFunction.prototype;var result = myFunction.call(obj,"Li","Cherry");return typeof result === 'obj'? result : obj;
}

  1. 创建一个空对象 obj;
  2. 将新创建的空对象的隐式原型指向其构造函数的显示原型。
  3. 使用 call 改变 this 的指向
  4. 如果无返回值或者返回一个非对象值,则将 obj 返回作为新对象;如果返回值是一个新对象的话那么直接直接返回该对象。

所以我们可以看到,在 new 的过程中,我们是使用 call 改变了 this 的指向。

作为函数方法调用函数

在 JavaScript 中, 函数是对象。
JavaScript 函数有它的属性和方法。 call() 和 apply() 是预定义的函数方法。 两个方法可用于调用函数,两个方法的第一个参数必须是对象本身
在 JavaScript 严格模式(strict mode)下, 在调用函数时第一个参数会成为 this 的值, 即使该参数不是一个对象。 在 JavaScript 非严格模式(non-strict mode)下, 如果第一个参数的值是 null 或 undefined, 它将使用全局对象替代。

这个时候我们再来看例 6: 例 6:

var name = "windowsName";function fn() {var name = 'Cherry';innerFunction();function innerFunction() {console.log(this.name);      // windowsName}}fn()

这里的 innerFunction() 的调用是不是属于第一种调用方式:作为一个函数调用(它就是作为一个函数调用的,没有挂载在任何对象上,所以对于没有挂载在任何对象上的函数,在非严格模式下this 就是指向 window 的)

然后再看一下 例 7: 例 7:

var name = "windowsName";var a = {name : "Cherry",func1: function () {console.log(this.name)     },func2: function () {setTimeout(  function () {this.func1()},100 );}};a.func2()     // this.func1 is not a function

这个简单一点的理解可以理解为“匿名函数的 this 永远指向 window”,你可以这样想,还是那句话this 永远指向最后调用它的那个对象,那么我们就来找最后调用匿名函数的对象,这就很尴尬了,因为匿名函数名字啊,笑哭,所以我们是没有办法被其他对象调用匿名函数的。所以说 匿名函数的 this 永远指向 window。

如果这个时候你要问,那匿名函数都是怎么定义的,首先,我们通常写的匿名函数都是自执行的,就是在匿名函数后面加 () 让其自执行。其次就是虽然匿名函数不能被其他对象调用,但是可以被其他函数调用啊,比如例 7 中的 setTimeout。

转载于:https://www.cnblogs.com/SZLLQ2000/p/8926204.html

函数调用的方法一共有 4 种,call,apply,bind相关推荐

  1. 整理*软件测试的方法一共有几种

    软件测试的方法一共有几种 参考资料:百度百科-软件测试 从是否关心内部结构来看 白盒测试:又称为结构测试或逻辑驱动测试,是一种按照程序内部逻辑结构和编码结构,设计测试数据并完成测试的一种测试方法. 黑 ...

  2. 软件测试的方法一共有几种

    1.按是否查看程序内部结构分为:(1)黑盒测试(black-box testing):只关心输入和输出的结果(2)白盒测试(white-box testing):去研究里面的源代码和程序结构2.按是否 ...

  3. js中的4种函数调用模式:函数调用、方法调用、构造器调用、间接调用

    全栈工程师开发手册 (作者:栾鹏) js系列教程4-函数.函数参数教程全解 js中的4种函数调用模式 javascript一共有4种调用模式:函数调用模式.方法调用模式.构造器调用模式和间接调用模式. ...

  4. 【转】Java中字符串中子串的查找共有四种方法(indexof())

    原文网址:http://wfly2004.blog.163.com/blog/static/1176427201032692927349/ Java中字符串中子串的查找共有四种方法,如下: 1.int ...

  5. Java中字符串中子串的查找共有四种方法(indexof())

    2019独角兽企业重金招聘Python工程师标准>>> public class FirstDemo { /** *API中String的常用方法 */ // 查找指定字符串是否存在 ...

  6. java indexof 子字符串_Java中字符串中子串的查找共有四种方法(indexof())

    Java中字符串中子串的查找共有四种方法(indexof()) Java中字符串中子串的查找共有四种方法,如下: 1.int indexOf(String str) :返回第一次出现的指定子字符串在此 ...

  7. 人民币兑换c语言程序,C语言换零钱:把一元人民币兑换成硬币,共有多少种兑换方法?...

    C语言换零钱:把一元人民币兑换成硬币,共有多少种兑换方法? 答案:6  信息版本:手机版 解决时间 2019-10-07 06:29 已解决 2019-10-06 08:05 以下是我敲的代码,经Mi ...

  8. /* * 编程题第四题(20分): 用1元5角钱人名币兑换5分、2分和1分的硬币(每一种都要有)共一百枚,问共有几种兑换方案?并输出每种方案。 */

    题目: /* 编程题第四题(20分): 用1元5角钱人名币兑换5分.2分和1分的硬币(每一种都要有)共一百枚,问共有几种兑换方案?并输出每种方案. */ 我使用java做的 public class ...

  9. 工厂方法模式的一种特例——简单工厂模式

    工厂模式可以分为三类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory) 这三种模式从上到下逐步 ...

最新文章

  1. php simpletest 测试数据库,在PHP中使用SimpleTest进行单元测试
  2. SSM格式化导出报表时间的格式
  3. spring Boot Actuator使用
  4. msconfig深解
  5. [leetcode]693. 交替位二进制数
  6. 2021-01-08 PMP 群内练习题 - 光环
  7. 解决smtp出现(500, b'Error: bad syntax')
  8. matlab单边指数信号傅里叶变换,第三章3典型信号傅里叶变换性质1讲解.ppt
  9. Linux基础命令之好用的组合
  10. 如何优雅高效地使用Python——这些Python技巧你必须学会!
  11. 收集的一些有意思的网站(持续更新)
  12. 正则表达式-re.error: unbalanced parenthesis at position 7
  13. python实现工作流审批_工作流和审批流
  14. 从五个方面来讲一下平面设计颜色搭配知识——黎乙丙
  15. 告别手摇织布机的AI时代
  16. 响应式网站设计(2)-关于网站制作你不知道的那些文件儿
  17. Unity自定义材质自发光烘焙设置工具
  18. 美团 YOLOv6 ORT/MNN/TNN/NCNN C++推理部署
  19. 度过有意义的生命--俞敏洪2009-06-02同济大学的演讲
  20. 双十一预售单品榜单出炉,极米H3S成投影品类爆款位列智能投影Top 1

热门文章

  1. 李俊君信电保研面试发言稿及其分析总结
  2. 【SQLServer】【恢复挂起的解决方案】附加文件时候的提示“无法重新生成日志,原因是数据库关闭时存在打开的事务/用户,该数据库没有检查点或者该数据库是只读的。 ”【数据库恢复】...
  3. 关于log4net使用中遇到的错误
  4. WCF部署:让IIS有权限访问证书文件
  5. Sql Server使用链接服务器远程取数据!
  6. 3.1 数据链路层功能概述
  7. matlab多维数组、结构体数组
  8. Round Robin 算法
  9. PCIe配置空间和PCI设备中的寄存器
  10. echarts空数据如何设置_拼多多分时折扣如何设置优化?分时数据怎么看?