bind、apply、call的理解
一直感觉代码中有call和apply就很高大上(看不懂),但是都草草略过,今天非要弄明白!
以前总是死记硬背:call、apply、bind 都是用来修改函数中的this,传参时,call是一个个传参,apply是数组形式传参,call和apply立即执行并且返回值是你调用的方法的返回值,若该方法没有返回值,则返回undefined。bind是改变this后返回一个新的函数,他不会立即执行。
死记硬背的结果就是:总以为这三个方法改变了原方法的this,原方法的this就永久改变了!大错特错啊!!
1.提出问题:看到好多call使用场景,就是不求甚解!
例1:Object.prototype.toString.call(arguments) 用来精确判断数据类型:"[object Array]" 或者 "[object Object]"
例2:Array.slice.call(类数组) 或者 [].slice.call(类数组) 用来把类数组转为数组,其实这里就是让类数组使用一下不属于自己的方法slice
2.验证问题:看看apply的用法 (别人写的)
function people(age,sex){
this.age=age;
this.sex=sex;
};
function adult(age,sex){
people.apply(this,arguments)
};
var jack = new adult(18,'man');
console.log(jack.age+":"+jack.sex)
输出为 18:man
其实看到这段代码就知道apply怎么用了吧。
其实apply说到底就是为了使一个对象可以使用不属于自己的方法,
3. 扩展(填坑之路):我想自己写一下验证apply会不会改变this,如下(自己写的)
function fn() {
console.log(this);
}
var obj={a:[4,5,6],b:[7,8]};
fn.apply(obj); // {a: Array(3), b: Array(2)}
var f=new fn(); // { }
郁闷:倒数第二行我不是用fn.apply(obj)改了fn的this指向为obj了么,为什么最后一行new出来的对象是空的?不应该是带a和b属性么?
答案:你只是用fn.apply(obj)执行了一把fn,执行时顺便把fn中的this改成了obj而已,然后把结果输出,这并不会改变fn原函数啊。
否则调用一次 Array.slice.call(类数组) ,难道就要把数组的slice方法里的this永久修改为传入的参数 类数组 么!那不是疯了么!
以后这样死记硬背:call、apply、bind 是Function.prototype下的方法,作用是执行一下目标函数,执行时顺便把目标函数中的this改一下,然后把结果输出,执行后,不会影响原函数!
题外话:如果你的代码也想用这三个方法,你就要学习数组的slice写法,里面的逻辑都考虑到this问题。
bind、apply、call的理解的更多相关文章
- javascript中bind,apply,call的相同和不同之处
javasctipt中bind,apply,call的相同点是: 1,都是用来改变this的指向; 2,都可以通过后续参数进行传参; 3,第一个参数都是指定this要指向的对象; 不同点: 1,调用方 ...
- javascript 的bind/apply/call性能
javascript有两种使用频率非常高的三个内置的功能:bind/apply/call.许多技术是基于高点,这些功能实现.这三个功能被用来改变的功能运行环境.从而达到代码复用的目的. 先来所说bin ...
- .bind.apply() 解决 new 操作符不能用与 apply 或 call 同时使用
背景: 小明想要用数组的形式为 Cls.func 传入多个参数,他想到了以下的写法: var a = new Cls.func.apply(null, [1, 2, 3]); 然而浏览器却报错Cls. ...
- bind,apply,call的区别
在Javascript中,bind, apply, call方法都可以显式绑定上下文this,这三者有何不同呢? bind只绑定this不马上执行 var person = { firstname: ...
- 箭头函数表达式和声名式函数表达式的区别以及 Function.prototype的bind, apply,call方法
箭头函数不能用做构造函数 箭头函数没有arguments参数 箭头函数没有自己的this,是从作用域链上取this,是与箭头函数定义的位置有关的,与执行时谁调用无关,所以用call,apply,bin ...
- javascript中call()、apply()、bind()的用法终于理解
其实是一个很简单的东西,认真看十分钟就从一脸懵B 到完全 理解! 先看明白下面: 例1 obj.objAge; //17 obj.myFun() //小张年龄undefined 例2 shows( ...
- JavaScript 中call()、 apply()、 bind()改变this指向理解
最近开发的过程中遇到了this指向问题,首先想到的是call().apply().bind()三个方法,有些时候这三个方法确实是十分重要,现在我们就把他们的使用方法及异同点讲解一下. 1.每个函数都包 ...
- apply通过实例理解
测试->运行环境chrom console >var aaa = {a:1,b:2,c:function(){console.log(this.a)}} 运行结果:undefined &g ...
- JavaScript: bind apply call
var foo = function(age,sex){ console.log(this.name,age,sex); }; //call将改变函数运行的context foo.call({name ...
- 理解$watch ,$apply 和 $digest --- 理解数据绑定过程
原文地址:http://angular-tips.com/blog/2013/08/watch-how-the-apply-runs-a-digest/ 注 这篇博文主要是写给新手的,是给那些刚刚开始 ...
随机推荐
- Vue利用搜狐获取公网ip地址
在index.html中添加代码: <script src="https://pv.sohu.com/cityjson?ie=utf-8"></script> ...
- spring的面试
IOC IOC(Inversion Of Controll,控制反转)是一种设计思想,将原本在程序中手动创建对象的控制权,交由给Spring框架来管理.IOC容器是Spring用来实现IOC的载体,I ...
- TCP协议有几大计时器?
1)超时重传计时器 目的:避免无限等待确认报文 创建时间:在发送TCP报文段时,会为该报文段设置一个超时重传计时器 可能发生的情况:在超时时间到达之前,收到了该报文段的确认则撤销计时器,否则重传该报文 ...
- linux根据进程名终止进程
2017年09月25日 19:44:32 aladdin_sun 阅读数 5235 linux根据进程名终止进程 实验环境 操作系统:CentOS Linux release 7.3.1611 ( ...
- Educational Codeforces Round 71
https://www.cnblogs.com/31415926535x/p/11460682.html 上午没课,做一套题,,练一下手感和思维,,教育场的71 ,,前两到没啥,,后面就做的磕磕巴巴的 ...
- python学习67-面向对象-封装
封装 1.什么是封装? 根据名字寓意为:把一个东西装起来,然后密封,类似这样的面向对象的编程为封装. 真正的封装是明确的区别内外,只能在内部用,外部无法调用. 2. 举例: class Car: _s ...
- go对elasticsearch的增删改查
环境 elasticsearch 6.8 (6.x版本应该都没问题) go客户端sdk: github.com/elastic/go-elasticsearch/v6 其实自己封装api也行,反正el ...
- springboot 配置elasticsearch Java High Rest Client
前提声明 在新版本的spring boot中逐渐放弃了对Spring Data Elasticsearch的支持,所以不推荐使用,使用ES官方推出的Java High Rest Client. 引入依 ...
- C#通用公共类库ZXNetStandardDepot.Common
总结了一下写项目中遇到的各种方法,总结前辈们的经验,生成了该类库,引用net standard类库,支持net core/net framework. 使用方法 1.nuget 搜索 ZXNetSta ...
- 报告题目:HAO智能:HI + AI + OI
报告题目:HAO智能:HI + AI + OI 报告摘要:大数据面向异构自治的多源海量数据, 旨在挖掘数据间复杂且演化的关联.大数据知识工程(BigKE)从大数据的 HACE定理开始, 从大知识建模 ...