Vacuousness
मैं किसी ऐसे फ़ंक्शन को परिभाषित करने या उसका उपयोग करने की कोशिश करने की अनुशंसा नहीं करता हूं जो गणना करता है कि क्या पूरी दुनिया में कोई भी मूल्य खाली है। "खाली" होने का वास्तव में क्या मतलब है? अगर मेरे पास है let human = { name: 'bob', stomach: 'empty' }, तो मुझे isEmpty(human)लौट जाना चाहिए true? अगर मेरे पास है let reg = new RegExp('');, तो मुझे isEmpty(reg)लौट जाना चाहिए true? किस बारे में isEmpty([ null, null, null, null ])- इस सूची में केवल शून्यता है, तो क्या सूची ही खाली है? मैं जावास्क्रिप्ट में कुछ नोट्स "रिक्वेस्टनेस" (जानबूझकर अस्पष्ट शब्द, पूर्व-मौजूदा संघों से बचने के लिए) पर आगे रखना चाहता हूं - और मैं यह तर्क देना चाहता हूं कि जावास्क्रिप्ट वैल्यूज में "रिक्तिपन" को कभी भी उदारता से नहीं निपटाया जाना चाहिए।
Truthiness / Falsiness
मूल्यों की "रिक्ति" का निर्धारण कैसे किया जाए, यह तय करने के लिए, हमें जावास्क्रिप्ट को इनबिल्ट करने की आवश्यकता है, निहित अर्थ "सत्य" या "मिथ्या" हैं। स्वाभाविक रूप से, nullऔर undefinedदोनों "झूठे" हैं। कम स्वाभाविक रूप से, संख्या 0(और कोई अन्य संख्या को छोड़कर NaN) भी "मिथ्या" है। कम से कम स्वाभाविक रूप से: ''falsy है, लेकिन []और {}(और new Set(), और new Map()) truthy कर रहे हैं - हालांकि वे सभी समान रूप से हलका लगते हैं!
अशक्त बनाम अप्रभावित
वहाँ भी कुछ के विषय में चर्चा है nullबनाम undefinedहम वास्तव में हमारे कार्यक्रमों में vacuousness व्यक्त करने के लिए दोनों की क्या ज़रूरत है? - मैं व्यक्तिगत रूप से कभी भी अक्षरों को यू, एन, डी, ई, एफ, आई, एन, ई, डी होने से बचाता हूं। मैं हमेशा null"रिक्ति" का संकेत देने के लिए उपयोग करता हूं । फिर, हालांकि, हमें जावास्क्रिप्ट की अंतर्निहित समझदारी के साथ कैसे nullऔर undefinedअलग होने की आवश्यकता है:
- गैर-मौजूद संपत्ति तक पहुँचने की कोशिश करता है
undefined
- किसी पैरामीटर को कॉल करते समय एक पैरामीटर को प्राप्त करने से उस पैरामीटर का परिणाम प्राप्त होता है
undefined:
let f = a => a;
console.log(f('hi'));
console.log(f());
- डिफ़ॉल्ट मान वाले पैरामीटर केवल दिए जाने पर डिफ़ॉल्ट प्राप्त करते हैं
undefined, नहीं null:
let f = (v='hello') => v;
console.log(f(null));
console.log(f(undefined));
गैर-सामान्य रिक्ति
मेरा मानना है कि सामान्य फैशन में कभी भी खालीपन से नहीं निपटना चाहिए। इसके बजाय हमें हमेशा यह निर्धारित करने से पहले अपने डेटा के बारे में अधिक जानकारी प्राप्त करने की कठोरता होनी चाहिए - मैं मुख्य रूप से यह जाँच कर रहा हूं कि मैं किस प्रकार के डेटा के साथ काम कर रहा हूं:
let isType = (value, Cls) => {
try {
return Object.getPrototypeOf(value).constructor === Cls;
} catch(err) {
return false;
}
};
ध्यान दें कि यह फ़ंक्शन बहुरूपता को अनदेखा करता है - यह valueएक प्रत्यक्ष उदाहरण होने की उम्मीद करता है Cls, न कि एक उपवर्ग का उदाहरण Cls। मैं instanceofदो मुख्य कारणों से बचता हूं :
([] instanceof Object) === true ("एक सरणी एक वस्तु है")
('' instanceof String) === false ("एक स्ट्रिंग एक स्ट्रिंग नहीं है")
ध्यान दें कि इस Object.getPrototypeOfतरह के एक मामले से बचने के लिए प्रयोग किया जाता है जैसे फ़ंक्शन अभी भी (झूठे), और (सही) के लिए सही ढंग से वापस आता है ।let v = { constructor: String };isTypeisType(v, String)isType(v, Object)
कुल मिलाकर, मैं isTypeइन युक्तियों के साथ इस फ़ंक्शन का उपयोग करने की सलाह देता हूं :
- अज्ञात प्रकार के कोड प्रसंस्करण मूल्यों की मात्रा कम करें। उदाहरण के लिए
let v = JSON.parse(someRawValue);, हमारा vचर अब अज्ञात प्रकार का है। जितनी जल्दी हो सके, हमें अपनी संभावनाओं को सीमित करना चाहिए। ऐसा करने का सबसे अच्छा तरीका एक विशेष प्रकार की आवश्यकता के द्वारा हो सकता है: जैसे if (!isType(v, Array)) throw new Error('Expected Array');- यह वास्तव में एक त्वरित और अभिव्यंजक तरीका है जिससे की सामान्य प्रकृति को हटाया जा सके vऔर यह सुनिश्चित हो कि यह हमेशा ए Array। कभी-कभी, हालांकि, हमें vकई प्रकार के होने की अनुमति देने की आवश्यकता होती है । उन मामलों में, हमें कोड के ब्लॉक बनाने चाहिए जहां vअब सामान्य नहीं है, जितनी जल्दी हो सके:
if (isType(v, String)) {
/* v isn't generic in this block - It's a String! */
} else if (isType(v, Number)) {
/* v isn't generic in this block - It's a Number! */
} else if (isType(v, Array)) {
/* v isn't generic in this block - it's an Array! */
} else {
throw new Error('Expected String, Number, or Array');
}
- सत्यापन के लिए हमेशा "श्वेतसूची" का उपयोग करें। यदि आपको एक मान की आवश्यकता है, जैसे, एक स्ट्रिंग, संख्या, या ऐरे, उन 3 "सफेद" संभावनाओं की जांच करें, और 3 में से कोई भी संतुष्ट नहीं होने पर एक त्रुटि फेंकें। हम "काला" संभावनाओं के लिए कि जाँच को देखने के लिए सक्षम होना चाहिए बहुत उपयोगी नहीं है: कहते हैं कि हम लिखने
if (v === null) throw new Error('Null value rejected');- यह सुनिश्चित करना है कि के लिए अच्छा है nullमूल्यों के माध्यम से यह कर नहीं है, लेकिन एक मूल्य अगर करता है इसके माध्यम से बनाने के लिए, हम अभी भी शायद ही जानते हैं इसके बारे में कुछ भी। एक मान vजो इस अशक्त-जांच से गुजरता है वह अभी भी बहुत सामान्य है - यह कुछ भी है लेकिनnull ! ब्लैकलिस्ट शायद ही जेनेरिक-नेस को दूर करते हैं।
जब तक एक मूल्य nullनहीं है , कभी भी "एक रिक्त मान" पर विचार न करें। इसके बजाय, "एक एक्स जो खाली है" पर विचार करें। अनिवार्य रूप से, कभी भी ऐसा करने पर विचार if (isEmpty(val)) { /* ... */ }न करें - चाहे वह isEmptyफ़ंक्शन कैसे लागू किया गया हो (मैं जानना नहीं चाहता ...), यह सार्थक नहीं है! और यह बहुत सामान्य है! रिक्तता की गणना केवल ज्ञान के valप्रकार के साथ की जानी चाहिए । इस तरह दिखना चाहिए:
- "एक तार, जिसमें कोई वर्ण नहीं है":
if (isType(val, String) && val.length === 0) ...
- "एक वस्तु, 0 सहारा के साथ":
if (isType(val, Object) && Object.entries(val).length === 0) ...
- "एक संख्या, समान या शून्य से कम":
if (isType(val, Number) && val <= 0) ...
"ए अर्रे, विथ नो आइटम": if (isType(val, Array) && val.length === 0) ...
एकमात्र अपवाद तब nullहोता है जब कुछ कार्यक्षमता को इंगित करने के लिए उपयोग किया जाता है। इस मामले में यह कहना सार्थक है: "एक रिक्त मान":if (val === null) ...