जांचें कि क्या कोई चर फ़ंक्शन प्रकार का है


903

मान लीजिए मेरे पास कोई चर है, जिसे निम्नानुसार परिभाषित किया गया है:

var a = function() {/* Statements */};

मैं एक फ़ंक्शन चाहता हूं जो यह जांचता है कि चर का प्रकार फ़ंक्शन-लाइक है या नहीं। अर्थात :

function foo(v) {if (v is function type?) {/* do something */}};
foo(a);

यदि चर ऊपर बताए गए तरीके से aहै, तो मैं कैसे जांच सकता हूं Function?


जवाबों:


380

यकीन है कि अंडरस्कोर का तरीका अधिक कुशल है, लेकिन जांच करने का सबसे अच्छा तरीका है, जब दक्षता कोई समस्या नहीं है, तो अंडरपार्क के पेज @Paul रोजानिया द्वारा लिंक पर लिखा गया है।

अंडरस्कोर से प्रेरित होकर, अंतिम कार्य समारोह इस प्रकार है:

function isFunction(functionToCheck) {
 return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}

1
ऐसा कोई व्यक्ति हो सकता है जिसने इस मामले पर अधिक गहन शोध किया हो, लेकिन सरल "परिणाम सत्यापन" के साथ jsperf के संशोधन 4 के परिणामों पर एक नज़र हैisFunctionAअन्य तरीकों की तुलना में कार्यान्वयन अंतर दिखाता है।
जोएल पुर

24
साथ अद्यतन प्रदर्शन परीक्षणों यह लग रहा है वहाँ एक विशाल गति आपके ब्राउज़र पर निर्भर करता है अंतर नहीं है की तरह। Chrome में typeof(obj) === 'function'अब तक का सबसे तेज़ प्रतीत होता है; हालाँकि, फ़ायरफ़ॉक्स obj instanceof Functionमें स्पष्ट विजेता है।
जस्टिन वॉर्केन्टिन

7
भाग के बारे में: टाइपोफ़ का उपयोग केवल जाँच के लिए किया जाना चाहिए कि क्या चर या गुण अपरिभाषित हैं। पर javascript.info/tutorial/type-detection में typeof का एक अच्छा उपयोग अनुभाग और एक निम्नलिखित लेखक राज्यों, उस मामले बिल्कुल विपरीत है
कोनराड Madej

11
एलेक्स, मैं उत्सुक हूं कि आप क्यों कहते हैं कि टाइपो केवल अपरिभाषित की जांच करने के लिए यूटेट होना चाहिए। यह नाम बताता है कि इसका उद्देश्य कुछ के प्रकार की जांच करना है, न कि यह मौजूद है कि क्या है। क्या तकनीकी समस्याएं या समस्याएं हैं जो टाइप चेकिंग करने के लिए इसका उपयोग करते समय उत्पन्न हो सकती हैं, या क्या यह एक प्राथमिकता है? यदि कैवियट हैं तो उन्हें सूचीबद्ध करना अच्छा होगा ताकि अन्य उन पर ट्रिपिंग से बच सकें।
19 अगस्त को jinglesthula

14
अनुचित रूप से
अधूरा

1710
if (typeof v === "function") {
    // do something
}

44
वैसे ही जैसे कुछ चीजें के लिए बाहर घड़ी typeof Object, typeof Dateऔर typeof Stringहै, जो सभी वापसी 'function'भी।
डेव वार्ड

358
@ क्या, मुझे यकीन नहीं है कि समस्या क्या है क्योंकि वे कार्य हैं।
मैथ्यू क्रुमले

6
क्या अंतर है if (v instanceOf Function)?
mquandalle

10
@ mquandalle कोई बड़ा अंतर नहीं है, सिवाय इसके instanceofकि आप किसी अन्य दस्तावेज़ (एक iframe, शायद) से आए फ़ंक्शन की जाँच कर रहे हैं, तो काम नहीं करेगा। प्रदर्शन भिन्न होता है।
rvighne

8
स्वीकृत जवाब के विपरीत यह async फ़ंक्शंस के लिए भी काम करता है। एक के लिए asyncfunctionToCheck, getType.toString.call(functionToCheck)==='[object AsyncFunction]'जहां के रूप मेंtypeof asyncfunctionToCheck === 'function'
TDreama

132

Underscore.js एक अधिक विस्तृत लेकिन अत्यधिक प्रदर्शन करने वाले परीक्षण का उपयोग करता है:

_.isFunction = function(obj) {
  return !!(obj && obj.constructor && obj.call && obj.apply);
};

देखें: http://jsperf.com/alternative-isfunction-implementations

संपादित करें: अपडेट किए गए परीक्षण बताते हैं कि टाइपोफ़ तेज़ हो सकता है, http://jsperf.com/alternative-isfunction-implementations/4 देखें


क्या इस दृष्टिकोण का उपयोग करने का कोई विशेष कारण है typof?
sv_in

1
अधिकांश ब्राउज़रों में अंडरस्कोर का संस्करण बहुत तेज है। देखें: jsperf.com/alternative-isfunction-implementations
पॉल

13
मुझे यकीन है कि अंडरस्कोर पसंद है, सरल लेकिन शक्तिशाली। उस ने कहा, शायद यह ध्यान देने योग्य है कि इस कार्यान्वयन को उन विशेषताओं के साथ किसी वस्तु द्वारा खराब किया जा सकता है।

3
@PaRRosania ने आज से पहले इन प्रदर्शन परीक्षणों को ठोकर मारी, और उन्हें संशोधन 4 के साथ सत्यापन और अधिक परीक्षण डेटा के साथ अपडेट किया - कृपया ब्राउज़र परीक्षण कवरेज बढ़ाने के लिए इसे चलाएं। यह प्रति सेकंड के संचालन में धीमा है (कई परीक्षणों के कारण), लेकिन यह एक कार्यान्वयन अंतर भी दिखाता है (आपके जावास्क्रिप्ट कंसोल और पुनः लोड पृष्ठ खोलें, लॉग त्रुटि संदेश हो सकता है)। नोट: संशोधन 3 जोड़ा गया isFunctionD (केवल के आधार पर typeof == "function") - और यह अंडरस्कोर के "फास्ट" संस्करण की तुलना में बहुत तेज लगता है ।
जोएल पुर

6
यह उत्तर अब थोड़ा भ्रामक है, क्योंकि अंडरस्कोर। जेएस अब संशोधन 12 पर है , न कि उपर्युक्त संशोधन 4, इसके वैकल्पिक isFunction()कार्यान्वयन के परीक्षण के । वर्तमान में यह कुछ बहुत करीब का उपयोग करता है जो कि डंडियन ने सुझाया था।
जोनाथन यूनिस

112

कई तरीके हैं इसलिए मैं उन सभी को संक्षेप में बताऊंगा

  1. सबसे अच्छा तरीका है:
    function foo (v) {if (v इंस्टोफ फंक्शन) {/ * कुछ करें * /}};
    
    
    अधिकांश परफ़ॉर्मर (कोई स्ट्रिंग तुलना नहीं) और सुरुचिपूर्ण समाधान - इंस्टोऑफ़ ऑपरेटर को बहुत लंबे समय तक ब्राउज़रों में समर्थित किया गया है, इसलिए चिंता न करें - यह IE 6 में काम करेगा।
  2. अगला सबसे अच्छा तरीका है:
    function foo (v) {if (टाइपोफ़ v === "फंक्शन") {/ * कुछ करें * /}};
    
    
    इसका नुकसान typeofयह है कि यह मौन विफलता के लिए अतिसंवेदनशील है, बुरा है, इसलिए यदि आपके पास एक टाइपो है (उदाहरण के लिए "वित्त") - तो इस मामले में `अगर 'सिर्फ झूठे वापस आ जाएगा और आपको पता नहीं चलेगा कि बाद में आपको कोई त्रुटि हुई है तुम्हारा कोड
  3. अगला सबसे अच्छा तरीका है:
    फंक्शन फंक्शन (functionToCheck) {
        var getType = {};
        functionToCheck और& getType.toString.call (functionToCheck) === '[ऑब्जेक्ट फंक्शन]' लौटाएं;
    }
    
    
    इसका समाधान # 1 या # 2 से अधिक नहीं है, लेकिन यह बहुत कम पठनीय है। इसका एक उन्नत संस्करण है
    फंक्शन फंक्शन (x) {
        वापसी object.prototype.toString.call (x) == '[ऑब्जेक्ट फ़ंक्शन]';
    }
    
    
    लेकिन अभी भी समाधान # 1 की तुलना में बहुत कम अर्थ है

10
एक अलग फ्रेम संदर्भ में पारित एक समारोह के मामले में पहला समाधान विफल रहता है। उदाहरण के लिए, एक iframe से top.Function !== Function। सुनिश्चित करने के लिए, दूसरे का उपयोग करें (डिबग के दौरान "फ़ंक्शन" के किसी भी गलत वर्तनी को सही किया जाएगा, उम्मीद है)।
मैक्सआर्ट

टाइपो के बारे में अपनी बात के बारे में: जिस भी कोड में यह टाइपो है, वह जल्दी से विफल होने की संभावना है / टाइपो पर आधारित किसी भी अन्य कीड़े से अधिक स्पष्ट नहीं है। टाइपोफ === "फ़ंक्शन" सबसे साफ समाधान है। इसके अतिरिक्त आपका "सर्वश्रेष्ठ" समाधान जहां आप उपयोग करते हैं, instanceofवह कई ग्लोबल्स को ध्यान में नहीं रखता है, जैसे कि फ़्रेम में एक चेक, और झूठे नकारात्मक को वापस कर सकता है।
ब्रिंकिम

84

jQuery (संस्करण 3.3 के बाद से हटा दिया गया है) संदर्भ

$.isFunction(functionName);

AngularJS संदर्भ

angular.isFunction(value);

लोदश संदर्भ

_.isFunction(value);

अंडरस्कोर संदर्भ

_.isFunction(object); 

N4.js v4.0.0 संदर्भ के बाद से हटाए गए

var util = require('util');
util.isFunction(object);

56

@grandecomplex: आपके समाधान के लिए निष्पक्षता की एक उचित मात्रा है। इस तरह लिखा जाए तो यह बहुत स्पष्ट हो जाएगा:

function isFunction(x) {
  return Object.prototype.toString.call(x) == '[object Function]';
}

Object.prototype.toString.call अन्य जावास्क्रिप्ट प्रकार में आपकी रुचि के लिए उपयोगी है। आप यहां तक ​​कि अशक्त या अपरिभाषित के खिलाफ जांच कर सकते हैं जो इसे बहुत शक्तिशाली बनाता है।
जेसन फोगलिया


35

instanceofऑपरेटर की कोशिश करें : ऐसा लगता है कि सभी कार्य Functionवर्ग से विरासत में मिले हैं :

// Test data
var f1 = function () { alert("test"); }
var o1 = { Name: "Object_1" };
F_est = function () { };
var o2 = new F_est();

// Results
alert(f1 instanceof Function); // true
alert(o1 instanceof Function); // false
alert(o2 instanceof Function); // false

19

अधिक ब्राउज़र समर्थन के साथ कुछ और इसमें async फ़ंक्शंस शामिल हो सकते हैं:

const isFunction = value => value && (Object.prototype.toString.call(value) === "[object Function]" || "function" === typeof value || value instanceof Function);

और फिर इसका परीक्षण करें जैसे:

isFunction(isFunction); //true
isFunction(function(){}); //true
isFunction(()=> {}); //true
isFunction(()=> {return 1}); //true
isFunction(async function asyncFunction(){}); //true
isFunction(Array); //true
isFunction(Date); //true
isFunction(Object); //true
isFunction(Number); //true
isFunction(String); //true
isFunction(Symbol); //true
isFunction({}); //false
isFunction([]); //false
isFunction("function"); //false
isFunction(true); //false
isFunction(1); //false
isFunction("Alireza Dezfoolian"); //false

11

एक और सरल तरीका:

var fn = function () {}
if (fn.constructor === Function) {
  // true
} else {
  // false
}

1
अगर fn को अपरिभाषित किया जाएगा तो यह एक त्रुटि फेंक देगा
कामिल ऑर्कोवॉस्की

fn && fn.constructor === Functionइस बारे में कैसा है?
यारोस्लाव मेल्निचुक

9

उन लोगों के लिए जो कार्यात्मक शैली में रुचि रखते हैं, या मेटा प्रोग्रामिंग (जैसे टाइप चेकिंग) में उपयोग करने के लिए अधिक अभिव्यंजक दृष्टिकोण की तलाश करते हैं, ऐसे कार्य को पूरा करने के लिए रामा पुस्तकालय देखना दिलचस्प हो सकता है ।

अगले कोड में केवल शुद्ध और पॉइंटफ़्री फ़ंक्शन शामिल हैं:

const R = require('ramda');

const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);

const equalsSyncFunction = isPrototypeEquals(() => {});

const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);

ES2017 के अनुसार, asyncफ़ंक्शन उपलब्ध हैं, इसलिए हम उनके खिलाफ भी जांच कर सकते हैं:

const equalsAsyncFunction = isPrototypeEquals(async () => {});

const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);

और फिर उन्हें एक साथ संयोजित करें:

const isFunction = R.either(isSyncFunction, isAsyncFunction);

बेशक, समारोह के खिलाफ रक्षा की जानी चाहिए nullऔर undefinedमूल्यों, तो यह "सुरक्षित" बनाने के लिए:

const safeIsFunction = R.unless(R.isNil, isFunction);

और, पूरा करने के लिए स्निपेट:

const R = require('ramda');

const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);

const equalsSyncFunction = isPrototypeEquals(() => {});
const equalsAsyncFunction = isPrototypeEquals(async () => {});

const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);
const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);

const isFunction = R.either(isSyncFunction, isAsyncFunction);

const safeIsFunction = R.unless(R.isNil, isFunction);

// ---

console.log(safeIsFunction( function () {} ));
console.log(safeIsFunction( () => {} ));
console.log(safeIsFunction( (async () => {}) ));
console.log(safeIsFunction( new class {} ));
console.log(safeIsFunction( {} ));
console.log(safeIsFunction( [] ));
console.log(safeIsFunction( 'a' ));
console.log(safeIsFunction( 1 ));
console.log(safeIsFunction( null ));
console.log(safeIsFunction( undefined ));

हालाँकि, ध्यान दें कि उच्च-स्तरीय कार्यों के व्यापक उपयोग के कारण यह समाधान अन्य उपलब्ध विकल्पों की तुलना में कम प्रदर्शन दिखा सकता है।


7

यदि आप Lodash का उपयोग करते हैं तो आप इसे _.isFunction के साथ कर सकते हैं ।

_.isFunction(function(){});
// => true

_.isFunction(/abc/);
// => false

_.isFunction(true);
// => false

_.isFunction(null);
// => false

trueयदि मान एक फ़ंक्शन है, तो यह विधि वापस आती है false


4

मैंने पाया कि जब IE8 में स्थानीय ब्राउज़र कार्यों का परीक्षण, का उपयोग कर toString, instanceofऔर typeofकाम नहीं किया। यहाँ एक विधि है जो IE8 में ठीक काम करती है (जहाँ तक मुझे पता है):

function isFn(f){
    return !!(f && f.call && f.apply);
}
//Returns true in IE7/8
isFn(document.getElementById);

वैकल्पिक रूप से, आप मूल कार्यों के लिए जाँच कर सकते हैं:

"getElementById" in document

हालांकि, मैंने कहीं पढ़ा है कि यह हमेशा IE7 और नीचे काम नहीं करेगा।


4

नीचे मेरे लिए भी काम करने लगता है (परीक्षण से node.js):

var isFunction = function(o) {
     return Function.prototype.isPrototypeOf(o);
};

console.log(isFunction(function(){})); // true
console.log(isFunction({})); // false

4

मुझे लगता है कि आप फंक्शन प्रोटोटाइप पर एक ध्वज को परिभाषित कर सकते हैं और जांच कर सकते हैं कि क्या उदाहरण आपको विरासत में मिला है

एक ध्वज को परिभाषित करें:

Function.prototype.isFunction = true; 

और फिर जांचें कि क्या यह मौजूद है

var foo = function(){};
foo.isFunction; // will return true

नकारात्मक पक्ष यह है कि एक और प्रोटोटाइप एक ही ध्वज को परिभाषित कर सकता है और फिर यह बेकार है, लेकिन यदि आप शामिल मॉड्यूल पर पूर्ण नियंत्रण रखते हैं तो यह सबसे आसान तरीका है


अगर foo अपरिभाषित है, तो यह त्रुटि के साथ विफल हो जाएगा। यह उल्लेख नहीं करना कि आप मूल प्रोटोटाइप को संशोधित करते हैं जो पूरी तरह से गलत है।
कामिल ऑरचैकोव्स्की

3

नोड v0.11 के बाद से आप मानक उपयोग फ़ंक्शन का उपयोग कर सकते हैं:

var util = require('util');
util.isFunction('foo');

2
use.isFunction को हटा दिया गया है
कीहर्स

2

आपको js में typeOfऑपरेटर का उपयोग करना चाहिए ।

var a=function(){
    alert("fun a");
}
alert(typeof a);// alerts "function"

0

पिछले कुछ उत्तरों के अनुसार समाधान टाइपोफ़ का उपयोग करना है। NodeJs में निम्नलिखित कोड स्निपेट है,

    function startx() {
      console.log("startx function called.");
    }

 var fct= {};
 fct["/startx"] = startx;

if (typeof fct[/startx] === 'function') { //check if function then execute it
    fct[/startx]();
  }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.