Underscore: إرجاع _.isNumber (NaN) صحيحًا

تم إنشاؤها على ١٥ ديسمبر ٢٠١١  ·  38تعليقات  ·  مصدر: jashkenas/underscore

نظرًا لأن NaN تعني "ليس رقمًا" ، فيبدو أن الاختيار isNumber في هذه الحالة يجب أن يعرض القيمة false. ألاحظ من المناقشات الأخرى أن هذا في الواقع عن قصد. ربما يجب أن تعكس الوثائق هذه الحقيقة صراحة.

enhancement fixed

التعليق الأكثر فائدة

حسنًا ، لقد بدأت بمشكلة بسيطة. لدي مدخلات عبارة عن سلاسل وأرقام وربما NaN. لدي حل بسيط في JavaScript الأساسية باستخدام parseInt و isFinite لاختبار ما إذا كانت عملية التحليل ناجحة. بسيطة ولكنها ليست نظيفة تمامًا أو تصف هدفي. لذلك ، قررت استخدام مكتبة goto الرائعة تمامًا للقيام بهذا النوع من المهام. أجد دالة في الفحص الأولي تقول إنها تأخذ قيمة وتخبرك ما إذا كان رقمًا ، وهو ما أعتقد أنه ما أريده حسب تعريفي الشائع.

أولاً ، يمكنك أن ترى كيف ستساعد إضافة سطر إلى الوثائق مستخدمي المكتبة في الحصول على الوظيفة المناسبة للوظيفة في المرة الأولى؟ ثانيًا ، أسأل مرة أخرى عن مثال يكون فيه هذا مفيدًا.

يبدو أنك تعرف كل ما يمكن معرفته عن اللغة. لذا ، فبدلاً من إطلاق طلقة عمياء في الحلول المظلمة التي يمكن أن يقدمها لي أخي في الصف الثامن ، ربما سيكون من الرائع استخدام بعض من هذا الإتقان في تعليم بقيتنا عبر وثائق رائعة. شكرا لك على وقتك.

ال 38 كومينتر

أنت على حق ، إنه متعمد. ولا أعتقد أنه يجب ذكر ذلك صراحة. من المحتمل أن يعرف أي شخص سبق له العمل مع IEEE 754 أن NaN هو مجرد قيمة نقطة عائمة أخرى.

ذات صلة: مناقشة في # 321

وجهة نظري في السؤال هي أنه عندما أقوم بمهام ويب مشتركة ، تبدو الوظيفة المسماة isNumber طريقة جيدة للتحقق مما إذا كانت القيمة التي تم العثور عليها تجيب على تعريف المستخدم الشائع لـ "هل هذا رقم؟".

بالإضافة إلى ذلك ، يبدو لي أن قيمة NaN تم تقديمها في المقام الأول للمساعدة في تحديد القيم التي تكسر الحسابات. بروح المواصفات تبدو الإجابة الصحيحة عندما تسأل السؤال "هل هذا رقم؟" هو في الواقع أنه "ليس رقمًا". إذا كان بإمكانك تسمية مثال شائع حيث تريد أن تكون الإجابة صحيحة لهذا السؤال ، فسأصمت الآن :)

أنت تبحث عن isFinite ، والذي يجب أن يعرفه الأشخاص الذين يعرفون JS بالفعل.

حسنًا ، لقد بدأت بمشكلة بسيطة. لدي مدخلات عبارة عن سلاسل وأرقام وربما NaN. لدي حل بسيط في JavaScript الأساسية باستخدام parseInt و isFinite لاختبار ما إذا كانت عملية التحليل ناجحة. بسيطة ولكنها ليست نظيفة تمامًا أو تصف هدفي. لذلك ، قررت استخدام مكتبة goto الرائعة تمامًا للقيام بهذا النوع من المهام. أجد دالة في الفحص الأولي تقول إنها تأخذ قيمة وتخبرك ما إذا كان رقمًا ، وهو ما أعتقد أنه ما أريده حسب تعريفي الشائع.

أولاً ، يمكنك أن ترى كيف ستساعد إضافة سطر إلى الوثائق مستخدمي المكتبة في الحصول على الوظيفة المناسبة للوظيفة في المرة الأولى؟ ثانيًا ، أسأل مرة أخرى عن مثال يكون فيه هذا مفيدًا.

يبدو أنك تعرف كل ما يمكن معرفته عن اللغة. لذا ، فبدلاً من إطلاق طلقة عمياء في الحلول المظلمة التي يمكن أن يقدمها لي أخي في الصف الثامن ، ربما سيكون من الرائع استخدام بعض من هذا الإتقان في تعليم بقيتنا عبر وثائق رائعة. شكرا لك على وقتك.

