JavaScript提供了apply和call两种调用方式来确定函数中的this的指向,在现实编码中,我确实

很少接触到这两个方法。但很无奈,很多面试题都要考这两种方法,我又没怎么用到,所以我们先来

闲聊下他们到底有什么用和到底怎么用。
         我们先来聊一下apply的用法吧,它是用来改变函数的指向的,说白了,就是指向了别的函数的作用域。

例如看一下下面这个例子。

var A={
name:"我是小A",
fun:function(){
console.log("大家好! "+this.name)
}
} var B = {
name:"我是小B"
} A.fun(); //大家好! 我是小A
A.fun.apply(B); //大家好! 我是小B

可以看出来,当我们使用了apply将引用指向了B时,A调用fun时并不是调用本身中的name  而是调用了B中的那么;

但如果我们在调用函数中并没用引用到this,那么是不是说apply就失去了意义?再来看一下下面的例子

var A={
name:"我是小A",
fun:function(num,money){
console.log("大家好! "+this.name+" 我有"+num+"张"+money+"块")
}
} var B = {
name:"我是小B"
}
var monies = [10,20]; A.fun.apply(B,monies); //大家好! 我是小B 我有10张20块

可以看出:apply中

  第一个参数为thisObject,调用时采用传入的thisObject代替函数体中this的指向

 第二个参数传入一个数组,函数会用数组的值取代“参数列表"。

这里聊一下monies,就要说到参数列表,当然我们会想到arguments,在这里插入聊一下arguments。网

上arguments是具有数组某些特性的‘类数组‘(伪数组);其实JS并没有重载函数的功能,但是auguments对象

能够模拟重载。每个函数都有一个Arguments对象实例arguments,它引用着函数的实参,可以用数组下

标的方式”[]“引用arguments的元素。arguments.length为函数实参个数。

function test() {
        var s = "";
        for (var i = 0; i < arguments.length; i++) {
            alert(arguments[i]);
            s += arguments[i] + ",";
        }
        return s;
    }
    test("name", "age")

输出

name,age

匿名函数中可以用arguements.callee引用函数自身。

例如 function(){

if(n>0) return 0;

else return n+arguments.callee(n+1);

}

回归正题,我们可以用arguments来代替函数中的参数

var A={
name:"我是小A",
fun:function(num,money){
console.log("大家好! "+this.name+" 我有"+arguments[0]+"张"+arguments[1]+"块")
}
} var B = {
name:"我是小B"
}
var monies = [10,20]; A.fun.apply(B,monies); //大家好! 我是小B 我有10张20块

这里又有一个问题,可不可以用Array.prototype.shift.apply(arguments)来代替arguments[0]呢?直接看代码

var A={
name:"我是小A",
fun:function(num,money){
console.log("大家好! "+this.name+" 我有"+Array.prototype.shift.apply(arguments)+"张"+arguments[1]+"块")
}
} var B = {
name:"我是小B"
}
var monies = [10,20]; A.fun.apply(B,monies); //大家好! 我是小B 我有10张undefined块

当我们使用Array.prototype.shift.apply(arguments)调用之后,arguments[0]就会被抹去,所以arguments[1]就会冒到arguments[0]上。

这可以看出arguments这个”伪数组“,除了不是”原型继承自’Array.prototype‘“职位,其他特征和数组是一样的。

最后,我们考虑一下,如果使用apply方法时,传入的第一个参数是null时,调用函数时,会发生什么情况,会不会报错呢!

不多说,直接上例子

var A={
name:"我是小A",
fun:function(num,money){
console.log("大家好! "+this.name+" 我有"+num+"张"+money+"块")
}
} var B = {
name:"我是小B"
}
var monies = [10,20];
name="我是小C" A.fun.apply(null,monies); //大家好! 我是小C 我有10张20块

可以看到  如果第一传入的参数是null的话,在函数提内的this会指向全局对象,在浏览器中就是window。

所以可以总结出两点:

1.如果函数中有明确使用this,那么this就会指向传入的第一个参数的作用域。

2.如果传入的第一参数为null时,this就会指向全局的作用域。

apply的另一种用法就是用于将数组分割为一个个元素。

例如想在数组中a[1,2,3,4]中寻找出最大的袁术出来。

如果直接调用Math.max(a);就会输出NaN,所以这时候我们可以这样

Math.max.apply(null,a);        //输出4

聊完了apply之后,我们再聊一下call就更简单了,其实他们的作用都是一样的。他们唯一的区别就是

apply和call在形式参数上的不同,apply只能传入两个参数且,第二个参数传入的是数组,而call在

第二参数开始可以接受任意个参数。大家看下面的例子就一目了然了

var A={
name:"我是小A",
fun:function(num,money){
console.log("大家好! "+this.name+" 我有"+num+"张"+money+"块")
}
} var B = {
name:"我是小B"
}
var monies = [10,20];
A.fun(monies[0],monies[1]); //大家好! 我是小A 我有10张20块
A.fun.apply(B,monies); //大家好! 我是小B 我有10张20块
A.fun.call(B,monies); //大家好! 我是小B 我有10,20张undefined块
A.fun.call(B,monies[1],monies[2]); //大家好! 我是小B 我有20张undefined块

