将Function.prototype.call生成的函数作为参数传递时,Array.prototype.map不是函数

时间:2015-06-02 11:13:15

标签: javascript arrays

有时我像这样使用Array.prototype.map方法:

var array = ['1', '2', '3', '4'].map(parseFloat); // the result is [1, 2, 3, 4]
  

parseInt 需要2个参数,在这种情况下会返回不正确的值

现在我要做的不是代码:

var  array = ['a', 'b', 'c', 'd'].map( function (item) { 
    return item.toUpperCase(); 
}); // the result is ['A', B', 'C', 'D']

我试过了:

var array = ['a', 'b', 'c', 'd'].map(''.toUpperCase.call);

有人可以向我解释为什么我会收到错误消息:

  

未捕获的TypeError:[&#34; a&#34;,&#34; b&#34;,&#34; c&#34;,&#34; d&#34;]。地图不是函数< / p>

2 个答案:

答案 0 :(得分:4)

第一个问题是你传递的功能''.toUpperCase.apply Function.prototype.apply相同:它没有受约束。

会发生什么等同于

['a', 'b', 'c', 'd'].map(function(v, i, arr){
   return undefined.apply(v, i, arr)
});

如果使用

绑定它
['a', 'b', 'c', 'd'].map(''.toUpperCase.apply.bind(''.toUpperCase));

然后你遇到第二个问题:map不会只将一个参数传递给你的回调。它还传递索引和整个数组。

你可以用

“修复”这两个问题
['a', 'b', 'c', 'd'].map(function(v){ return ''.toUpperCase.apply(v) });

(更多解释而非修复,右)

使用call更容易,可以修复:

var arr = ['a', 'b', 'c', 'd'].map(''.toUpperCase.call.bind(''.toUpperCase));

应该写成

var arr = ['a', 'b', 'c', 'd'].map(Function.prototype.call.bind(''.toUpperCase));

旁注:您很幸运在第一个示例中使用了parseFloat。试试parseInt

答案 1 :(得分:1)

当您将func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { let location = locations.last as! CLLocation let geocoder = CLGeocoder() geocoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, e) -> Void in if let error = e { println("Error: (e.localizedDescription)") } else { let placemark = placemarks.last as! CLPlacemark self.addObserver(self, forKeyPath: "LocationString", options: .New, context: &self.myContext) self.LocationManager.stopUpdatingLocation() self.LocationString = "\(placemark.subLocality), \(placemark.locality)" println("\(placemark.subLocality), \(placemark.locality)") } }) } override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject: AnyObject], context: UnsafeMutablePointer<Void>) { } 传递给''.toUpperCase.call时,虽然它会正确传递参数,但Array.map函数会从call函数中解体,该函数包含实现细节。

所以,现在toUpperCase确实有Function.call回调函数传递给它的正确参数,但它没有引用Array.map函数。

  

MDN:您可以在调用现有对象时指定其他''.toUpperCase对象   功能。 this引用当前对象调用对象

所以this''.toUpperCase.call("a")完全不同,这是call("a")传递给''.toUpperCase.call时发生的事情