জেএস অবজেক্টের ধরণটি পরীক্ষা করার সবচেয়ে সঠিক উপায়?


137

typeofঅপারেটর সত্যিই একটি বস্তুর বাস্তব টাইপ এটি আমাদেরকে সাহায্য করে না।

আমি ইতিমধ্যে নিম্নলিখিত কোডটি দেখেছি:

Object.prototype.toString.apply(t)  

প্রশ্ন:

এটি কি বস্তুর প্রকারের পরীক্ষা করার সবচেয়ে সঠিক উপায়?


2
এই নিবন্ধটি একবার দেখুন: javascriptweblog.wordpress.com/2011/08/08/…
জেমস এলার্ডিস

4
: এই পোস্টে তাকান stackoverflow.com/questions/332422/...
isJustMe


3
সর্বাধিক সঠিক উপায় হ'ল ... ধরণটি পরীক্ষা না করা। আপনার প্রকারের দরকার কেন?
hugomg

উত্তর:


190

জাভাস্ক্রিপ্ট স্পেসিফিকেশন কোনও বস্তুর শ্রেণি নির্ধারণ করার জন্য ঠিক একটি সঠিক উপায় দেয়:

Object.prototype.toString.call(t);

http://bonsaiden.github.com/JavaScript-Garden/#types


5
আপনি যদি কোনও নির্দিষ্ট ধরণের সন্ধান করে থাকেন তবে আপনি সম্ভবত এর লাইনের সাথে কিছু করতে চাইবেন: Object.prototype.toString.call(new FormData()) === "[object FormData]"যা সত্য হবে। আপনি পরিবর্তে slice(8, -1)ফিরে আসতে ব্যবহার করতে পারেনFormData[object FormData]
ক্রিস মেরিসিক

4
ব্যবহার Object.prototypeএবং এর মধ্যে কোন পার্থক্য আছে {}?
গেমফ্রি

3
হয়তো এই বছর ধরে পরিবর্তন হয়েছে, কিন্তু Object.prototype.toString.call(new MyCustomObject())আয় [object Object]যেহেতু new MyCustomObject() instanceOf MyCustomObject returns trueযা কি আমি (যেমন, Chrome 54.0.2840.99 মিটার) চেয়েছিলাম
মাসলো

@ ম্যাসলো, আমি যে সমস্যাটি নিয়ে এসেছি একই বিষয়ে আমি দৌড়ে এসেছি। অনলাইনে কিছু ডকুমেন্টেশন সন্ধানের পরে, আমি ব্যবহার করে শেষ করেছি new MyCustomObject().constructor === MyCustomObject
solstice333

3
এটি প্রশ্ন উত্থাপন করে, কেন তারা কোনও সুবিধাজনক পদ্ধতিতে এই কোডটি জড়িত করেনি, বা কোনও অতিরিক্ত অপারেটরকে এটি সংকলনের অনুমতি দেয়নি। আমি জানি আপনি কেবল মেসেঞ্জার, তবে খুব স্পষ্টভাবেই তা ভয়াবহ।
অ্যান্ড্রু এস

60

এটি Object.prototype.toStringএকটি ভাল উপায়, তবে এর অভিনয়টি সবচেয়ে খারাপ।

http://jsperf.com/check-js-type

জেএস টাইপ পারফরম্যান্স চেক করুন

ব্যবহার করুন typeofকিছু মৌলিক সমস্যা (স্ট্রিং, সংখ্যা, বুলিয়ান ...) এবং ব্যবহারের সমাধানের জন্য Object.prototype.toStringকিছু জটিল (মত বিন্যাস, তারিখ, 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"

Jscreen এ পরীক্ষাটি সঠিক নয়। সেই পরীক্ষাগুলি সমান নয় (একই জিনিসের জন্য পরীক্ষা করা)। উদাহরণস্বরূপ, টাইপফ [] "" বস্তু "প্রদান করে, টাইপফ} {" অবজেক্ট "প্রদান করে, যদিও একটি বস্তু অ্যারে এবং অন্যটি একটি অবজেক্ট অবজেক্ট। সেই পরীক্ষার সাথে আরও অনেক সমস্যা আছে ... জেএসপুর্গের দিকে তাকানোর সময় সতর্কতা অবলম্বন করুন যে পরীক্ষাগুলি অ্যাপলগুলিকে আপেলের সাথে তুলনা করছে।
kmatheny

আপনার typeফাংশনটি ভাল, তবে দেখুন অন্য কিছু typeফাংশনের সাথে এটি কীভাবে তুলনা করে। http://jsperf.com/code-type-test-a-test
প্রোগো 12

18
এই কর্মক্ষমতা মেট্রিকগুলি কিছু সাধারণ জ্ঞান সহকারে মেতে উঠতে হবে। অবশ্যই, প্রোটোটাইপ.টো স্ট্রিং প্রস্থের ক্রম অনুসারে অন্যের তুলনায় ধীরে ধীরে, তবে জিনিসগুলির দুর্দান্ত স্কিমে এটি প্রতি কলে গড়ে কয়েক শতাধিক ন্যানোসেকেন্ড লাগে । এই কলটি খুব ঘন ঘন সম্পাদিত হওয়া সমালোচনামূলক পথে ব্যবহার করা না হলে এটি সম্ভবত নির্দোষ। আমি বরং কোডের চেয়ে সোজা ফরওয়ার্ড কোড চাই যা একটি মাইক্রোসেকেন্ড দ্রুত শেষ করে।
ডেভিড

({}).toString.call(obj)Object.prototype.toString jsperf.com/object-check-test77 এর
timaschew

সুন্দর সমাধান। আমি আপনার ফাংশনটি আমার লিবিতে ধার করি :)
ডং

19

গৃহীত উত্তরটি সঠিক, তবে আমি বেশিরভাগ প্রকল্পগুলিতে এই সামান্য উপযোগটি সংজ্ঞায়িত করতে চাই।

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);

11
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বিরতি কারণ
রায়নস

ঠিক আছে, সুতরাং "টাইপফ (ও) === 'অবজেক্ট' &&O উদাহরণস্বরূপ সামোবজেক্ট"। স্ট্রিংগুলির জন্য এটি পরীক্ষা করা সহজ। আপনি যা পরীক্ষা করছেন তা আগে থেকেই জেনে রাখার প্রাথমিক সমস্যাটি সমাধান না করে অতিরিক্ত কাজের মতো মনে হচ্ছে।
জেমি ট্রওয়ারজি

দুঃখিত যে কোড স্নিপেটটি কোনও অর্থহীন নয় তবে আমি মনে করি আপনি কী বলতে চাইছেন তা আমার জানা আছে, আপনি যদি স্ট্রিংয়ের জন্য পরীক্ষা করে নিচ্ছেন তবে তার typeof(x)==='string'পরিবর্তে ব্যবহার করুন।
জেমি ট্রেওয়ার্গি

BTW, Object.getPrototypeOf(true)যেখানে ব্যর্থ (true).constructorআয় Boolean
কেটসফোগ

5

আমি যুক্তি দিয়েছি যে এখানে প্রদর্শিত বেশিরভাগ সমাধান অতিরিক্ত প্রকৌশলী হওয়ার কারণে ভুগছে। সম্ভবত কোনও মান টাইপ রয়েছে [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

4

রিয়েল প্রকারের কোনও অবজেক্ট (দেশীয় অবজেক্ট বা ডাটা টাইপের নাম (যেমন স্ট্রিং, তারিখ, নম্বর, .. ইত্যাদি) সহ এবং রিয়েল প্রকারের (এমনকি কাস্টমগুলি সহ) সন্ধান করার সর্বোত্তম উপায়; প্রোটোটাইপ নির্মাণকারীর নাম সম্পত্তি:

নেটিভ টাইপ এক্স 1:

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
জুলিয়ান নাইট

2

পুরানো প্রশ্ন আমি জানি। আপনার এটি রূপান্তর করার দরকার নেই। এই ফাংশনটি দেখুন:

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। এটি কীভাবে প্রশ্নের উত্তর দেয়?
জুলিয়ান নাইট

1
@ জুলিয়ানকনাইট পরিবর্তন দেখুন, আপনি কি চান? আপনি যদি ফলাফল হিসাবে অপরিজ্ঞাত বা "অপরিজ্ঞাত" পছন্দ করেন তবে আপনি যদি চান তবে শেষের মিথ্যাটি প্রতিস্থাপন করতে পারেন।
কোডবিট

0

উপরের সঠিক উত্তরগুলি দ্বারা অনুপ্রাণিত হয়ে আমি একটি সামান্য ধরণের চেক ইউটিলিটি একসাথে রেখেছি:

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
জুলিয়ান নাইট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.