闲聊js中的apply、call和arguments的更多相关文章

  1. 兄台息怒,关于arguments,您的想法和大神是一样一样的----闲聊JS中的apply和call

    JavaScript提供了apply和call两种调用方式来确定函数体中this的指向,表现出来的特征就是:对象可以'借用'其他对象的方法.之前的几篇博客回顾了一些Web控件的一些开发方法,我们聊了如 ...

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

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

  3. js中的apply和call API

    借用网上的一个例子: fun.call(this,arg1,arg2,arg3) fun.apply(this,arguments) this.fun(arg1,arg2,arg3) 三种方法等效. ...

  4. js中call apply方法的使用介绍

    js call call 方法 请参阅 应用于:Function 对象 要求 版本 5.5 调用一个对象的一个方法,以另一个对象替换当前对象. call([thisObj[,arg1[, arg2[, ...

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

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

  6. js中call(),apply(),以及prototype的含义

    最近段时间主要学习前端去了,然而所遇到的一些问题我觉得有必要去深究一下 prototype: 1 js中有三种表达方法 类方法,属性方法,原型方法 function People(name) { th ...

  7. Js中的apply和call

    1.call和apply都是为了改变某个函数运行时的上下文而存在的 2.也就是改变函数体内this的指向. 3.二者的作用完全一样,只是接受参数的方式不太一样. 4.call 需要把参数按顺序传递进去 ...

  8. js中的apply调用

    今天看了阮一锋老师的一篇文章,感觉很明了对闭包的理解,尤其是文章中的apply的介绍 apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象. ...

  9. js中函数的 this、arguments 、caller,call(),apply(),bind()

    在函数内部有两个特殊的对象,arguments 和 this,还有一个函数对象的属性caller. arguments对象 arguments是一个类似数组的对象,包含着传入函数的所有参数. func ...

随机推荐

  1. XGBoost算法--学习笔记

    学习背景 最近想要学习和实现一下XGBoost算法,原因是最近对项目有些想法,准备做个回归预测.作为当下比较火的回归预测算法,准备直接套用试试效果. 一.基础知识 (1)泰勒公式 泰勒公式是一个用函数 ...

  2. 第一章 C++概述

    第一节 C++语言的发展历史 略 第二节 C++语言的特点 1.C++是一种面向对象的程序设计语言,其中的新技术主要包括: 抽象数据类型 封装和信息隐蔽 以继承和派生方式实现程序的重用 以运算符重载和 ...

  3. 杨老师课堂_Java核心技术下之控制台模拟记事本案例

    预览效果图: 背景介绍: 编写一个模拟记事本的程序通过在控制台输入指令,实现在本地新建文件打开文件和修改文件等功能. 要求在程序中: 用户输入指令1代表"新建文件",此时可以从控制 ...

  4. Python并发编程之线程中的信息隔离(五)

    大家好,并发编程 进入第三篇. 上班第一天,大家应该比较忙吧.小明也是呢,所以今天的内容也很少.只要几分钟就能学完. 昨天我们说,线程与线程之间要通过消息通信来控制程序的执行. 讲完了消息通信,今天就 ...

  5. PHP访问数据库配置通用方法

    提取一种对数据库配置的通用方式 目的是通过通用类访问配置文件的方式,提供对数据库连接的动态获取和设置,使开发时和生产应用时都能够提供灵活的.简化的.解耦的操作方式.比如在配置文件中配置好两套数据库访问 ...

  6. 使用WampServer和DVWA在Windows10上搭建渗透测试环境

    前言: DVWA是一个具有脆弱性的Web测试应用,需要PHP和MySQL的环境支持.我们可以手动配置DVWA所需的运行环境,也可以使用WampServer进行搭建.WampServer是集成了Apac ...

  7. HoloLens开发手记-实现3D应用启动器

    一直有人问我,第三方应用在HoloLens上可以实现3D启动图标吗?就像微软官方出的应用那样.在不久之前,这个问题的答案还是No. 但是随着最新的Windows build 1803版本的发布,现在我 ...

  8. Spark2.1.0——Spark初体验

    学习一个工具的最好途径,就是使用它.这就好比<极品飞车>玩得好的同学,未必真的会开车,要学习车的驾驶技能,就必须用手触摸方向盘.用脚感受刹车与油门的力道.在IT领域,在深入了解一个系统的原 ...

  9. 如何把Python脚本导出为exe程序

    一.pyinstaller简介 pyinstaller将Python脚本打包成可执行程序,使在没有Python环境的机器上运行 最新版是pyinstaller 3.1.1.支持python2.7和py ...

  10. traceback模块

    traceback模块被用来跟踪异常返回信息 如下例所示: import traceback try: raise SyntaxError, "traceback test" ex ...