我无法帮助,但注意到无法做到像
这样的事情 ["cat", "dog"].map(String.prototype.toUpperCase);
抛出
未捕获的TypeError:String.prototype.toUpperCase在null或undefined上调用
以下代码有效(在es6箭头表示法中为我的打字方便),但似乎很奇怪间接:
["cat", "dog"].map(s=>s.toUpperCase())
奇怪的是间接的,因为它创建了一个额外的匿名函数,只是为了包装一个已经存在的非常好的函数。也许这是一个人必须忍受的东西,但它的味道并不合适。
所以我有两个问题:
是否有直接的方法将字符串方法映射到字符串数组而不将其包装在匿名函数中?
为什么我首先尝试的代码无效的技术解释是什么?我有两个猜测,但不知道哪个是对的。
猜猜(a):这是因为拳击,即字符串文字与字符串对象不同,并且由于某种原因将方法映射到它们上并没有做同样的安静强制只是在字符串上调用方法。
猜猜(b):这是因为虽然函数是第一类对象,但方法不是以相同的方式,并且不能被映射?
猜猜(c):我应该使用其他一些语法?! ("".prototype.toUpperCase
??)因为JavaScript gremlins?因为null既是对象又不是对象?在ES2025中修复了吗?只要用lodash就可以治好了吗?
谢谢!
答案 0 :(得分:5)
1。是否有直接的方法将字符串方法映射到字符串数组而不将其包装在匿名函数中?
否(假设通过"没有将其包装在匿名函数中#34;您通常意味着"没有创建附加功能")。
2。为什么我首先尝试的代码不起作用的技术解释是什么?我有两个猜测,但不知道哪个是对的。
"问题"是toUpperCase
本质上是一个实例方法。它期望this
引用应该更改的值。但是.map
会将值作为参数传递给函数。你的第一个例子基本上是在做
String.prototype.toUpperCase("dog")
并且根本不是该功能如何运作。以下工作
String.prototype.toUpperCase.call("dog")
但反过来不是.map
的工作方式。
不猜a和b。关于c,您应该使用的语法是您的第二个解决方案。当然还有其他方法。你可以写一个辅助函数:
function toUpper(s) {
return s.toUpperCase();
}
但与使用箭头功能没什么不同。
由于toUpperCase
不接受参数,你甚至可能会疯狂到类似的事情
["cat", "dog"].map(String.prototype.toUpperCase.call.bind(String.prototype.toUpperCase));
但那
答案 1 :(得分:2)
当您尝试编写优雅的功能程序时,对象方法(以及处理this
)可能是一个真正的痛苦。不用担心,只是将有问题的语法抽象为自己的函数
const send = (method, ...args) => obj =>
obj[method](...args)
let x = ["cat", "dog"].map(send('toUpperCase'))
console.log(x) // ['CAT', 'DOG']
let y = ['cat', 'dog'].map(send('substr', 0, 1))
console.log(y) // ['c', 'd']

这是另一种可能很好的写作方式
const call = (f, ...args) => obj =>
f.apply(obj, args)
let x = ["cat", "dog"].map(call(String.prototype.toUpperCase))
console.log(x) // ['CAT', 'DOG']
let y = ['cat', 'dog'].map(call(String.prototype.substr, 0, 1))
console.log(y) // ['c', 'd']

另一种方法是定义自己的功能
const map = f => xs => xs.map(x => f(x))
const toUpperCase = x => x.toUpperCase()
const substr = (x,y) => z => z.substr(x,y)
let x = map (toUpperCase) (["cat", "dog"])
console.log(x) // ['CAT', 'DOG']
let y = map (substr(0,1)) (['cat', 'dog'])
console.log(y) // ['c', 'd']

答案 2 :(得分:0)
要回答您的问题,否,您无法在不使用回调函数的情况下将字符串方法映射到字符串数组。
你写的第一个代码:
["cat", "dog"].map(String.prototype.toUpperCase);
不能正常工作,因为.map()
方法需要一个处理每个迭代元素的回调函数并将其返回,但您只是试图在String.prototype.toUpperCase
上调用undefined
函数,因为您没有把它绑定到当前元素。
<强>解决方案:强>
为了让它工作并等同于ES6提供的代码:
["cat", "dog"].map(s=>s.toUpperCase())
您需要修改代码以接受在String.prototype.toUpperCase
方法传递的迭代元素上调用.map()
的回调函数:
["cat", "dog"].map(function(s){return s.toUpperCase()});
答案 3 :(得分:0)
var a = ["cat", "dog"];
var res = a.map(String.prototype.toUpperCase.call, String.prototype.toUpperCase);
console.log(res);
&#13;