JS的函数和this
JS 函数 this
2023-06-13 09:13:55 时间
背景
我没有系统性的从头开始学过一遍JS,全凭之前学的其它语言,尤其是Python,直接上手操作了,所以留了不少的坑。
虽然对我来说是一个坑,但我觉得本文更适合放到学习的分类里。
给出下列代码。这里是对原问题的一个抽象,只是把问题的核心单独摘出来了:
function each(arr, action) {
for (const item of arr) {
action(item)
}
}
const arr1 = [1, 2, 3]
const arr2 = []
each(arr1, item => arr2.push(item))
console.log(arr2)
// [ 1, 2, 3 ]
这个函数它的功能就是遍历一遍数组,然后把每个元素传给action
参数。到目前为止是没有问题的。
问题复现
我这里自作聪明,把上面的第9行改了一下,简化代码:
each(arr1, arr2.push)
然后就顺利的报错了,这里给出错误信息:
action(item)
^
TypeError: Cannot convert undefined or null to object
这里是node的报错,当时在浏览器里内容不太一样,但也提到了undefined
相关的内容。
原理
原理很简单,就是action(item)
这样调用的时候,传给action
的this
是undefined
。
新建一个文件,写入下列代码足以验证。这里的foo
是obj
对象的实例方法,es6
语法:
'use strict'
function call(func) {
func()
}
const obj = {
foo() {
console.log(this)
}
}
obj.foo()
// { foo: [Function: foo] }
call(obj.foo)
// undefined
这里要是严格模式,否则this
会指向global
(node)或者window
(浏览器)。
这里扯一下Python,同样的代码它运行出来结果就会不一样了。如果你对Python没有兴趣可以略过这里的对比:
def call(f):
f()
class Foo:
def bar(self):
print(self)
obj = Foo()
obj.bar()
# <__main__.Foo object at 0x0000017E14126E10>
call(obj.bar)
# <__main__.Foo object at 0x0000017E14126E10>
这里的原因就是,当我们使用obj.bar
这样获得方法的话,Python会给我们把obj
和第一个参数self
绑定上。
解决方案
我们需要进行一个操作,如果也想像Python那样: Function.prototype.bind()
bind()
方法创建一个新的函数,在bind()
被调用时,这个新函数的this
被指定为bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。 来源: MDN
所以说我们把上面的JS测试代码改成这样,就可以了:
call(obj.foo.bind(obj))
// { foo: [Function: foo] }
但是回到我们实际应用场景,还是这样写更好点:
call(() => obj.foo())
// { foo: [Function: foo] }
或许还有更多的方法。至于如何选择,就仁者见仁、智者见智了。
相关文章
- js indexOf 的正确用法「建议收藏」
- js用户注册表单验证_onclick调用js函数
- 【说站】js函数中参数的使用
- 【说站】js函数声明的提升顺序
- 在线客服系统复制聊天链接,JS实现复制文本函数
- 显示农历的js代码详解编程语言
- js Date 函数方法详解编程语言
- JS数组转字符串(3种方法)
- JS注册事件和销毁事件
- Linux上的JS压缩工具(js压缩工具linux)
- 利用 JS 实现 Redis 的连接(js连接redis)
- 使用JS技术实现Oracle数据库链接(js 链接 oracle)
- 用js怎么把&字符换成"&:"
- [js]轻便的XMLHttpRequest应用函数:downloadUrl()
- 用JS输入email的代码,以防垃圾邮件
- js验证符合用户体验的网页表单特效
- 兼容IE和FF的js脚本代码小结(比较常用)
- js编程笔记无名函数
- 用正则表达式判断字符串是汉字还是拼音的js函数代码
- js动画(animate)简单引擎代码示例
- JS特殊函数(Function()构造函数、函数直接量)区别介绍
- JS实现导航栏悬停效果
- JS取文本框中最小值的简单实例
- js定时器(执行一次、重复执行)
- js字符串完全替换函数分享