函数中的apply,call入门介绍

###函数中的apply,call入门


  牵扯到apply,call就要先说一下它们和函数的渊源

Javascript函数既是也是对象

  它和其它的javascript对象没有什么区别。并且每个函数都包含两个非继承而来的方法 apply()和call(),这两个方法都可以间接的调用函数

例如:

function f() {console.log(1);
}
f.call(); //1
f.apply(); //1
复制代码

  并且这两个方法都允许显示的指定函数调用后的this值。   关于this值,由于this值的是在进入执行上下文阶段被确认的,所以this的值让人琢磨不透。但是我们可以通过apply()和call() 在函数调用时显示指定所需的this值。


###那么apply和call方法到底是用来做什么的呢?

  任何函数在调用时都可以被指定this值,作为this指向的对象的方法来调用。

那就意味这任何函数可以被任何对象调用,这才是apply和call的方法的最终目的。

  让我们来一个使用例子来理解

function Animal() {};
Animal.prototype = {constructor: Animal,other: function() {console.log('这是一只' + this.name);}
}
var animal = new Animal();
//定义一个对象
var dog = {name: '狗'
};//我的dog对象想使用Animal函数的other方法怎么办,使用call或apply
animal.other.call(dog);
animal.other.apply(dog);
复制代码

  在上面,我们将animal.other(思考一下它是什么,是的,它本质上也是一个函数)作为dog对象的方法调用。接下来,我们运用的实际一些.

//设置一个类数组对象
var arrLike = {0: '我是apply',1: '我是call',length: 2
}//将Arrar的slice函数的this显式指向arrLike,并将0作为参数传入slice函数
var newArr = Array.prototype.slice.call(arrLike, 0);
//等价于 
arrLike.slice(0);
console.log(newArr);复制代码

  对于apply()和cal()所有传入它们的第一个实参都会变为this的值,哪怕传入的实参是原始值,null,undefined。而如果传入的第一个实参是undefined和null 在ES3和非严格模式下会被全局对象替换掉,而其它的原始值则会被相应的包装对象所替代

  用通俗一点的话来说,Js根本不在乎apply/call 的第一个参数是什么,函数仍然会被调用,只不过调用会不会报错是另一码事.

var str = '我是一个函数';
//将字符串传入,但是String对象无法调用slice属性 报错
Array.prototype.pop.call(str);
复制代码

  为了能对这两个方法记忆深刻以及何时用这两个方法,列出一些常用的用法

  首先,就现在来说,这两种方法的性能差异几乎忽略不记,所以他们之间如何使用呢?

  apply()方法适用于传入第二个参数是有序且参数不定的就使用apply方法,比如函数的arguments这个类数组对象就很适合作为参数传递。

function A(a, b, c) {console.log(a, b, c);
}var fn = (function(func, b, c) {var args = arguments;return () => {func.apply(null, args);}
}(A, 66, 99));fn();
复制代码

再比如说给数组追加元素

var arr1 = [1, 2, 3];
var arr2 = [66, 99, 131];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1);
复制代码

同样将arr2数组作为参数传递。


而对于无序,相互之间没有什么关联的参数,就使用call()

获取数组的最大值和最小值

var arr = [0, 1, 2, 3, 4];//获取最大数
var max1 = Math.max.apply(Math, arr),max2 = Math.max.call(Math, 0, 1, 2, 3, 4),//获取最小数min1 = Math.min.apply(Math, arr),min2 = Math.min.call(Math, 0, 1, 2, 3, 4);
console.log(max1, max2, min1, min2);复制代码

arr本身是没有Math方法的,但是我们可以用call或者apply使用其方法


判断对象的具体类型

//验证对象的具体类型
var arr = [];
var type = Object.prototype.toString.call(arr);
console.log(type);// [object Array]复制代码

在使用typeof时得到的结果都是Object,无法判断具体是哪一种类型。于是可以用 Object.prototype.toString.call()来获得具体类型。当然,前提是toSting()方法没有被重写过


将类数组对象转为真正的数组,通常我们使用Array.prototype.slice.call() 来转换

var arrLike = {length: 3,0: '值1',1: '值2',2: '值3'
}
var newArr = [].__proto__.slice.call(arrLike);
var type = Object.prototype.toString.call(newArr);
console.log(newArr, type); //[ '值1', '值2', '值3' ] '[object Array]'
复制代码

当然,splice,concat也可以将类数组对象转数组.

这里普及一下类数组对象。 通过索引访问元素,并且拥有length属性 也就是说,需要满足两个条件,1.使用序号定义属性,2.拥有length属性,属性值为元素个数 在使用序号定义属性时,建议从0开始按顺序定义属性。否则会出现数组元素为empty的情况


var arrLike = {length: 3,0: '值1',1: '值2',3: '值3'
}
var newArr = [].__proto__.slice.call(arrLike);
var type = Object.prototype.toString.call(newArr);
console.log(newArr, type); //[ '值1', '值2', empty] [object Array]
复制代码

转载于:https://juejin.im/post/5c9e2679f265da3097285f37

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/449056.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

H.264入门级概念之I、B、P帧

MPEG压缩中的 I、B、P帧 首先,MPEG-1压缩的基本思想:帧内压缩和帧间压缩。 其次,时间相关性的统计分析:统计的结果表明,在间隔1~2帧的图像中,各像素只有10%以下的点,其亮度差值变化超过2%,而色度差值的变化只有1%以下。 采用的压缩方法: 分组:把几帧图像分为一组(GOP),为防止…

亚洲第二富豪吕志和的“双赢”人生