أنا مهتم بما يعتقدهjashkenas . لا أقصد أن أبدو مهينًا أو متعاليًا. أعلم أنني أتيت هكذا في بعض الأحيان. أعتقد أنها حقيقة أنني أحاول توجيه المحادثة في اتجاه يُظهر المشكلة بشكل أفضل من خلال إعطاء هذه الإجابات البسيطة ورؤية كيف فشلوا في حل المشكلة في عينيك.

أولاً ، يمكنك أن ترى كيف ستساعد إضافة سطر إلى الوثائق مستخدمي المكتبة في الحصول على الوظيفة المناسبة للوظيفة في المرة الأولى؟

ربما بالتأكيد.

ثانيًا ، أسأل مرة أخرى عن مثال يكون فيه هذا مفيدًا.

اختبار [[Class]] == "الرقم"؟ يجب أن يكون ذلك واضحًا ، فهو يتطابق مع الأرقام. ربما ليست أعدادًا طبيعية أو أعدادًا صحيحة أو أرقامًا محدودة أو أرقامًا حقيقية أو أرقامًا منطقية أو أي مجموعة فرعية كنت تتوقعها ، لكنها بالتأكيد جميع الأرقام.

بعد كل ما قيل ، هناك أوقات يمكن أن تكون فيها إضافة الكثير من الزغب في الوثائق ضارة. لكنني لا أعتقد أن هذا هو واحد من تلك الأوقات. قد يكون هذا مفيدًا للمطورين الذين قد يكون لديهم ، في حالتهم الحالية ، تفسير متضارب للمفهوم المجرد للرقم. كما هو الحال في حالتك ، حيث قمت بالفعل بإنشاء نموذج عقلي للمجموعة التي تريد اختبارها ، ثم عثرت على وظيفة _ ظهرت_ لإجراء هذا الاختبار. +1 ، على الرغم من أنني ما زلت مهتمًا بما يعتقدهjashkenas .

نعم - ليس من الواضح على الإطلاق ما إذا كان _.isNumber سيعود true أو false عند تمرير NaN . أنا بالتأكيد لن أتذكر دون تجربته. تمت إضافة ملاحظة إلى الوثائق في الالتزام أعلاه. شكرا.

شكرا يا شباب. يسعدني معرفة أن شخصًا آخر قد لا يواجه نفس المشكلة.

يبدو هذا بالتأكيد كحالة حيث يجب أن تتفوق الدلالات على الحقائق التقنية. نعم ، قد يكون NaN رقمًا وفقًا لبعض المواصفات. لكن إذا سألت شيئًا السؤال "هل أنت رقم؟" وهي تقول "أنا لست رقمًا" ، إذًا يجب أن أصدقها. ليس رقمًا - NaN - في النهاية ليس رقمًا ... ويجب أن يُرجع isNumber خطأ.

وضع مسكتك في المستندات - بدلاً من إصلاح الأشياء لفهم البشر - يؤدي فقط إلى تقليل وقت الترميز والمزيد من الوقت للنظر في الوثائق التي تخدش رأسك.

هل يمكن إعادة النظر في هذا من فضلك؟

contentfree : NaN عضو في العوامات. كل رقم في JS هو عدد عشري. أعتقد أن هذا يجعل NaN مثل رقم ey كما يحصلون عليه. NaN لا يعني "أنا لست رقمًا". إنه التمثيل الرقمي للأرقام غير. أغلقت القضية في كتابي. استخدم isFinite إذا كنت تريد اختبار الأرقام التي ليست NaN / Infinity / -Infinity .

ليس للتغلب على حصان ميت ولكن ...

لماذا لا تفعل فقط
obj instanceOf Number

يبدو لي أنه إذا كانت هناك طريقة أكثر قابلية للقراءة للقيام بالإجراء الضروري الموجود بالفعل في مواصفات جافا سكريبت ، فسأقوم بذلك بهذه الطريقة بدون استخدام مكتبة بها مكتبة غير معروفة (ما لم أضيع وقتًا في التحقيق).

أنا أصوت أنه إذا لم نكن لنصلح هذا ليكون صحيحًا من الناحية اللغوية ، فيجب علينا فقط إزالة النفقات العامة والصداع غير المجدية من المكتبة.

