2012-02-16 10 views
23

मेरे पास तारों की एक सरणी है। मैं सरणी में प्रत्येक स्ट्रिंग को ट्रिम करना चाहता हूं।क्यों '' '.trim() `सीधे' [] .map()` 'कॉलबैक काम नहीं गुजर रहा है?

मैं ''.trim() साथ [].map() का उपयोग कर काम करेगा सोचा ...

[' a', ' b ', 'c'].map(String.prototype.trim); 

... लेकिन मेरे कंसोल ने कहा ...

TypeError: String.prototype.trim called on null or undefined

jsFiddle

मैं अपने सरणी में null या undefined मान नहीं देख सकता।

String.prototype.trim() और Array.prototype.map() क्रोम 17 में परिभाषित किया गया है, जिसका मैं परीक्षण करने के लिए उपयोग कर रहा हूं।

यह क्यों काम नहीं करता है? मुझे लगता है कि मैंने कुछ स्पष्ट रूप से अनदेखा किया है।

मुझे एहसास है कि मैं वहां एक लूप या ड्रॉप कर सकता हूं। हालांकि, इस सवाल का मुद्दा यह नहीं है।

उत्तर

16

trim, String प्रोटोटाइप पर है, जिसका अर्थ है कि यह उम्मीद this संदर्भ है कि एक स्ट्रिंग जहां के रूप में Array पर map विधि पहला तर्क और this संदर्भ वैश्विक वस्तु होने के रूप में वर्तमान सरणी आइटम प्रदान करता है।

+0

! मुझे पता था कि यह कुछ स्पष्ट होगा। मेरा दिमाग आज काम नहीं कर रहा है। धन्यवाद स्लेस। – alex

+2

तो यह क्यों काम नहीं करता है?'['ए', 'बी', 'सी']। नक्शा (String.prototype.trim.apply); '... और यह' map() 'संदर्भ के बाहर क्यों काम करता है? 'String.prototype.trim ('a')' (ध्यान दें कि यह वास्तव में * काम नहीं करता है * - एक खाली स्ट्रिंग देता है - लेकिन यह कोई त्रुटि नहीं फेंकता है।) – nrabinowitz

+5

@nrabinowitz: 'लागू करें' ' यह 'String.prototype.trim' तक बाध्य नहीं है - यह' अपरिभाषित 'या' शून्य 'या' विंडो' 'तक सीमित हो जाता है। (यही कारण है कि उन्होंने 'Function.bind() 'का आविष्कार किया।) – Ryan

25

ऐसा इसलिए है क्योंकि trim उचित this संदर्भ के साथ नहीं कहा जा रहा है। याद रखें कि this जेएस में गतिशील रूप से बाध्य है। आप trim को पारित करने के लिए ठीक से this बाध्य करने के लिए एक आवरण बनाने के लिए करना होगा:

[' a', ' b ', 'c'].map(function (str) { 
    return str.trim(); 
}); 
+2

उत्तर देने के लिए धन्यवाद। मुझे लगता है कि मैं jQuery की '$ .trim()' का उपयोग अक्सर कर रहा हूं। – alex

+0

बहुत अच्छा जवाब! :) – CoR

+0

यह इस तथ्य को छोड़कर लगभग सही है कि आप एक लूप में फ़ंक्शन बना रहे हैं। – Mrchief

30

क्या @Slace कहते हैं सही व्याख्या है। @ थॉमसएडिंग का जवाब भी काम करता है लेकिन इसमें एक भयानक अक्षमता है कि एक लूप के भीतर फ़ंक्शंस बना सकता है, जो not a good thing to do है।

करने का एक और तरीका है (reference here) होगा:

[' a', ' b ', 'c'].map(Function.prototype.call, String.prototype.trim); 
// gives ["a", "b", "c"] 

स्टैंडर्ड ब्राउज़र त्याग: यह जहाँ भी Function.prototype.call और String.prototype.trim काम करेंगे काम करेंगे और पुराने ब्राउज़र के लिए, आप आसानी से एक polyfill साथ trim स्थानापन्न कर सकते हैं इस तरह:

if(!String.prototype.trim) { 
    String.prototype.trim = function() { 
    return this.replace(/^\s+|\s+$/g,''); 
    }; 
} 

अद्यतन: Interstingly, जबकि इस क्रोम में सबसे तेजी से काम करता है, @ ThomasEding की विधि थोड़ा तेज IE10 में चलाता है और FF20 - http://jsperf.com/native-trim-vs-regex-trim-vs-mixed

+1

मुझे पूरा यकीन है कि @ थॉमसएडिग का जवाब एक से अधिक फ़ंक्शन नहीं बनाता है। मुझे लगता है कि 'नक्शा' फ़ंक्शन एक फ़ंक्शन संदर्भ स्वीकार करता है और फिर * इसे प्रति बार एक बार * कॉल करता है। फ़ंक्शन स्वयं एक बार बनाया गया है और फिर * 'map' फ़ंक्शन पर पास किया गया - बस 'मैप' के jQuery के कार्यान्वयन की तरह: http://james.padolsey.com/jquery/#v=1.7.2&fn=jQuery.map –

+0

हाँ ... मेरे परीक्षणों से, यह सच प्रतीत होता है। मैं सुधार करूँगा। – Mrchief

1

ES6 के साथ वाक्यविन्यास यह इस रूप में के रूप में आसान हो सकता है:

[' hello ', ' world'].map(str => str.trim()); 
बिल्कुल
+0

2017 में ऐसा करने का यह सबसे अच्छा तरीका है। देखते हैं कि 2018 में क्या होता है: डी –

संबंधित मुद्दे