call、apply和 bind的简单使用方法
- call、apply:
在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。
JavaScript 的一大特点是,函数存在「定义时上下文」和「运行时上下文」以及「上下文是可以改变的」这样的概念。
call可以传递一个thisArgs参数和一个参数列表,thisArgs 指定了函数在运行期的调用者,也就是函数中的 this 对象,而参数列表会被传入调用函数中。thisArgs 的取值有以下4种情况:
(1) 不传,或者传null,undefined, 函数中的 this 指向 window 对象
(2) 传递另一个函数的函数名,函数中的 this 指向这个函数的引用
(3) 传递字符串、数值或布尔类型等基础类型,函数中的 this 指向其对应的包装对象,如 String、Number、Boolean
(4) 传递一个对象,函数中的 this 指向这个对象
function a() {
console.log(this); //输出函数a中的this对象
}
function b() {} //定义函数b
var obj = {
name: 'hehe'
}; //定义对象obj
a.call(); //window
a.call(null); //window
a.call(undefined); //window
a.call(1); //Number
a.call(''); //String
a.call(true); //Boolean
a.call(b); // function b(){}
a.call(obj); //Object
这是call 的核心功能,它允许你在一个对象上调用该对象没有定义的方法,并且这个方法可以访问该对象中的属性。
function animals() {}
animals.prototype = {
type: "dog",
say: function() {
console.log("I am a " + this.type);
}
}
var dog = new animals();
dog.say(); //I am a dog
var cat = {type:'cat'};
dog.say.call(cat); //I am a cat
因此,可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中cat没有say方法),但是其他的有(本栗子中dog有say方法),我们可以借助call或apply用其它对象的方法来操作。
apply、call 的区别:
对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。
对象.函数名.call(thisArgs, arg1, arg2);
对象.函数名.apply(thisArgs, [arg1, arg2])
其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。
- bind:
bind是ES5 新增的一个方法,它的传参和call类似,但又和 call/apply 有着显著的不同,即调用 call 或 apply 都会自动执行对应的函数,而 bind 不会执行对应的函数,只是返回了对函数的引用。
MDN的解释是:bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。
var obj = {
id : 1,
eventBind: function(){
var _this = this;
$('.btn').on('click',function(event) {
alert(this.id); //undefined
alert(_this.id); //1
});
}
}
obj.eventBind();//没有这句话,click事件不执行
由于 Javascript 特有的机制,上下文环境在 eventBind:function(){ } 过渡到 $('.btn').on('click',function(event) { }) 发生了改变,上述使用变量保存 this 这些方式都是有用的,也没有什么问题。当然使用 bind() 可以更加优雅的解决这个问题:
var obj = {
id : 1,
eventBind: function(){
$('.btn').on('click',function(event) {
alert(this.id); //1
}.bind(this));
}
}
obj.eventBind();//没有这句话,click事件不执行
- call、apply和bind的区别:
var obj = {
x: 88,
};
var foo = {
getX: function() {
return this.x;
}
}
console.log(foo.getX.bind(obj)()); //88
console.log(foo.getX.call(obj)); //88
console.log(foo.getX.apply(obj)); //88
三个输出的都是88,但是注意使用 bind() 方法后面多了对括号。
也就是说,区别就是,当你希望改变上下文环境之后并非立即执行,而是回调执行的时候,使用 bind() 方法;而 apply/call 则会立即执行函数。
本文转载于:猿2048https://www.mk2048.com/blog/blog.php?id=h1kk2jkj0ib
call、apply和 bind的简单使用方法的更多相关文章
- Javascript中call,apply,bind方法的详解与总结
在 javascript之 this 关键字详解 文章中,谈及了如下内容,做一个简单的回顾: 1.this对象的涵义就是指向当前对象中的属性和方法. 2.this指向的可变性.当在全局作用域时,thi ...
- 继承:call、apply、bind方法
javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. call,apply,bind这 ...
- JavaScript中的call、apply、bind方法的区别
在JavaScript 中,this的指向是动态变化的,很可能在写程序的过程中,无意中破坏掉this的指向,所以我们需要一种可以把this的含义固定的技术,于是就有了call,apply 和bind这 ...
- JS进阶系列之this (call、apply、bind)
在javascript中,this的指向是在执行上下文的创建阶段确定的,其实只要知道不同执行方式下,this的指向分别是是什么,就能很好的掌握this这个让人摸不透的东西. 一.全局执行 全局执行又分 ...
- call,apply,bind的用法与区别
1.call/apply/bind方法的来源 首先,在使用call,apply,bind方法时,我们有必要知道这三个方法究竟是来自哪里?为什么可以使用的到这三个方法? call,apply,bind这 ...
- 对于call,apply,bind 的理解
JavaScript 中 call().apply().bind() 的用法 之前对与JavaScript中的call,apply,bind这几个方法一直理解的很模糊,今天总结一下. 例1 var n ...
- 有关call和apply、bind的区别及this指向问题
call和apply都是解决this指向问题的方法,唯一的区别是apply传入的参数除了其指定的this对象之外的参数是一个数组,数组中的值会作为参数按照顺序传入到this指定的对象中. bind是解 ...
- 简单模拟实现javascript中的call、apply、bind方法
目录 引子 隐式丢失 硬绑定 实现及原理分析 总体实现(纯净版/没有注释) 写在最后 引子 读完<你不知道的JavaScript--上卷>中关于this的介绍和深入的章节后,对于this的 ...
- JS中的call、apply、bind方法
JS中的call.apply.bind方法 一.call()和apply()方法 1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]] ...
随机推荐
- UnicodeDecodeError
'gbk' codec can't decode byte 0x80 in position xx open文件时,添加参数'encoding='utf-8' 'utf-8' codec can't ...
- package.xml使用说明
1. package.xml使用说明 a. pacakge.xml 包含了package的名称. 版本号. 内容描述. 维护人员. 软件许可. 编译构建工具. 编译依赖. 运行依赖等信息. 2. pa ...
- LeetCode-062-不同路径
不同路径 题目描述:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 "Start" ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角(在下 ...
- Jmeter-根据负载计算并发用户实际案例
业务场景 假设公司领导现在给你分配了一个性能测试需求如下: 1:公司有1000人在上班时间段会登录平台进行打卡操作,可能会登录打卡多次2:业务高峰时间段在8:00-8:30,半小时3:需要保证90%用 ...
- 【python】人脸识别
#coding:utf-8# from __future__ import print_functionfrom time import time #有些步骤要计时,看每个步骤花多长时间import ...
- CentOS8时间同步
CentOS8中默认已经不再支持ntpd软件包,同时也无法通过官方软件仓库安装, CentOS8上使用Chrony配置NTP服务器,用于同步时间. 它有两个程序,chrony和chronyd, chr ...
- Java学习笔记:04面向对象-内部类_访问修饰符_final
04面向对象-内部类/访问修饰符/final 1.static的介绍 static:关键字,静态的 static的作用是用来修饰类中的成员 2.访问一个类中的某一个成员变量 方法一: _1.创建对象 ...
- vue-cli项目创建步骤
vue-cli项目创建步骤: 1.cmd打开命令行窗口 2.输入cnpm install vue-cli -g,然后回车等待(想在哪个目录建立vue项目就要在进入到对应目录再输入命令) 3.安装结束后 ...
- 官宣 .NET 7 Preview 2
今天,我们很高兴发布 .NET 7 预览版 2..NET 7 的第二个预览版包括对 RegEx 源生成器的增强.将 NativeAOT 从实验状态转移到运行时的进展,以及对"dotnet n ...
- Qt记事本,美化版
主体代码实现 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QMenu> ...