عامل التشغيل instanceof سيعمل فقط مع الكائنات وليس العناصر الأولية: new Number(5) instanceof Number == true; 5 instanceof Number == false . كما أنه لن يعمل عبر الإطارات في المتصفحات. التحقق من [[Class]] عبر Object::toString مقبول بشكل عام ليكون أكثر طرق التحقق من النوع موثوقية في JavaScript.

+1 على جعل المكتبة أكثر فائدة وفي نفس الحالة تثقيف المستخدمين الجدد في JavaScript.

اقتراح:
_.isNumber (كائن ، [isFinite]) ؛

سيسمح ذلك بإضافة بسيطة إلى تطبيقك الحالي عند اكتشافك لهذه المشكلة أثناء تعلم أن isFinite ربما كان ما كنت تبحث عنه في المقام الأول.

2 ج

@ nickl- فكرة مثيرة للاهتمام ، ولكن ... لماذا لا تستخدم ببساطة isFinite في هذه الحالة؟

بدلاً من ذلك ، نظرًا لأن _.isNaN موجود بالفعل ، فمن المحتمل أن تتم إضافة _.isFinite للتماثل:

_.isFinite = function (value) {
  return value > -1 / 0 && value < 1 / 0;
};

تضمين التغريدة

المشكلة الوحيدة التي أتوقعها هي أن السلاسل ستمرر كـ "0x0" ، "0xF" ، "2" ، إلخ. لذا ، بغض النظر عن أي شيء ، يجب أن يتم دمجه مع _.isNumber أو ما يعادله:

_.isFinite = function (obj) {
  return obj > -1/0 && obj < 1/0 && _.isNumber(obj);
};

يمكن إزالة خمسة أحرف باستخدام val === + val لاختبار الأرقام:

_.isFinite = function (obj) {
  return obj > -1/0 && obj < 1/0 && obj === +obj;
};

octatone بالتأكيد ، أعتقد أن هذا أمر عادل ... من الناحية الفنية ، هذه السلاسل _are_ محدودة ، حيث يمكن استخدامها في المقارنات الرقمية (يجب على المترجم إجبارها على الأرقام) ، لكن اقتراحك أكثر اتساقًا مع وظائف التحقق من النوع السفلية الحالية.

ماذا عن _ ، isValidNumber الذي يتماشى مع _.isValidDate الموجود ولا يخلط بين الوسيطة isFinite؟

@ nickl-

NaN و Infinity _are_ أرقام صالحة. أعتقد أن تسمية هذه الوظيفة isValidNumber قد تربك الغرض منها أو تقصد إعادة تسمية isNumber إلى isValidNumber؟

NaN و Infinity _are_ أرقام صالحة. أعتقد أن تسمية هذه الوظيفة isValidNumber ستربك الغرض منها.

أنا موافق.

لم أقل إعادة تسمية ...

لقد فوجئت أيضًا بمعرفة أن _.isNumber(NaN) === true .

أعتقد أنني أميل إلى الاتفاق مع @ contentfree https://github.com/jashkenas/underscore/issues/406#issuecomment -4144992. في هندسة البرمجيات ، لدينا مبدأ لهذه الحالة المحددة: مبدأ أقل دهشة . ؛-)

وبعد رؤية الكثير من الناس في حيرة من أمرهم ، أعتقد أنه سيكون من المنطقي الحصول على الوظيفة للقيام بما يتوقعه البشر الذين ليسوا من ذوي النواة الصلبة عندما ينظرون إلى اسمها.

فقط بلدي الصغير 2 ¢… ™

_.isNaN محير أيضًا. في المستند:

ملاحظة: هذه ليست نفس الدالة الأصلية isNaN ، والتي ستعيد أيضًا صحيحًا للعديد من القيم غير الرقمية الأخرى ، مثل undefined.

بالمعنى الطبيعي ، undefined هو في الواقع ليس رقم A.

أصوت لصالح البناء الدلالي ، isNumber == Not a number لول. أعتقد ، إذا كنت بحاجة إلى الخوض في التفاصيل حول التحقق من قيم الفاصلة العائمة ، فهل تفعل ذلك بطريقة أخرى؟

أنا أصوت لصالح البناء الدلالي ،

الآن ، إنه رقم بمقدار [[Class]] تمامًا مثل -Infinity ، Infinity ، & Object(2) . إنها واحدة من تلك الأشياء التي يتعلمها المطورون ، مثل الوظائف هي كائنات أيضًا. من المحتمل أنك سترغب في إجراء نوع من التحقق من صحة رقمك وهو خارج نطاق هذه الطريقة. على سبيل المثال ، هل هو أكبر من -1 ، أو أقل من Math.pow(2,32) ، أو عدد صحيح. في حالات -Infinity أو Infinity أو NaN أستخدم _.isFinite كمدقق. وبالمثل لا يتم التحقق من صحة _.isDate إذا كان كائن التاريخ يمثل تاريخًا صالحًا.

