জাভাস্ক্রিপ্ট ভেরিয়েবলের ধরণ পাওয়ার জন্য আরও ভাল উপায়?


260

জেএসের চেয়ে ভেরিয়েবলের ধরণ পাওয়ার আরও ভাল উপায় কি আছে typeof? এটি করার সময় এটি কার্যকর হয়:

> typeof 1
"number"
> typeof "hello"
"string"

আপনি চেষ্টা করার সময় কিন্তু এটি অকেজো:

> typeof [1,2]
"object"
>r = new RegExp(/./)
/./
> typeof r
"function"

আমি জানি instanceof, তবে এর জন্য আপনাকে আগে টাইপটি জানতে হবে।

> [1,2] instanceof Array
true
> r instanceof RegExp
true

একটি ভাল উপায় আছে কি?


1
এফওয়াইআই, typeof new RegExp(/./); // "function"ক্রোমে সমস্যাটি ক্রোম 14 এ স্থির হয়েছে বলে মনে হয়
ব্যবহারকারী 113716


সতর্কতা: আপনি যদি আপনার জেএসটি মিনিমাইটিং করছেন এবং আপনি 'কাস্টম অবজেক্টস' যেমন টাইপস্ক্রিপ্ট ক্লাস ব্যবহার করছেন তবে নীচের কয়েকটি উত্তর আপনাকে nপ্রত্যাশিত মূল নামের পরিবর্তে অস্পষ্ট ফাংশনটির নাম প্রদান করবে । উদাহরণস্বরূপ constructor.nameআপনাকে nপ্রত্যাশিত পুরো নামটির পরিবর্তে দিতে পারে
সাইমন_উইভার

উত্তর:


221

অ্যাঙ্গাস ক্রল সম্প্রতি এই সম্পর্কে একটি আকর্ষণীয় ব্লগ পোস্ট লিখেছেন -

http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

তিনি বিভিন্ন পদ্ধতির উপকারিতা এবং বিপরীতে গিয়ে একটি নতুন পদ্ধতি 'টু টাইপ' সংজ্ঞায়িত করেন -

var toType = function(obj) {
  return ({}).toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}

3
আকর্ষণীয় পার্শ্ব নোট এখানে - এটি সম্ভবত "হোস্ট" অবজেক্টটি ফাংশনে প্রেরণ করা যেতে পারে break ActiveXObjectউদাহরণস্বরূপ ইন্টারনেট এক্সপ্লোরার উদাহরণস্বরূপ।
অ্যান্ডি ই

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

1
আপনার টাইপ নামকরণ থাকে: অথবা: _ এই Regex প্রসারিত হতে পারেmatch(/\s([a-z,_,:,A-Z]+)/)
Masi

6
রেজেক্সেও এই জাতীয় জিনিসের জন্য নম্বর অন্তর্ভুক্ত করতে হবে Uint8Array। পরিবর্তে, আরও সাধারণ match(/\s([^\]]+)/)যা কিছু হ্যান্ডেল করা উচিত তা বিবেচনা করুন ।
লিলি ফিনলে

2
আমি \wপরিবর্তে অপারেটর শব্দটি ব্যবহার করার পরামর্শ দেব ...
কায়সার

51

আপনি ব্যবহার করার চেষ্টা করতে পারেন constructor.name

[].constructor.name
new RegExp().constructor.name

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

একটি বিকল্প ব্যবহার করা হয় Object.prototype.toString.call

Object.prototype.toString.call([])
Object.prototype.toString.call(/./)

10
nameECMAScript- এর একটি এক্সটেনশন এবং সমস্ত ব্রাউজারে কাজ করবে না।
অ্যান্ডি ই

16
জাভাস্ক্রিপ্টে যা কিছু করা হয়েছে তা কোনওভাবেই খারাপ বলে সন্দেহের নিশ্চয়তা দেওয়ার কারণে আপ-ভোট দেওয়া হয়েছে।
liljoshu

1
ইভিল: আপনি যদি নিজের কোডটি খাটো করে নিচ্ছেন তবে আপনার প্রত্যাশা করা অবজেক্টের নামের পরিবর্তে constructor.nameএমন কিছু nহতে পারে। সুতরাং এটির জন্য সতর্কতা অবলম্বন করুন - বিশেষত যদি আপনি কেবলমাত্র উত্পাদনকে ছোট করে দেখান।
সাইমন_উইভার

nullএবং undefinedদুর্ভাগ্যক্রমে কোনও কনস্ট্রাক্টর নেই।
অ্যান্ড্রু গ্রিম

জাভাস্ক্রিপ্ট নিজেই খারাপ। এবং নির্বোধ। এই প্রশ্নের কোন ভাল উত্তর নেই তা হ'ল এর জীবন্ত প্রমাণ।
ব্যবহারকারী 2173353

38

যুক্তিসঙ্গতভাবে ভাল টাইপ ক্যাপচার ফাংশন হ'ল YUI3 দ্বারা ব্যবহৃত :

var TYPES = {
    'undefined'        : 'undefined',
    'number'           : 'number',
    'boolean'          : 'boolean',
    'string'           : 'string',
    '[object Function]': 'function',
    '[object RegExp]'  : 'regexp',
    '[object Array]'   : 'array',
    '[object Date]'    : 'date',
    '[object Error]'   : 'error'
},
TOSTRING = Object.prototype.toString;

function type(o) {
    return TYPES[typeof o] || TYPES[TOSTRING.call(o)] || (o ? 'object' : 'null');
};

এটি জাভাস্ক্রিপ্ট দ্বারা সরবরাহিত অনেক আদিমাকে ক্যাপচার করে তবে আপনি সর্বদা TYPESঅবজেক্টটি সংশোধন করে আরও কিছু যোগ করতে পারেন । নোট করুন যে typeof HTMLElementCollectionসাফারিতে প্রতিবেদন করা হবে function, তবে টাইপ করুন (এইচটিএমএলিমেন্ট সংগ্রহ) ফিরে আসবেobject


31

আপনি নিম্নলিখিত ফাংশন দরকারী খুঁজে পেতে পারেন:

function typeOf(obj) {
  return {}.toString.call(obj).split(' ')[1].slice(0, -1).toLowerCase();
}

অথবা ES7 এ (আরও উন্নতি হলে মন্তব্য করুন)

function typeOf(obj) {
  const { toString } = Object.prototype;
  const stringified = obj::toString();
  const type = stringified.split(' ')[1].slice(0, -1);

  return type.toLowerCase();
}

ফলাফল:

typeOf(); //undefined
typeOf(null); //null
typeOf(NaN); //number
typeOf(5); //number
typeOf({}); //object
typeOf([]); //array
typeOf(''); //string
typeOf(function () {}); //function
typeOf(/a/) //regexp
typeOf(new Date()) //date
typeOf(new Error) //error
typeOf(Promise.resolve()) //promise
typeOf(function *() {}) //generatorfunction
typeOf(new WeakMap()) //weakmap
typeOf(new Map()) //map

ধন্যবাদ আমাকে জোহরিস: আমাকে অবহিত করার জন্য: ত্রুটি, প্রতিশ্রুতি, জেনারেটর ফাংশন


এর জন্য ধন্যবাদ. এটি তারিখের অবজেক্টগুলির জন্যও কাজ করে:typeOf(new Date())
জেমস ইরউইন

আহ, আমি সে সম্পর্কে ভুলে গেছি - ধন্যবাদ, এটি এখন অন্তর্ভুক্ত।
ভিক্স

1
এবংtypeOf(Promise.resolve())//promise typeOf(function *() {})//generatorfunction
জনহিসি

টাইপস্ক্রিপ্টে কাজ করার জন্য আমি এই উত্তরটি পেতে পারি না। ত্রুটি দেয়:[ts] Cannot redeclare block-scoped variable 'toString'
ডৌলডিকে

টাইপস্ক্রিপ্ট সম্পর্কে নিশ্চিত নয়। আপনি কি ES7 সংস্করণ ব্যবহার করে দেখেছেন? টসস্ট্রিং স্পষ্টভাবে ঘোষণা না করা কারণ হতে পারে?
ভিক্স

15

এছাড়াও আমরা আইপিআর 101 থেকে কিছুটা উদাহরণ পরিবর্তন করতে পারি

Object.prototype.toType = function() {
  return ({}).toString.call(this).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}

এবং কল হিসাবে

"aaa".toType(); // 'string'

6
বাচ্চাদের মনে রাখবেন, জাভাস্ক্রিপ্টের ভিত্তি অবজেক্টগুলিকে সামঞ্জস্য করা সামঞ্জস্যতা এবং অন্যান্য উদ্ভট সমস্যার কারণ হতে পারে। লাইব্রেরি এবং বৃহত প্রকল্প উভয় ক্ষেত্রে এটিকে স্বল্প পরিমাণে ব্যবহার করার চেষ্টা করুন!
আলেকজান্ডার ক্র্যাগস

9

এক লাইন ফাংশন:

function type(obj) {
    return Object.prototype.toString.call(obj).replace(/^\[object (.+)\]$/,"$1").toLowerCase()
}

এই হিসাবে একই ফলাফল দিতে jQuery.type()


3

আপনি Object.prototype.toStringযে কোনও বস্তুর জন্য আবেদন করতে পারেন :

var toString = Object.prototype.toString;

console.log(toString.call([]));
//-> [object Array]

console.log(toString.call(/reg/g));
//-> [object RegExp]

console.log(toString.call({}));
//-> [object Object]

এটি IE বাদে সমস্ত ব্রাউজারগুলিতে ভাল কাজ করে - অন্য উইন্ডো থেকে প্রাপ্ত কোনও চলকটিতে এটি কল করার সময় এটি কেবল থুথু ফেলবে [object Object]


1
@ শিওন আমি আই আই এর বিরুদ্ধে ঘৃণা কিছুটা বেশি বলে মনে করি। আইই 9 এর পূর্বসূরীদের তুলনায় অনেক ভাল ব্রাউজার।
আইলিন

4
@pessimopoppotamus কিন্তু যারা তাদের ব্রাউজারটি আইই 9 তে আপডেট করবেন তারা আইই ব্যবহার করেন না।
অ্যালেক্স টারপিন

1
আইই 9 সঠিক দিকের এক ধাপ, IE 10 দেখতে বেশ সুন্দর দেখাচ্ছে। ঘটনাক্রমে, আমি যে বাগটি উল্লেখ করেছি তা আইই 9 তে একটি রিগ্রেশন ছিল - তারা এটি আইই 8 তে স্থির করেছে
অ্যান্ডি ই

3

আমার 2 ¢! সত্যিই, উত্তরগুলির দীর্ঘ তালিকা থাকা সত্ত্বেও আমি এটিকে এখানে ফেলে দেওয়ার কারণগুলির একটি অংশ হ'ল আরও কিছু all in oneধরণের সমাধান সরবরাহ করা এবং কীভাবে আরও যুক্ত করার জন্য এটি প্রসারিত করা যায় সে সম্পর্কে ভবিষ্যতে কিছুটা ফিড ফিরে পাওয়া real types

নিম্নলিখিত সমাধান হিসাবে, পূর্বোক্ত হিসাবে, আমি এখানে পাওয়া বেশ কয়েকটি সমাধান একত্রিত করেছি, পাশাপাশি যদি উপলব্ধ থাকে তবে jQuery সংজ্ঞায়িত অবজেক্টের মান ফেরত দেওয়ার জন্য একটি সংশোধন করেছি । আমি দেশীয় অবজেক্ট প্রোটোটাইপটিতেও এই পদ্ধতিটি যুক্ত করি। আমি জানি যে এটি প্রায়শই নিষিদ্ধ, কারণ এটি অন্যান্য অন্যান্য এক্সটেনশনে হস্তক্ষেপ করতে পারে, তবে আমি তা ছেড়ে চলেছি । যদি আপনি এটি করার এই পদ্ধতিটি পছন্দ না করেন তবে কেবল বেস ফাংশনটি আপনার পছন্দ মতো অনুলিপি করুন এবং পাস করার জন্য একটি আর্গুমেন্ট প্যারামিটারের সাথে সমস্ত ভেরিয়েবল প্রতিস্থাপন করুন (যেমন আর্গুমেন্ট [0])।jQueryuser bewarethis

;(function() {  //  Object.realType
    function realType(toLower) {
        var r = typeof this;
        try {
            if (window.hasOwnProperty('jQuery') && this.constructor && this.constructor == jQuery) r = 'jQuery';
            else r = this.constructor && this.constructor.name ? this.constructor.name : Object.prototype.toString.call(this).slice(8, -1);
        }
        catch(e) { if (this['toString']) r = this.toString().slice(8, -1); }
        return !toLower ? r : r.toLowerCase();
    }
    Object['defineProperty'] && !Object.prototype.hasOwnProperty('realType')
        ? Object.defineProperty(Object.prototype, 'realType', { value: realType }) : Object.prototype['realType'] = realType;
})();

তারপরে সহজেই, সহজে যেমন ব্যবহার করুন:

obj.realType()  //  would return 'Object'
obj.realType(true)  //  would return 'object'

দ্রষ্টব্য: এখানে 1 টি আর্গুমেন্ট পাসযোগ্য। যদি বুল হয় true, তবে রিটার্নটি সর্বদা লোয়ারকেসে থাকবে

আরও উদাহরণ:

true.realType();                            //  "Boolean"
var a = 4; a.realType();                    //  "Number"
$('div:first').realType();                   // "jQuery"
document.createElement('div').realType()    //  "HTMLDivElement"

যদি আপনার কাছে এটি সহায়ক হতে পারে তবে যেমন অন্য কোনও লাইব্রেরি (মু, প্রোটো, ইউই, দোজো, ইত্যাদি ...) দিয়ে যখন কোনও বস্তু তৈরি করা হয়েছিল তখন সংজ্ঞায়িত করার জন্য দয়া করে এটিকে মন্তব্য করতে বা সম্পাদনা করতে দ্বিধা বোধ করবেন এবং আরও চালিয়ে যেতে থাকুন সঠিক এবং নির্ভুল বা GitHubআমি এর জন্য তৈরি করাতে রোল কর এবং আমাকে জানাতে। আপনি সেখানে সিডিএন মিনিট ফাইলের একটি দ্রুত লিঙ্কও খুঁজে পাবেন।


2
function getType(obj) {
    if(obj && obj.constructor && obj.constructor.name) {
        return obj.constructor.name;
    }
    return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
}

আমার প্রাথমিক পরীক্ষায়, এটি বেশ ভালভাবে কাজ করছে। প্রথম কেসটি "নতুন" দিয়ে তৈরি যে কোনও বস্তুর নাম মুদ্রণ করবে এবং ২ য় ক্ষেত্রে অন্য কিছু ধরা উচিত catch

আমি ব্যবহার করছি (8, -1)কারণ আমি ধরে নিচ্ছি যে ফলাফলটি সর্বদা শুরু হতে চলেছে [objectএবং শেষ হবে ]তবে আমি নিশ্চিত না যে প্রতিটি দৃশ্যে এটি সত্য।


2

আমি এখানে সর্বাধিক সর্বজনীন সমাধান অনুমান করি - প্রথমে যাচাই করা undefinedএবং nullতারপরে কেবল কল করা constructor.name.toLowerCase()

const getType = v =>
  v === undefined
    ? 'undefined'
    : v === null
      ? 'null'
      : v.constructor.name.toLowerCase();




console.log(getType(undefined)); // 'undefined'
console.log(getType(null)); // 'null'
console.log(getType('')); // 'string'
console.log(getType([])); // 'array'
console.log(getType({})); // 'object'
console.log(getType(new Set())); // `set'
console.log(getType(Promise.resolve())); // `promise'
console.log(getType(new Map())); // `map'

আমি যতদূর জানি - .constructor.nameসর্বদা স্ট্রিংয়ের মান থাকে। অপরিজ্ঞাত / নাল জন্য আমাদের ফাংশন দ্বারা ফিরে উপযুক্ত স্ট্রিং আছে।
আর্সেনোইচ

ধন্যবাদ - আমার মন্তব্য মুছে ফেলছে…
বার্গি

যেহেতু constructorএকটি উত্তরাধিকারসূত্রে প্রাপ্ত সম্পত্তি, তাই এটি তৈরি করা সামগ্রীর জন্য বিরতি Object.create(null)। ঠিক করার মতো যথেষ্ট সহজ, তবে এটিকে কী বলব? "[বস্তু নাল]"?
traktor53

0

typeof কন্ডিশনটি ভেরিয়েবল টাইপ চেক করতে ব্যবহৃত হয়, যদি আপনি যদি ভেরিয়েবল টাইপ চেক করেন তবে-অন্য অবস্থায় যেমন eg

if(typeof Varaible_Name "undefined")
{

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