لماذا يُرجع مثيل الخطأ لبعض القيم الحرفية؟
-
03-07-2019 - |
سؤال
"foo" instanceof String //=> false
"foo" instanceof Object //=> false
true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false
// the tests against Object really don't make sense
تتطابق القيم الحرفية للمصفوفة مع القيم الحرفية للكائنات...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
لماذا لا كل منهم؟أو لماذا لا يفعلون ذلك جميعًا لا?
وما هو مثالهم إذن؟
إنه نفس الشيء في FF3 وIE7 وOpera وChrome.لذلك، على الأقل أنها متسقة.
غاب عن عدد قليل.
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
المحلول
والبدائيون هي نوع مختلف من نوع من الكائنات التي تم إنشاؤها من داخل جافا سكريبت. من موزيلا API مستندات :
var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)
لا أستطيع أن أجد أي وسيلة لبناء أنواع بدائية مع رمز، وربما غير ممكن. وربما هذا هو السبب الذي جعل الناس استخدام typeof "foo" === "string"
بدلا من instanceof
.
وطريقة سهلة لتذكر أشياء من هذا القبيل يسأل نفسك "أنا أتساءل ماذا سيكون عاقل وسهلة لتعلم"؟ مهما كان الجواب، جافا سكريبت يفعل الشيء الآخر.
نصائح أخرى
وأنا استخدم:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
ولأن في جافا سكريبت السلاسل يمكن أن يكون الحرفية أو الكائنات.
في جافا سكريبت كل ما هو كائن (أو على الأقل أن تعامل على أنها كائن)، باستثناء <لأ href = "https://developer.mozilla.org/en-US/docs/Glossary/Primitive" يختلط = " noreferrer "> البدائيون (والقيم المنطقية، لاغية والأرقام وسلاسل وundefined
قيمة (ورمزها في ES6)):
console.log(typeof true); // boolean
console.log(typeof 0); // number
console.log(typeof ""); // string
console.log(typeof undefined); // undefined
console.log(typeof null); // object
console.log(typeof []); // object
console.log(typeof {}); // object
console.log(typeof function () {}); // function
وكما ترون الأشياء، المصفوفات وnull
القيمة هي كل الأشياء تعتبر (null
هو إشارة إلى كائن الذي لا وجود له). وظائف متميزة لأنها نوع خاص من للاستدعاء م> التحف. ومع ذلك فهي لا تزال تعترض.
ومن ناحية أخرى true
الحرفية، 0
، ""
وundefined
ليست الكائنات. وهي القيم البدائية في جافا سكريبت. ومع ذلك لديها القيم المنطقية والأرقام وسلاسل أيضا منشئات Boolean
، Number
وString
على التوالي التي التفاف البدائيون كل منها لتوفير وظائف وأضاف:
console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0)); // object
console.log(typeof new String("")); // object
وكما ترون عندما يتم تغليف القيم البدائية داخل Boolean
، Number
وString
الصانعين على التوالي عندما تصبح الكائنات. المشغل instanceof
يعمل فقط للكائنات (والذي هو السبب في أنه يعود false
القيم البدائية):
console.log(true instanceof Boolean); // false
console.log(0 instanceof Number); // false
console.log("" instanceof String); // false
console.log(new Boolean(true) instanceof Boolean); // true
console.log(new Number(0) instanceof Number); // true
console.log(new String("") instanceof String); // true
وكما ترون كل من typeof
وinstanceof
غير كافية لاختبار ما إذا كانت القيمة منطقية، عددا أو سلسلة - typeof
يعمل فقط من أجل القيم المنطقية البدائية والأرقام وسلاسل. وinstanceof
لا يعمل من أجل القيم المنطقية البدائية والأرقام والسلاسل.
ولحسن الحظ هناك حل بسيط لهذه المشكلة. تطبيق الافتراضي toString
(أي كما انها محددة أصلا على Object.prototype.toString
) إرجاع الممتلكات [[Class]]
الداخلية لكلا القيم البدائية والأجسام:
function classOf(value) {
return Object.prototype.toString.call(value);
}
console.log(classOf(true)); // [object Boolean]
console.log(classOf(0)); // [object Number]
console.log(classOf("")); // [object String]
console.log(classOf(new Boolean(true))); // [object Boolean]
console.log(classOf(new Number(0))); // [object Number]
console.log(classOf(new String(""))); // [object String]
والخاصية [[Class]]
الداخلية للقيمة هو أكثر فائدة بكثير من typeof
القيمة. يمكننا استخدام Object.prototype.toString
لخلق بنفسك نسختنا (أكثر فائدة) المشغل typeof
كما يلي:
function typeOf(value) {
return Object.prototype.toString.call(value).slice(8, -1);
}
console.log(typeOf(true)); // Boolean
console.log(typeOf(0)); // Number
console.log(typeOf("")); // String
console.log(typeOf(new Boolean(true))); // Boolean
console.log(typeOf(new Number(0))); // Number
console.log(typeOf(new String(""))); // String
والأمل ساعدت هذه المادة. لمعرفة المزيد حول الاختلافات بين الأوليات والأشياء ملفوفة قراءة بلوق وظيفة التالية: <لأ href = "http://javascriptweblog.wordpress.com/2010/09/27/the-secret-life-of-javascript-primitives/ "يختلط =" noreferrer "عنوان =" الحياة السرية للجافا سكريبت البدائيون | تفعيل جافا، جافا سكريبت ... "> الحياة السرية للجافا سكريبت البدائيون
ويمكنك استخدام خاصية المنشئ:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
typeof(text) === 'string' || text instanceof String;
يمكنك استخدام هذا، وسوف يعمل في كلتا الحالتين
var text="foo";
// نوع سوف يعملString text= new String("foo");
// مثيل سوف يعمل
وأعتقد أنني قد حان حتى مع حل ناجع:
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
ويعرف هذا في ECMAScript مواصفات القسم 7.3.19 الخطوة 3 : If Type(O) is not Object, return false.
في كلمة أخرى، إذا كان Obj
في Obj instanceof Callable
ليس كائن، instanceof
وقصيرة الدائرة لfalse
مباشرة.
https://www.npmjs.com/package/typeof
وإرجاع سلسلة تمثيل instanceof
(اسم الصانعين)
function instanceOf(object) {
var type = typeof object
if (type === 'undefined') {
return 'undefined'
}
if (object) {
type = object.constructor.name
} else if (type === 'object') {
type = Object.prototype.toString.call(object).slice(8, -1)
}
return type.toLowerCase()
}
instanceOf(false) // "boolean"
instanceOf(new Promise(() => {})) // "promise"
instanceOf(null) // "null"
instanceOf(undefined) // "undefined"
instanceOf(1) // "number"
instanceOf(() => {}) // "function"
instanceOf([]) // "array"
بالنسبة لي الارتباك الناجم عن
"str".__proto__ // #1
=> String
لذا "str" istanceof String
يجب أن يعود true
لأن كيفية عمل istanceof على النحو التالي:
"str".__proto__ == String.prototype // #2
=> true
نتائج التعبير #1 و #2 يتعارضون مع بعضهم البعض، لذلك ينبغي أن يكون هناك واحد منهم على خطأ.
رقم 1 خطأ
وأعلم أن ذلك سببه __proto__
هي خاصية غير قياسية، لذا استخدم الخاصية القياسية:Object.getPrototypeOf
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
الآن ليس هناك خلط بين التعبير #2 و #3
وأو يمكنك جعل مجرد وظيفة الخاصة بك مثل ذلك:
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
والاستعمال:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
وهذه يجب أن تعود صحيح على حد سواء.