call、apply 和 bind
call()、apply()、bind() 都是用来重定义 this 这个对象的!
var obj1 = {
username: "HuiTaiLang",
fn: function() {
concole.loh(this);
console.log(this.username);
}
}
var obj2 = obj1.fn;
obj2(); //undefined
我们想打印对象 obj2 里面的 username 却打印出来 undefined 是怎么回事呢?如果我们直接执行 obj2.fn()是可以的。
var obj1 = {
username: "HuiTaiLang",
fn: function() {
console.log(this);
console.log(this.username);
}
}
obj1.fn(); //HuiTaiLang
能够打印是因为,第一个打印里面的 this 指向全局window,第二个打印里面的 this 指向 obj1 。


虽然这种方法可以达到打印username目的,但是如果我们需要将对象保存到另外的一个变量中,那么就可以通过以下方法。
call
var obj1 = {
username: "HuiTaiLang",
fn: function() {
console.log(this)
console.log(this.username);
}
}
var obj2 = obj1.fn;
obj2.call(obj1); // HuiTaiLang
通过在 call 方法,第一个参数就是要添加的 obj1环境中,简单来说,this就会指向那个对象。
call 方法除了第一个参数以外还可以添加多个参数,如下:
var obj1 = {
username: "HuiTaiLang",
fn: function(num1, num2) {
console.log(num1 + num2);
console.log(this.username);
}
}
var obj2 = obj1.fn;
obj2.call(obj1, 2, 3); // 5
apply
apply方法和call方法有些相似,它也可以改变this的指向。
var obj1 = {
username: "HuiTaiLang",
fn: function() {
console.log(this.username);
}
}
var obj2 = obj1.fn;
obj2.apply(obj1); // HuiTaiLang
同样apply也可以有多个参数,但是不同的是,第二个参数必须是一个数组,如下:
var obj1 = {
username: "HuiTaiLang",
fn: function(num1, num2) {
console.log(num1 + num2);
console.log(this.username);
}
}
var obj2 = obj1.fn;
obj2.apply(obj1, [2, 3]); // 5
注意:如果call和apply的第一个参数写的是null,那么this指向的是window对象。
var obj1 = {
username: "HuiTaiLang",
fn: function() {
console.log(this);
}
}
var obj2 = obj1.fn;
var obj3 = obj1.fn;
obj2.call(null); // window
obj3.apply(null); // window
bind
bind和call、apply方法不同,实际上bind方法返回的是一个修改过后的函数。
var obj1 = {
username: "HuiTaiLang",
fn: function() {
console.log(this.username);
}
}
var obj2 = obj1.fn;
obj2.bind(obj1);
var newFn = obj2.bind(obj1);
console.log(newFn);
newFn();