ماذا عن تحديث التوثيق بـ "راجع أيضًا: isFinite" و "راجع أيضًا:" مقال طرق تعداد لتحديد ما إذا كان شيء ما قيمة رقمية يمكنك استخدامها بالفعل »"

michaelficarra أعلم أنه في المواصفات ، يعد NaN نوعًا رقميًا إلى حد كبير. لكن هل هذا ما يفكر فيه المبرمج عندما يسأل هل هذا رقم؟

ما يريد معظمنا معرفته ، في معظم الأحيان ، هل يمكنني استخدام هذا في العمليات الحسابية الأساسية. لذلك عليك أن تذهب هو رقم (x) && isFinite (x). وهذا جيد على ما أعتقد. لكنها مسكتك كبير بالنسبة للمبرمج الجديد ولا يقرأ جيدًا.

من وجهة نظر لغة إنجليزية بحتة ، ليس هناك أي رقم (NaN) يعود صحيحًا من اختبار يسمى isNumber لا معنى له على الإطلاق. ألن يتم تسمية هذا بشكل أفضل هو Numeric أو isNumericType؟

ليس لدي أدنى شك في أن هذا سيضيف أخطاء ويضيع ساعات عديدة ، على الأقل في المرة الأولى التي يواجه فيها الناس هذا.

لذلك عليك أن تذهب هو رقم (x) && isFinite (x).

لقد قمت مؤخرًا بمحاذاة تطبيق _.isFinite لمتابعة ES6 Number.isFinite .
يضمن أن تكون القيمة عددًا بدائيًا ومحدودة ويجب التعامل مع هذه الحالة الشائعة.

لا حاجة لتغيير سلوك _.isNumber الذي يتوافق مع طرق الاختيار [[Class]] .

من وجهة نظر لغة إنجليزية بحتة ، ليس هناك أي رقم (NaN) يعود صحيحًا من اختبار يسمى isNumber لا معنى له على الإطلاق. ألن يتم تسمية هذا بشكل أفضل هو Numeric أو isNumericType؟

انظر تعليقي حول التحقق ، _.isNumber ، و _.isDate .

jdalton أنت محق بشأن كون السلوك ثابتًا مع _.isDate. وأنتم يا رفاق تقومون بعمل رائع مع الشرطة السفلية ، لذلك أعتقد أن القرار يقع عليك حقًا.

ولكن يبدو الأمر بديهيًا للغاية أن الشيء الذي يسمى ليس رقمًا هو رقم.

@ Walms 100٪ موافقون. أعتقد في هذه الحالة ، يجب على المبرمج والحدس أن يبطلا "الصحة" المطلقة للبيان المعطى لـ NaN وهو رقمي تقنيًا.

ولكن يبدو الأمر بديهيًا للغاية أن الشيء الذي يسمى ليس رقمًا هو رقم.

في هذا السياق ، هل يعد الأمر بديهيًا أكثر من إرجاع _.isNumber true للكائنات الرقمية ، Object(2) التي هي من النوع object ؟

هذه طرق [[Class]] . ربما يحتاج ذلك إلى توضيح أكثر في الوثائق.

لقد اقترحت بالفعل بديلاً قابلاً للتطبيق وهو ببساطة جعل _.isFinite يتبع ES6 Number.isFinite . إذا كنت تريد is-number أساسيًا ، استخدم typeof x == 'number' . إذا كنت تريد بعض التحقق من أن القيمة ليست NaN أو Infinity أو -Infinity ، الكل [[Class]] من Number ، ثم _.isFinite هو السبيل للذهاب.

ابحث عن تسطير أسفل السطر للمساهمة للحصول على المزيد من طرق الأرقام الحبيبية الدقيقة. لديها _.isNumeric ، _.isInteger ، _.isZero ، _.isEven ، _.isOdd ، _.isFloat ، _.isNegative ، & _.isPositive .

jdalton أعتقد أن

لم أر في البداية أن _.isNumber تم إعطاؤه سياقًا من حقيقة أنه كان مسبوقًا بـ is ، مما يعني أنه كان فحصًا للنوع. مع هذا السياق ، فأنت محق تمامًا ، فلا معنى لـ _.isNumber لإرجاع خطأ لـ NaN.

