为何无法将jQuery的data函数传入Array.map?两种写法为何不等价?
嘿,这个问题戳中了JavaScript里函数上下文绑定和jQuery方法内部逻辑的关键点,咱们一步步理清楚:
首先,你得明白jQuery的.data()方法是怎么工作的:它本质上是jQuery对象的一个方法,内部依赖this指向当前的jQuery实例——哪怕你只有一个元素的jQuery对象,.data()内部也会通过this.each()来处理元素(这是jQuery方法的通用设计,兼容多元素集合)。
那问题出在哪呢?
当你直接写
keys.map($el.data)时,你是把$el.data这个函数单独抽出来传给了Array.map。这时候,函数的调用上下文(也就是this)不再是原来的$el对象了!Array.map会把回调函数的this默认绑定到全局对象(浏览器里是window),或者你指定的第二个参数,但这里没指定,所以this变成了window。而window上根本没有each方法,自然就抛出TypeError: this.each is not a function了。而用匿名函数包裹的写法
keys.map(key => $el.data(key)),本质是在匿名函数里主动以$el作为调用者调用.data()。这时候.data()内部的this还是指向$el这个jQuery实例,所以能正常遍历(哪怕是单个元素)并返回对应的数据,自然得到[1,2]。
如果不想用匿名函数,还有个办法:用bind()把$el.data的上下文固定住,比如:
const keys = ['row-idx', 'col-idx']; const values = keys.map($el.data.bind($el));
这样$el.data的this就永远绑定到$el上,传给map调用时也不会出错,结果和匿名函数写法一致。
说白了,这两种写法完全不等价,核心区别就是函数调用时的this指向有没有被正确保留。
内容的提问来源于stack exchange,提问作者max pleaner

