网站首页 > 知识剖析 正文
我们在看一些插件的时候,经常会用到这 3 个函数,那么他们具体的用途是什么呢?区别又是什么呢?我们先看看下面一段代码:
var name = '小白'
var obj = {
name: '小明',
getName: function () {
console.log(this, this.name)
return this.name
}
}
var getName = obj.getName
obj.getName()
// obj, 小明
getName()
// window,小白
是不是很神奇,同一个函数,执行的结果不一样,这里涉及到一个this的指向问题。
函数中的this指向
js中一个普通函数this的指向与其本身无关,只与调用该函数的对象有关。根据这个规则,我们回到上面的问题,obj.getName调用getName函数的对象是obj,所以this指向了obj对象,那么得到的obj.name为小明;而getName()是直接调用的函数,实际上是window.geName()是window对象在调用函数,this则指向window对象。(use strict 严格模式下,全局 this 是 undefined,而不是window)。
关于this的指向这里不做具体讲解,毕竟这是个复杂的问题,后面再分情况讲解,毕竟这也是一个高频面试题。
bind、call、apply 的作用
这 3 个函数的作用是,改变一个函数在执行时this的指向。我们来改造上面的代码。
var name = '小白';
var obj = {
name: '小明',
getName: function () {
console.log(this, this.name)
return this.name
}
};
var obj1 = {name: '小花'}
var getName = obj.getName;
getName();
// window,小白
obj.getName();
// obj, 小明
getName.apply(obj);
// obj,小明
getName.call(obj1);
// obj1,小花
getName.bind(obj)();
// obj,小明
可以看到,当我们改用apply去调用函数时,不管其所在的作用域,我们的this指向bind,apply,call函数接受的第一个参数。
相同点与不同点
相同点:三个函数都是为了改变被调用函数的this指向,都指向接受的第一个参数。
不同点:
- apply和call都是直接调用函数,而bind则是先将函数暂存起来,需要再单独调用一次。
- apply和call第一个参数一样,都是要绑定给 this 的值,如果这个值为null或者undefined,则为window对象。他们的区别在第二个参数上:当函数需要传递多个变量时, apply可以接受一个数组作为参数输入, call 则是接受一系列的单独变量。当参数个数已知的时候可以用call,而当参数个数不确定的时候可以用apply。
- bind和call很相似,第一个参数是this的指向,从第二个参数开始是接收的参数列表。区别在于bind方法返回值是函数以及bind接收的参数列表的使用。bind 方法不会立即执行,而是返回一个改变了上下文 this后的函数。而不会影响原函数中的this指向。
最后我们再看一个完整的实例来表现这个三个函数的用途和区别:
function sub(a, b) {
const sub = a + b
console.log(sub)
return sub
}
sub.call(null, 1, 2)
sub.apply(null, [1, 2])
sub.bind(null, 1, 2)()
可以看到,call和apply参数不一样,而bind参数和call一样,但还需要单独调用一下函数。
应用场景
求数组中的最大和最小值
var arr = [0,8,3,46]
var max = Math.max.apply(null,arr);//46
var min = Math.min.apply(null,arr);//0
// 等价于
var max = window.Math.max(...arr);
var min = window.Math.min(...arr);
这里利用apply的第二个参数是接受一个数组,而在调用函数的时候会自动展开这个数组,而max和min方法接受参数的形式是(1,2,3,4)。
将 arguments 等类数组转换为数组
var trueArr = Array.prototype.slice.call(arguments,0,arguments.length)
判断变量类型
function isArray(obj){
return Object.prototype.toString.call(obj) == '[object Array]';
}
isArray([]) // true
isArray('dot') // false
使用 log 代替 console.log
function log(){
console.log.apply(console, arguments);
}
总结
call、apply、bind都是为了改变当前要执行函数this指向,由第一个参数决定,为null或者undefined时则为window对象。call和apply的参数有区别。而bind不是马上执行函数,而是返回该函数和保留该函数的执行上下文。
学习如逆水行舟,不进则退,前端技术飞速发展,如果每天不坚持学习,就会跟不上,我会陪着大家,每天坚持推送博文,跟大家一同进步,希望大家能关注我,第一时间收到最新文章。
?
猜你喜欢
- 2024-11-13 “A妹”“碧梨”入围2020全英音乐奖最佳国际女歌手
- 2024-11-13 90后女生相亲50次仍单身,心理专家:这2招轻松搞定约会交谈
- 2024-11-13 三字男星嫖娼后续!录音内容毁三观,戴向宇成瓜主?多方回应来了
- 2024-11-13 吴亦凡鹿晗为黄子韬新歌打call 吴亦凡鹿晗黄子韬合体
- 2024-11-13 2019年这10部小说将被改编成电影 主演全都是熟面孔
- 2024-11-13 答应我,搞懂call、apply好嘛 call me by your name完整版在线观看
- 2024-11-13 《歌手》首战Jessie J夺冠 张天排第二
- 2024-11-13 SNH48 GROUP偶像运动会圆满落幕 snh48 7senses偶像运动会
- 2024-11-13 蔡依林为Jessie J打call:跪!说不出话来了!
- 2024-11-13 JS 歌曲 花与剑 手游花与剑歌曲
- 最近发表
-
- jQuery EasyUI使用教程:创建展开行详细编辑表单的CRUD应用
- CSDN免登陆复制代码的几种方法(csdn扫码登录怎么实现的)
- LayUi提高-Select控件使用(layui form select)
- 用 Playwright MCP 让 AI 改它自己写的屎山代码
- multiple-select.js中手动设置全选和取消全选
- 前端实现右键自定义菜单(html 自定义右键菜单)
- JavaScript脚本如何断言select下拉框的元素内容?
- 广州蓝景分享—实用的CSS技巧,助你成为更好的前端开发者
- MyBatis-Plus码之重器 lambda 表达式使用指南,开发效率瞬间提升80%
- Go语言之select的使用和实现原理(go select case)
- 标签列表
-
- xml (46)
- css animation (57)
- array_slice (60)
- htmlspecialchars (54)
- position: absolute (54)
- datediff函数 (47)
- array_pop (49)
- jsmap (52)
- toggleclass (43)
- console.time (63)
- .sql (41)
- ahref (40)
- js json.parse (59)
- html复选框 (60)
- css 透明 (44)
- css 颜色 (47)
- php replace (41)
- css nth-child (48)
- min-height (40)
- xml schema (44)
- css 最后一个元素 (46)
- location.origin (44)
- table border (49)
- html tr (40)
- video controls (49)