一、call

call有两个妙用

1、继承(我前面的文章有提到用call实现call继承,有兴趣可以看下。https://www.cnblogs.com/pengshengguang/p/10547624.html

2、修改函数运行时this的指向(今天要说的)

// 代码段一
var obj = {name: 'psg'};
function fn(num1, num2) {
console.log(num1+num2);
console.log(this)
}
// 1、call里面,第一个参数就会说要变成this的对象
fn(100, 200); //this指向window, num1=100, num2=200
fn.call(100, 200); //this指向100, num1=200, num2=undefined
fn.call(obj, 100, 200); //this指向obj, num1=100, num2=200 // 2、在非严格模式下,call里面,第一个参数如果是空、null、undefined,会导致this指向window
fn.call(); //this指向window // 3、在严格模式下,call里面,传谁this就是谁,不传,this就是undefined
fn.call(); //this指向undefined
fn.call(null); //this指向null
fn.call(undefined); //this指向undefined

二、apply

1、apply和call方法的作用是一模一样的,都是用来改变方法中this关键字并且将方法执行,而且在严格模式、非严格模式下对于第一个参数是null / undefined这种情况的规律也是一样的。

2、跟call唯一的的区别就是语法的区别:

//call传递参数是用逗号分隔,一个一个传进去
fn.call(obj, arg1,arg2,arg3.....)
//apply传递参数是用一个数组传的
fn.apply(obj, [arg1,arg2,arg3....])

三、bind

1、这个方法在IE6-IE8下不兼容。

2、与apply、call类似,都是用来改变this指向,但是bind体现了js的预处理思想。

->预处理:实现把fn的this改变成我们想要的结果,并且把对象的参数也准备好了,以后要用到了,直接执行即可。

var obj = {name: 'psg'};
function fn(num1, num2) {
console.log(num1+num2);
console.log(this);
}
fn.call(obj, 100, 200);
fn.bind(obj, 100, 200); // 只是改变了fn中的this为obj,并且给fn传递了两个参数值,但是此时并没有给fn这个函数执行。
// 但是,执行bind会有一个返回值,这个返回值myFn就是我们把fn的this改变后的那个结果!!! //那么,如何让fn这个函数执行呢,下面的写法就行解决方法
var myFn = fn.bind(obj, 100, 200);
myFn();

四、深入理解call

  4.1 如果我们要理解call,我们首先要知道call是怎样被执行的,涉及到了原型链查找机制。

//例如,现在有一个函数fn,我们想改变fn中this的指向,因此我们可以
fn.call(obj);
//上面的代码,其实是首先通过fnl的原型链,找到Function.ptototype中的call方法,然后执行call方法,cal方法中的this,就是fn

  4.2 伪代码模拟实现call方法

//伪代码
Function.prototype.myCall = function(context) {
//->1、让fn中的this关键字变成context
this = eval(this.toString().replace("this", context));
//->2、让fn执行
this();
}

  

  4.3 经典面试题

// 练习一
function fn1() {console.log(1);}
function fn2() {console.log(2);}
fn1.call(fn2); // ->1
// 原理:首先fn1通过原型链机制找到Function.prototype上的call方法,并且让call方法执行
// 此时call这个方法中的this就是fn1,在call方法执行过程中,让fn1中this关键字变成fn2,然后让fn1执行 fn1.call.call(fn2); // ->2
// 原理首先fn1通过原型链机制找到Function.prototype上的call方法,然后再让call方法通过原型找到call方法
// Function.prototype原型上的call(因为fn.call这个东西也是个函数数据类型),在第二次找到call时,让call方法执行,此时
// 的this是fn1.call。

  end

【JavaScript】深入理解call,以及与apply、bind的区别的更多相关文章

  1. javaScript 工作必知(十) call apply bind

    call  每个func 都会继承call apply等方法. function print(mesage) { console.log(mesage); return mesage; } print ...

  2. call apply bind 的区别

    1.call和apply都是对函数的直接调用,而bind方法返回的仍然是一个函数,因此后面还需要()来进行调用才可以 var xw={ name: "小王", gender: &q ...

  3. call apply bind的区别

    都是天生自带的内置方法(Function.prototype),所有的函数都可以调取这三个方法,改变this指向 call 语法:fn.call(context,para1......) 把fn方法执 ...

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

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

  5. call、apply/bind的区别和用法(简单粗暴的解释)

    var obj1={ name:"bob", age:20 } var obj2={ name:"coco", age:22 } function getAge ...

  6. 浅谈call apply bind的区别

    这三个方法的用法非常相似,将函数绑定到上下文中,即用来改变函数中this的指向.举个例子: var zlw = { name: "zlw", sayHello: function ...

  7. JS中call,apply,bind的区别

    1.关于this对象的指向,请看如下代码 var name = 'jack'; var age = 18; var obj = { name:'mary', objAge:this.age, myFu ...

  8. javascript中的call(),apply(),bind()方法的区别

    之前一直迷惑,记不住call(),apply(),bind()的区别.不知道如何使用,一直处于懵懂的状态.直到有一天面试被问到了这三个方法的区别,所以觉得很有必要总结一下. 如果有不全面的地方,后续再 ...

  9. 有关call和apply、bind的区别及this指向问题

    call和apply都是解决this指向问题的方法,唯一的区别是apply传入的参数除了其指定的this对象之外的参数是一个数组,数组中的值会作为参数按照顺序传入到this指定的对象中. bind是解 ...

  10. this指向与call,apply,bind

    this指向与call,apply,bind ❝ 「this」问题对于每个前端同学来说相信都不陌生,在平时开发中也经常能碰到,有时候因为「this」还踩过不少坑,并且「this」问题在面试题中出现的概 ...

随机推荐

  1. sql Left right join 多表 注意表的连接顺序

    多表左/右连接,表的连接顺序也可以影响查询速度 左连接时,应该把小表放在前面连接例子:A.B.C三表左连接情况1:A先和B连接,得到100条记录100条记录再和C左连接情况2:A先和C连接,得到50条 ...

  2. ntp时间同步,各种配置方法

    1 Windows xp NTP服务器的配置(2003配置方式一样) 1) 首先需要关闭作为NTP服务器的windows系统自带的防火墙,否则将同步不成功. 2) 单击“开始”,单击“运行”,键入 r ...

  3. Win8Metro(C#)数字图像处理--2.24二值图像闭运算

    原文:Win8Metro(C#)数字图像处理--2.24二值图像闭运算  [函数名称] 二值图像闭运算函数CloseOperateProcess(WriteableBitmap src) [算法说 ...

  4. 简单实用SQL脚本Part:查找SQL Server 自增ID值不连续记录

    原文:简单实用SQL脚本Part:查找SQL Server 自增ID值不连续记录 在很多的时候,我们会在数据库的表中设置一个字段:ID,这个ID是一个IDENTITY,也就是说这是一个自增ID.当并发 ...

  5. WPF 添加外部ResourceDirectory

    如果Resource资源文件在程序集中,可直接如下将资源文件添加当当前运行时 Application.Current.Resources.MergedDictionaries.Add(new Reso ...

  6. 零元学Expression Blend 4 - Chapter 41 Flash做的到的Blend也可以!轻松制作拥有动画的MenuBar!(中)

    原文:零元学Expression Blend 4 - Chapter 41 Flash做的到的Blend也可以!轻松制作拥有动画的MenuBar!(中) 我们接着进行动画MenuBar的制作 接续着上 ...

  7. 正则表达式-Csharp

    原文:正则表达式-Csharp 学习笔记:正则表达式 一. 正则表达式 正则表达式(Regex)是用来进行文本处理的技术,是语言无关的,在几乎所有语言中都有实现. 一个正则表达式就是由普通的字符及特殊 ...

  8. C#实现bitmap图像矫正

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  9. ASP.NET MVC控制器Controller中参数

    前述文章参见:ASP.NET MVC控制器Controller 绪论 之前的控制器返回的均为常量字符串,接下来展示如何获取请求传来的参数,而返回"动态"的字符串. 可以在操作方法B ...

  10. 使用百度网盘+Git,把版本控制托管到云端,附精彩评论

    http://www.cnblogs.com/vajoy/p/3929675.html 我试过多个这种双向同步的网盘,在网络状况不好.系统卡顿以及某些程序BUG的情况下,同步会有错乱现象,尤其是多个电 ...