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); // windowsName console.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。

函数调用的方法一共有 4 种,call,apply,bind的更多相关文章

  1. HTTP的请求方法一共有9种,有OPTIONS, HEAD, GET, POST等等(消息头有图,十分清楚)

    请求方法:指定了客户端想对指定的资源/服务器作何种操作 下面我们介绍HTTP/1.1中可用的请求方法: [GET:获取资源]     GET方法用来请求已被URI识别的资源.指定的资源经服务器端解析后 ...

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

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

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

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

  4. [Effective JavaScript 笔记]第18条:理解函数调用、方法调用及构造函数调用之间的不同

    面向对象编程中,函数.方法.类的构造函数是三种不同的概念. JS中,它们只是单个构造对象的三种不同的使用模式. 三种不同的使用模式 函数调用 function hello(username){ ret ...

  5. 第164天:js方法调用的四种模式

    js方法调用的四种模式 1.方法调用模式 function Persion() { var name1 = "itcast", age1 = 19, show1 = functio ...

  6. main方法中声明8种基本数据类型的变量并赋值

    main方法中声明8种基本数据类型的变量并赋值  char→  int→ long→ float→ double byte→ short→ 

  7. 【组合数学+动态规划】在如下8*6的矩阵中,请计算从A移动到B一共有____种走法。要求每次只能向上或向右移动一格,并且不能经过P。

    在如下8*6的矩阵中,请计算从A移动到B一共有__种走法.要求每次只能向上或向右移动一格,并且不能经过P. A:456 B:492 C:568 D:626 E:680 F:702 解析: 8*6的矩阵 ...

  8. 十二、C# 委托与Lambda表达式(匿名方法的另一种写法)

    委托与Lambda表达式   1.委托概述 2.匿名方法 3.语句Lambda 4.表达式Lambda 5.表达式树   一.委托概述 相当于C++当中的方法指针,在C#中使用delegate 委托来 ...

  9. Android开发之去掉标题栏的三种方法,推荐第三种

    Android:去掉标题栏的三种方法和全屏的三种方法 第一种:一般入门的时候常常使用的一种方法 onCreate函数中增加下面代码: requestWindowFeature(Window.FEATU ...

随机推荐

  1. curl 伪装来路(referer)

    curl -e http://vip.hihi.com http://test.image.ok.com/parcel/201704/1491035345125_971038.jpg 1xx.8x.3 ...

  2. 【XMPP】基于XMPP的即时通讯解决方案

    什么是XMPP 介绍XMPP之前,先来看看GTalk. GTalk是Google推出的IM(Instant Messaging,即时通讯)软件,类似于QQ和MSN. 从技术角度来说,GTalk与QQ和 ...

  3. 硬件信息 dmidecode dmesg lsdev lshw haparm lsusb

    dmidecode 显示从BIOS中获取的硬件信息 dmesg 检测到的硬件和启动的消息 lsdev 显示关于安装硬件信息 cat /proc/devices 显示当前核心配置的设备 haparm - ...

  4. 【12月21日】A股滚动市盈率PE历史新低排名

    2010年01月01日 到 2018年12月21日 之间,滚动市盈率历史新低排名.上市三年以上的公司,2018年12月21日市盈率在300以下的公司. 1 - 厦门象屿(SH600057) - 历史新 ...

  5. [Tensorflow] RNN - 03. MultiRNNCell for Digit Prediction

    Ref: http://blog.csdn.net/u014595019/article/details/52759104 Time: 2min Successfully downloaded tra ...

  6. ef 某些字段更新 某些字段不更新

    不更新 _pocDbContext.Entry<UploadFileActiveTask>(activeTask).Property("id").IsModified ...

  7. SpringBoot(十六)-- 使用外部容器运行springBoot项目

    spring-boot项目需要部署在外部容器中的时候,spring-boot导出的war包无法再外部容器(tomcat)中运行或运行报错. 为了解决这个问题,需要移除springBoot自带的tomc ...

  8. 精心收集的 48 个 JavaScript 代码片段,仅需 30 秒就可理解

    原文:Chalarangelo  译文:IT168 https://github.com/Chalarangelo/30-seconds-of-code#anagrams-of-string-with ...

  9. 不用軟體解PPT密碼

    解PPT密碼的軟體很多,最好用的是advanced office password recovery pro,論壇裡有,不多說了~ 但是軟體有時候在解PPT密碼時多顯無力,現介紹不用軟體就能解pptx ...

  10. vagrant up connection time out

    vagrant up connection time out 在一台重装系统的机子上装vagrant后 vagrant up 无法启系统 D:\work\vagrant>vagrant up B ...