我们会发现 bind 并没有被打印,而我们打印 newFn 打印出的是一个函数,并且可以正常执行。
同样bind也可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。
var obj1 = {
username: "HuiTaiLang",
fn: function(num1, num2) {
console.log(num1 + num2);
console.log(this.username);
}
}
var obj2 = obj1.fn;
var newFn1 = obj2.bind(obj1, 2, 3);
var newFn2 = obj2.bind(obj1);
newFn1();
newFn1(2, 3);
总结:
call 、bind 、apply 都可以用来改变上下文中的 this。这三个函数的第一个参数都是 this 的指向对象,后面的参数:
- call 的参数是直接放进去的,后面的参数全都用逗号分隔。
- apply 的所有参数,都必须放在一个数组里面传进去。
- bind 除了返回是函数以外,它的参数和 call 一样。
当然,三者的参数不限定是 string 类型,允许是各种类型,包括函数 、 object 等等!
call、apply 和 bind的更多相关文章
- JS核心系列:浅谈 call apply 与 bind
在JavaScript 中,call.apply 和 bind 是 Function 对象自带的三个方法,这三个方法的主要作用是改变函数中的 this 指向,从而可以达到`接花移木`的效果.本文将对这 ...
- Javascript中call,apply,bind方法的详解与总结
在 javascript之 this 关键字详解 文章中,谈及了如下内容,做一个简单的回顾: 1.this对象的涵义就是指向当前对象中的属性和方法. 2.this指向的可变性.当在全局作用域时,thi ...
- JS中call、apply、bind使用指南,带部分原理。
为什么需要这些?主要是因为this,来看看this干的好事. box.onclick = function(){ function fn(){ alert(this); } fn();}; 我们原本以 ...
- Javascript中call、apply、bind函数
javascript在函数创建的时候除了自己定义的参数外还会自动新增this和arguments两个参数 javascript中函数也是对象,call.apply.bind函数就是函数中的三个函数,这 ...
- 图解call、apply、bind的异同及各种实战应用演示
一.图解call.apply.bind的异同 JavaScript中函数可以通过3种方法改变自己的this指向,它们是call.apply.bind.它们3个非常相似,但是也有区别.下面表格可以很直观 ...
- js里function的apply vs. bind vs. call
js里除了直接调用obj.func()之外,还提供了另外3种调用方式:apply.bind.call,都在function的原型里.这3种方法的异同在stackoverflow的这个答案里说的最清楚, ...
- JS之apply,call,bind区别
为了加深对基础知识的理解,今天再复习下js中的apply,call,bind的区别和用法.整理笔记的过程也是一个再次学习的过程. apply和call js中的调用apply和call方法可以改变某个 ...
- JavaScript中call、apply、bind、slice的使用
1.参考资料 http://www.cnblogs.com/coco1s/p/4833199.html 2.归结如下 apply . call .bind 三者都是用来改变函数的this对象的指向 ...
- JS中的控制函数调用:call(),apply()和bind()
所有的函数都具有call(),apply()和bind()方法.它们可以在执行方法的时候用一个值指向this,并改变面向对象的作用域. apply方法: 以下的两种表达式是等价的: func(arg1 ...
- JS中的call、apply、bind方法
JS中的call.apply.bind方法 一.call()和apply()方法 1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]] ...
随机推荐
- 普通web项目一直无法访问页面,直接报404
错误:普通web项目一直无法访问页面,直接报404 原因:写了一个过滤乱码的类: 而在类上加了WebServlet注解,其实应该是WebFilter注解, 总结:基础不扎实,有些东西只会用,而不知道原 ...
- 解决死锁之路3 - 常见 SQL 语句的加锁分析 (转)
出处:https://www.aneasystone.com/archives/2017/12/solving-dead-locks-three.html 这篇博客将对一些常见的 SQL 语句进行加锁 ...
- 超详细的node/v8/js垃圾回收机制
前言 垃圾回收器是一把十足的双刃剑.其好处是可以大幅简化程序的内存管理代码,因为内存管理无需程序员来操作,由此也减少了(但没有根除)长时间运转的程序的内存泄漏.对于某些程序员来说,它甚至能够提升代码的 ...
- Info.plist常见的设置
建立一个工程后,会在Supporting files文件夹下看到一个"工程名-Info.plist"的文件,该文件对工程做一些运行期的配置,非常重要,不能删除 在旧版本Xcode创 ...
- AFNetWorking 文件上传 By-H罗
一.文件上传(图片,音频,视频,文本等)(不带进度) /** * 文件上传 导入 #import "AFNetworking.h" * @param filePath 上传文件本地 ...
- java中的代码块(初始化块)
介绍 代码块又叫初始化块,属于类中的成员,类似于方法,将逻辑语句封装在方法体中,通过{ } 包围起来,但和方法不同,没有方法名,没有返回值,没有参数,只有方法体,而且不通过对象或类显示调用,而是加载类 ...
- JVM学习——类加载机制(学习过程)
JVM--类加载机制 2020年02月07日14:49:19-开始学习JVM(Class Loader) 类加载机制 类加载器深入解析与阶段分解 在Java代码中,类型的加载.连接与初始化过程中都是在 ...
- 继承及super关键字
继承 继承的本质是对某一批类的抽象,从而实现对世界更好的建模 extend的意思是"扩展",子类是父类的扩展. Java中类只有单继承,没有多继承:儿子只能有一个亲生爸爸,一个爸爸 ...
- 基于Windows系统应用的权限维持
1.dll劫持 生成dll 通过msf将dll木马上传到目标应用程序的dll文件夹里面,然后通过msf来将木马dll名称和正常dll名称进行互换 远程开启监听,然后一旦目标机器的应用程序运行就会触发d ...
- [题解]UVA11027 Palindromic Permutation
链接:http://vjudge.net/problem/viewProblem.action?id=19602 描述:给出一个字符串,求重新排列后第n个回文串,若没有则输出"XXX&quo ...