ولكن بعد ذلك ، يبدو أن تسطير أسفل السطر للمساهمة و isFinite يكسر هذا السياق. كما يبدؤون ، فإنهم ينظرون إلى القيمة بدلاً من الكتابة. وهذا هو المكان الذي أعتقد أن الالتباس فيه أنه لا توجد طريقة واضحة لتحديد السياق من اسم الوظيفة.

قال كل هذا لا أرى أي طريقة لإصلاح هذا.

أعتقد أن المشكلة هنا هي أن هناك بعض الأشياء غير البديهية حول الأرقام. ومع ذلك ، فهم يتصرفون بطريقة متسقة. سيكون من الممكن جعل _.isNumber أكثر سهولة في هذه الحالة بجعله أقل اتساقًا ، مما يجعله في النهاية أقل سهولة في حالات أخرى.

فيما يلي بعض الأمثلة الملموسة:

# If you add two Numbers together you always get another Number back
# This function should always return true no matter what you pass it
closedUnderAddition = (a, b) -> !isNumber(a) || !isNumber(b) || isNumber(a + b)

closedUnderAddition(1,1) == true
closedUnderAddition(Number.MAX_INT,2**970) == true # false if isNumber checks finiteness

# If you divide two Numbers you always get another Number back
closedUnderDivision = (a, b) -> !isNumber(a) || !isNumber(b) || isNumber(a / b)

closedUnderDivision(1, 2) == true
closedUnderDivision(1, 0) == true # false if isNumber checks finiteness
closedUnderDivision(0, 0) == true # false if isNumber checks finiteness or NaN-ness

# Anything you cast to a Number is a Number
castsToNumber = (x) -> isNumber(Number(x))

castsToNumber(1) == true
castsToNumber(Infinity) == true # false if isNumber checks finiteness
castsToNumber("bees") == true # false if isNumber checks finiteness or NaN-ness
castsToNumber("3") == true

كما قال michaelficarra:

NaN لا تعني "أنا لست رقمًا". إنه التمثيل الرقمي للأرقام غير.

أو بعبارة أخرى ، هناك "أرقام" وأرقام. قد لا يكون NaN "رقمًا" ولكنه رقم مطلقًا جنبًا إلى جنب مع Infinity و -Infinity والأشياء السخيفة مثل -0. على الرغم من كونه بريًا وصوفيًا ، فإن تعريف الرقم محدد جيدًا ويتصرف باستمرار.

"الرقم" من ناحية أخرى هو مفهوم غير محدد بشكل سيئ ، اعتمادًا على من تتحدث إليه ، يمكن أن يتضمن أيًا مما سبق أو لا يتضمن أيًا مما سبق ، وربما سلاسل رقمية ، منطقية ، منتصف الليل وجميع أنواع الأشياء. هذا جيد ، لكن لن يكون هناك حل يلتزم بتعريف الجميع.

أعتقد لهذا السبب أن هذه مسألة توثيق بشكل أساسي.

هل توقف "الرقم" عن الظهور ككلمة لأي شخص آخر؟

نقاط جيدة ،sgentle. أنا أصوت للاتساق على الحدس ، لأن الأول مقياس موضوعي بينما لن نتفق جميعًا على ما هو بديهي (كما يوضح هذا الخيط).

فقط لا تعامل NaN على أنها "ليست رقمًا". NaN قيمة خاصة.

فقط لا تعامل NaN على أنها "ليست رقمًا". NaN قيمة خاصة.

نعم ولكن يسمى "ليس رقمًا".
بالنسبة لي هذا مثل هذا
var _false = "true" ؛
نعم ، يمكنك معرفة أن الخطأ صحيح ، لكنه محير بدون سبب وجيه.

Walms إنه اسم سيء ولكن هذا ليس خطأ JS. قد نلوم الرجل الذي أطلق عليها اسم "NaN". http://en.wikipedia.org/wiki/NaN

آرجو ، أتمنى أن يعيد _.isNumber(NaN) false ... بعض الخدوش الخطيرة للرأس هنا حتى أدركت أن هذا هو السبب.

if (isNaN(Number(value))) {
  alert('Number required.');
}

pspi متفق عليه. جعل _.isNumber() يتصرف بشكل صحيح بالمعنى _الدلالات_ يعني أنني لن أستخدمه أبدًا. ._isFinite() هو الوظيفة التي تعمل بالطريقة التي كنت أتوقعها.

وبالطبع ، بعد يوم واحد من نشر هذا ، اكتشفت أن _.isFinite('1') هو true ، على الرغم من أن الوسيطة ليست رقمًا.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات