ตัวtypeofดำเนินการไม่ได้ช่วยให้เราค้นหาประเภทของวัตถุจริงๆ
ฉันเห็นรหัสต่อไปนี้แล้ว:
Object.prototype.toString.apply(t)
คำถาม:
เป็นวิธีตรวจสอบประเภทของวัตถุที่ถูกต้องที่สุดหรือไม่?
ตัวtypeofดำเนินการไม่ได้ช่วยให้เราค้นหาประเภทของวัตถุจริงๆ
ฉันเห็นรหัสต่อไปนี้แล้ว:
Object.prototype.toString.apply(t)
คำถาม:
เป็นวิธีตรวจสอบประเภทของวัตถุที่ถูกต้องที่สุดหรือไม่?
คำตอบ:
ข้อกำหนดของ JavaScript ให้วิธีหนึ่งที่เหมาะสมในการกำหนดคลาสของอ็อบเจ็กต์:
Object.prototype.toString.call(t);
Object.prototype.toString.call(new FormData()) === "[object FormData]"ซึ่งจะเป็นจริง คุณยังสามารถใช้slice(8, -1)เพื่อส่งคืนFormDataแทน[object FormData]
Object.prototypeและ{}หรือไม่?
Object.prototype.toString.call(new MyCustomObject())กลับมา[object Object]ในขณะnew MyCustomObject() instanceOf MyCustomObject returns trueที่สิ่งที่ฉันต้องการ (Chrome 54.0.2840.99 ม.)
new MyCustomObject().constructor === MyCustomObject.
Object.prototype.toStringเป็นวิธีที่ดี แต่ประสิทธิภาพการทำงานที่เลวร้ายที่สุด
http://jsperf.com/check-js-type

ใช้typeofแก้ปัญหาพื้นฐานบางอย่าง (String, Number, Boolean ... ) และใช้Object.prototype.toStringแก้ปัญหาที่ซับซ้อน (เช่น Array, Date, RegExp)
และนี่คือทางออกของฉัน:
var type = (function(global) {
var cache = {};
return function(obj) {
var key;
return obj === null ? 'null' // null
: obj === global ? 'global' // window in browser or global in nodejs
: (key = typeof obj) !== 'object' ? key // basic: string, boolean, number, undefined, function
: obj.nodeType ? 'object' // DOM element
: cache[key = ({}).toString.call(obj)] // cached. date, regexp, error, object, array, math
|| (cache[key] = key.slice(8, -1).toLowerCase()); // get XXXX from [object XXXX], and cache it
};
}(this));
ใช้เป็น:
type(function(){}); // -> "function"
type([1, 2, 3]); // -> "array"
type(new Date()); // -> "date"
type({}); // -> "object"
typeฟังก์ชันของคุณดี แต่ดูว่าเป็นอย่างไรเมื่อเทียบกับtypeฟังก์ชันอื่น ๆ http://jsperf.com/code-type-test-a-test
คำตอบที่ยอมรับนั้นถูกต้อง แต่ฉันต้องการกำหนดยูทิลิตี้เล็ก ๆ น้อย ๆ นี้ในโครงการส่วนใหญ่ที่ฉันสร้าง
var types = {
'get': function(prop) {
return Object.prototype.toString.call(prop);
},
'null': '[object Null]',
'object': '[object Object]',
'array': '[object Array]',
'string': '[object String]',
'boolean': '[object Boolean]',
'number': '[object Number]',
'date': '[object Date]',
}
ใช้เช่นนี้:
if(types.get(prop) == types.number) {
}
หากคุณใช้เชิงมุมคุณสามารถฉีดได้อย่างหมดจด:
angular.constant('types', types);
var o = ...
var proto = Object.getPrototypeOf(o);
proto === SomeThing;
จับต้นแบบที่คุณคาดหวังว่าวัตถุจะมีจากนั้นเปรียบเทียบกับต้นแบบนั้น
ตัวอย่างเช่น
var o = "someString";
var proto = Object.getPrototypeOf(o);
proto === String.prototype; // true
o instanceof String; //trueไง?
"foo" instanceof Stringหยุดพัก
typeof(x)==='string'แทน
Object.getPrototypeOf(true)ล้มเหลวที่ผลตอบแทน(true).constructor Boolean
ฉันขอยืนยันว่าโซลูชันส่วนใหญ่ที่แสดงในที่นี้ประสบปัญหาจากการถูกวิศวกรมากเกินไป อาจเป็นวิธีที่ง่ายที่สุดในการตรวจสอบว่าค่าเป็นประเภทหรือไม่[object Object]คือการตรวจสอบ.constructorคุณสมบัติของมัน:
function isObject (a) { return a != null && a.constructor === Object; }
หรือสั้นกว่าด้วยฟังก์ชันลูกศร:
const isObject = a => a != null && a.constructor === Object;
a != nullส่วนหนึ่งเป็นสิ่งจำเป็นเพราะหนึ่งอาจจะผ่านnullหรือundefinedและคุณไม่สามารถดึงคุณสมบัติคอนสตรัคจากทั้งสองนี้
ใช้งานได้กับวัตถุใด ๆ ที่สร้างผ่าน:
Objectสร้าง{}คุณสมบัติที่เป็นระเบียบอีกประการหนึ่งของมันคือความสามารถในการรายงานที่ถูกต้องสำหรับคลาสแบบกำหนดเองที่ใช้ประโยชน์Symbol.toStringTagได้ ตัวอย่างเช่น:
class MimicObject {
get [Symbol.toStringTag]() {
return 'Object';
}
}
ปัญหาคือเมื่อเรียกObject.prototype.toStringอินสแตนซ์ของมันรายงานเท็จ[object Object]จะถูกส่งกลับ:
let fakeObj = new MimicObject();
Object.prototype.toString.call(fakeObj); // -> [object Object]
แต่การตรวจสอบกับตัวสร้างให้ผลลัพธ์ที่ถูกต้อง:
let fakeObj = new MimicObject();
fakeObj.constructor === Object; // -> false
วิธีที่ดีที่สุดในการค้นหาประเภท REAL ของวัตถุ (รวมถึงทั้ง Object ดั้งเดิมหรือชื่อ DataType (เช่น String, Date, Number, .. ฯลฯ ) และประเภท REAL ของวัตถุ (แม้แต่วัตถุที่กำหนดเอง) คือการจับ คุณสมบัติชื่อของคอนสตรัคเตอร์ของต้นแบบวัตถุ:
ประเภทเนทีฟ Ex1:
var string1 = "Test";
console.log(string1.__proto__.constructor.name);
แสดง:
String
Ex2:
var array1 = [];
console.log(array1.__proto__.constructor.name);
แสดง:
Array
คลาสที่กำหนดเอง:
function CustomClass(){
console.log("Custom Class Object Created!");
}
var custom1 = new CustomClass();
console.log(custom1.__proto__.constructor.name);
แสดง:
CustomClass
null undefined
คำถามเก่าที่ฉันรู้ คุณไม่จำเป็นต้องแปลง ดูฟังก์ชันนี้:
function getType( oObj )
{
if( typeof oObj === "object" )
{
return ( oObj === null )?'Null':
// Check if it is an alien object, for example created as {world:'hello'}
( typeof oObj.constructor !== "function" )?'Object':
// else return object name (string)
oObj.constructor.name;
}
// Test simple types (not constructed types)
return ( typeof oObj === "boolean")?'Boolean':
( typeof oObj === "number")?'Number':
( typeof oObj === "string")?'String':
( typeof oObj === "function")?'Function':false;
};
ตัวอย่าง:
function MyObject() {}; // Just for example
console.log( getType( new String( "hello ") )); // String
console.log( getType( new Function() ); // Function
console.log( getType( {} )); // Object
console.log( getType( [] )); // Array
console.log( getType( new MyObject() )); // MyObject
var bTest = false,
uAny, // Is undefined
fTest function() {};
// Non constructed standard types
console.log( getType( bTest )); // Boolean
console.log( getType( 1.00 )); // Number
console.log( getType( 2000 )); // Number
console.log( getType( 'hello' )); // String
console.log( getType( "hello" )); // String
console.log( getType( fTest )); // Function
console.log( getType( uAny )); // false, cannot produce
// a string
ต้นทุนต่ำและเรียบง่าย
falseหากวัตถุทดสอบเป็นnullหรือundefined
trueหรือfalse
falseมีค่า สิ่งนี้ช่วยตอบคำถามได้อย่างไร
ทางออกที่ดีที่สุดคือtoString(ตามที่ระบุไว้ข้างต้น):
function getRealObjectType(obj: {}): string {
return Object.prototype.toString.call(obj).match(/\[\w+ (\w+)\]/)[1].toLowerCase();
}
FAIR คำเตือน: toStringพิจารณาดังนั้นคุณต้องปกป้องในภายหลังด้วยNaNnumberNumber.isNaN(value)ดังนั้นคุณต้องปกป้องในภายหลังด้วย
วิธีแก้ปัญหาอื่น ๆ ที่แนะนำโดยใช้Object.getPrototypeOf ล้มเหลวด้วยnullและundefined
ฉันรวบรวมยูทิลิตี้ตรวจสอบประเภทเล็ก ๆ น้อย ๆ ที่ได้รับแรงบันดาลใจจากคำตอบที่ถูกต้องด้านบน:
thetypeof = function(name) {
let obj = {};
obj.object = 'object Object'
obj.array = 'object Array'
obj.string = 'object String'
obj.boolean = 'object Boolean'
obj.number = 'object Number'
obj.type = Object.prototype.toString.call(name).slice(1, -1)
obj.name = Object.prototype.toString.call(name).slice(8, -1)
obj.is = (ofType) => {
ofType = ofType.toLowerCase();
return (obj.type === obj[ofType])? true: false
}
obj.isnt = (ofType) => {
ofType = ofType.toLowerCase();
return (obj.type !== obj[ofType])? true: false
}
obj.error = (ofType) => {
throw new TypeError(`The type of ${name} is ${obj.name}: `
+`it should be of type ${ofType}`)
}
return obj;
};
ตัวอย่าง:
if (thetypeof(prop).isnt('String')) thetypeof(prop).error('String')
if (thetypeof(prop).is('Number')) // do something
nullหรือundefinedหรือtrueหรือfalse