亚洲第二富豪“香港石矿大王”吕志和,作为香港四大传奇富商之一,由于行事低调,鲜少接受媒体访问,使他更富有商界传奇色彩。 在多年的经营发展中,吕志和秉承真诚守信,互惠共存的商业信条,助他闯…

《 第一本Docker书 》读书笔记 --- Docker 各项操作命令及参数说明(docker run 命令各个参数说明)

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 PS :个人所有读书笔记只记录个人想要的内容,很可能原书大量内容没有纳入笔记中... ... 1. 可用 docker info 查…

配置u-boot的ip、网卡ip的命令

配置u-boot的ip地址: 串口连接设备,重启读秒时快速回车进入u-boot: setenv serverip 192.168.x.x 配置PC段连接的IP. setenv ipaddr 192.168.x.x 配置板子的.配置网卡ip(临时) 设备端终端: # ifconfig eth0 192.168.1.155 net…

Hadoop localhost: frankxulei@localhost: Permission denied (publickey,password)

Hadoop启动HDFS进程的时候报错,提示权限不够,具体信息如图所示:localhost: frankxuleilocalhost: Permission denied (publickey,password). frankxuleiubuntu:/usr/local/hadoop$ sbin/start-all.shWARNING: Attempting to start all Apache…

解决: java.net.ConnectException: Connection refused: connect

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 java.net.ConnectException: Connection refused: connect 1. 报错如上。 2. 原因和解决: 1)端口号被占用&…

大富由天定,小富靠算计!

没有人愿意自己越过越穷,但是相信还是有很多人对自己的财务状况一头雾水。 如果要给现在的流行词汇做一个排行榜,相信“理财”肯定位列其中。 不管钱多钱少,拥有更多的财富是每个人的追求目标。 但认识误区还是不少, 比如&am…

几个sql案例

第一题 select Case When t.flag>0 Then "T" Else "F" End from (SELECT instr(TableA.col1,TableA.col2) as flag from TableA) t第三题 select s.* from student s ,(SELECT name,MAX(score) m from student GROUP BY name) t where s.name t.n…

京东购物在微信等场景下的算法应用实践

本文根据京东微信手Q业务部马老师在京东\u0026amp;DataFun Talk算法架构系列活动中所分享的《京东购物在微信等场景下的算法应用实践》编辑整理而成,在未改变原意的基础上稍做修改。此次分享的是以WQ(微信手Q)购物智能推荐系统介绍智能推荐算…

va_list/va_start/va_end的使用

va_list 键入以保存有关变量参数的信息 va_start 初始化变量参数列表 初始化ap以检索参数paramN后面的附加参数。 调用va_start的函数在返回之前也应调用va_end。 参数不能是引用类型,也不能是与传递没有参数的参数时产生的类型不兼容的类型。 /* va_start examp…

docker save 与 docker export 的区别

缘起 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 docker save和docker export都能导出镜像包,咋看起来区别似乎不大。本文就针对这个问题,试图搞清楚docker…

这5种员工,千万不能重用

一、道德品质存在缺陷之人不能用。 (小人不能用) 当今社会,我们在评论一个人的好坏时,首先看到的是他的道德素养。这方面界定这个人的为人本质。一个道德本质不行、差的人,我们统称为小人。小人的本质表现为&#xff…

docker:安装mysql多个

Docker 容器镜像删除 docker commit了一个镜像之后想删除旧的镜像,出现以下报错 Error response from daemon: conflict: unable to delete 6f8214d56bfc (cannot be forced) - image has dependent child images 解决思路: docker save保存容器 docker …

PS图片后期之超简易造光调色方法

技法是死的,而人是活的,说的简单一点就是我们要学会开拓一下思维,调色的方法并不是只有【可选颜色】而已。 在修片之前,我们先要学会分析,在拍摄这一组照片时我希望有一种夕阳的光穿透晒在脸庞的感觉,而左边…

onvif发送订阅规则

发送消息的主要内容: 1、初始化请求 2、填充要发送的数据 3、发送并接受返回的数据 4、解析数据 5、清理缓存 正文 1、初始化onvif请求 定义一个onvif请求req 定义一个onvif标签tag 临时资源*tmpValue 临时结果tmpresult 主机ip acHostIp[16] ip地址 acLocalAddr…

在 idea 中为类和方法自动生成注释

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到教程。 项目规范中有一项常见的要求,在类级和方法级注释里写上创建者和创建时间,在方法级注释里写上创建者和维护者&…

《PWA实战:面向下一代的Progressive Web APP》读书笔记

前言 之前自己根据网上的教程学习写了几个PWA的小Demo,觉得PWA很有意思,想要更多的了解一下PWA,所以读了这本书。这本书是MANNIN出版社出的,所以书里的代码都有非常棒的注释,因此这篇笔记不会展开讲代码,而…

2进制 , 8进制 , 10进制 , 16进制 , 介绍 及 相互转换 及 快速转换

为什么要使用进制数 数据在计算机中的表示&#xff0c;最终以二进制的形式存在 , 就是各种 <黑客帝国>电影中那些 0101010… 的数字 ; 我们操作计算机 , 实际 就是 使用 程序 和 软件 在 计算机上 各种读写数据, 如果我们直接操作二进制的话 , 面对这么长的数进行思考或…

如何战胜浮躁

浮躁是当下年轻人的通病&#xff0c;因为各种压力或心智不够成熟等原因&#xff0c;导致在生活工作当中经常处于一种情绪无法自如控制的状态。这种浮躁的状态不仅影响到正常的工作生活&#xff0c;长时间的话还会影响到身体健康。本篇就来分享一些如何战胜浮躁的方法&#xff0…

wireshark的使用方法(转)

https://www.cr173.com/html/20128_all.html