फ़ंक्शन मापदंडों के लिए सेट प्रकार?


161

क्या एक जावास्क्रिप्ट फ़ंक्शन को यह बताने का एक तरीका है कि एक निश्चित पैरामीटर एक निश्चित प्रकार का है?

ऐसा कुछ करने में सक्षम होना सही होगा:

function myFunction(Date myDate, String myString)
{
    //do stuff
}

धन्यवाद!

अद्यतन : इसका उत्तर होना एक शानदार "नहीं" है, अगर मुझे myDateएक तारीख के रूप में माना जाना चाहिए (इस पर तारीख कार्यों को कॉल करने के लिए), मुझे इसे फ़ंक्शन के अंदर एक तिथि के रूप में डालना होगा या नया चर सेट करना होगा इसके लिए दिनांक लिखें?


1
बिलिन और सामान्य अर्थों में नहीं। आप इसे स्वयं कर सकते हैं, हाथ से, लेकिन फिर यह निर्भर करता है कि आप "एक निश्चित प्रकार" को कैसे परिभाषित करते हैं
hugomg

2
जावास्क्रिप्ट में भी कोई कक्षाएं नहीं हैं, इसलिए कोई भी नहीं है Date, केवल object
छुटकारा


@ माँ, यह एक वर्ग नहीं है। Dateएक समारोह है। JavaScript कीवर्ड के बारे में और जानने के लिए stackoverflow.com/questions/1646698/… पर एक नज़र डालें new। इसके अलावा, चूंकि कोई कक्षाएं नहीं हैं, इसलिए कोई कास्टिंग नहीं है। आप बस अपने इच्छित कार्यों को कॉल कर सकते हैं। यदि ऑब्जेक्ट उनके पास है, तो वे चलेंगे, अन्यथा आपको एक त्रुटि मिलेगी।
छुटकारा

2
यह एक पुराना है लेकिन किसी ने भी किसी प्रकार का उल्लेख नहीं किया है
किट

जवाबों:


180

नहीं, जावास्क्रिप्ट एक वैधानिक रूप से टाइप की गई भाषा नहीं है। कभी-कभी आपको अपने फ़ंक्शन बॉडी में कई प्रकार के मापदंडों को मैन्युअल रूप से जांचना पड़ सकता है।


180
आशीर्वाद और एक अभिशाप।
जेफरी स्वीनी

40
@JeffreySweeney न तो PHP स्टेटिक टाइप की गई है। लेकिन आपके पास php में hinting टाइप करने का विकल्प है। क्या आपने कभी बड़े नोडज बैकएंड एप्लिकेशन को देखा है? वास्तव में, प्रत्येक फ़ंक्शन में तर्क होते हैं, और आपके पास कोई तर्क नहीं है कि प्रत्येक तर्क क्या है। हम हजारों तर्कों के बारे में बात कर रहे हैं और पढ़ते समय, आपको पूरे कोड और कॉलर के पूरे कोड और उसके कॉलर आदि को पढ़ना होगा, आशीर्वाद? आप निश्चित रूप से मजाक कर रहे होंगे।
टॉस्कन

14
अलग कोई है जो कोई सुविधा प्रकार के लिए अनुमति देता है एक आशीर्वाद मैं टाइपप्रति बाहर बिंदु करना चाह सकते हैं इशारा कॉल को कोसने से: typescriptlang.org मूल रूप से EM6 + प्रकार हिंट
Toskan

23
@JeffreySweeney यह एक आशीर्वाद नहीं है। यह कैंसर है।
रोबो रोबोक

1
@ टॉस्कन मैं यह नहीं कहूंगा कि यह आशीर्वाद नहीं है। मैं अब चार साल से जावास्क्रिप्ट का उपयोग कर रहा हूं, और यह सिर्फ कुछ भाषाओं की प्रकृति है। प्रोग्रामिंग भाषाओं के सेट चाहिए दुर्बलता से दृढ़ता से एक ही तरह से यह उच्च स्तर के लिए निम्न स्तर से लेकर चाहिए लिखे गए टाइप किया से लेकर। इसके अतिरिक्त, इसमें सहायता के लिए जावास्क्रिप्ट instanceofऔर typeofकीवर्ड प्रदान करता है । यद्यपि यह अधिक कोड लेता है, हो सकता है कि यह डेवलपर के लिए जावास्क्रिप्ट को चुनने के लिए भाषा के रूप में ऐसी चीज़ के लिए हो जो काफी हद तक प्रकारों पर निर्भर करता है। विशाल नोडज बैकएंड अनुप्रयोगों के लिए के रूप में? मुझे लगता है कि यह सामान्य ज्ञान होना चाहिए।
मार्विन

81

स्वयं इसे जावास्क्रिप्ट में नहीं बल्कि Google बंद करने वाले कंपाइलर के उन्नत मोड का उपयोग करके आप ऐसा कर सकते हैं:

/**
 * @param {Date} myDate The date
 * @param {string} myString The string
 */
function myFunction(myDate, myString)
{
    //do stuff
}

Http://code.google.com/closure/compiler/docs/js-for-compiler.html देखें


1
यह एक्लिप्स जावास्क्रिप्ट एडिटर - आउटलाइन व्यू और कोड कंप्लीशन के साथ भी काम करता है । जबकि foo( /*MyType*/ param )यहाँ वर्णित तरीका भी काम करता है: stackoverflow.com/a/31420719/1915920
एंड्रियास डिट्रीच

मुझे एहसास है कि यह सवाल कितना पुराना है, लेकिन मैं यह बताना चाहता हूं कि यह इंटेलीज में सम्मानित है। यहाँ बहुत ही कम जवाब मिला।
ChettDM

67

जब आप जावास्क्रिप्ट को भाषा के प्रकारों के बारे में सूचित नहीं कर सकते हैं, तो आप अपने आईडीई को उनके बारे में सूचित कर सकते हैं, इसलिए आपको बहुत अधिक उपयोगी स्वतः पूर्णता मिलती है।

यहाँ दो तरीके हैं कि:

  1. उपयोग JSDoc , टिप्पणी में जावा स्क्रिप्ट कोड का दस्तावेजीकरण के लिए एक प्रणाली। विशेष रूप से, आपको @paramनिर्देश की आवश्यकता होगी :

    /**
     * @param {Date} myDate - The date
     * @param {string} myString - The string
     */
    function myFunction(myDate, myString) {
      // ...
    }

    आप कस्टम प्रकार को परिभाषित करने और @paramनिर्देशों में उन को निर्दिष्ट करने के लिए JSDoc का उपयोग भी कर सकते हैं , लेकिन ध्यान दें कि JSDoc किसी भी प्रकार की जाँच नहीं करेगा; यह केवल एक प्रलेखन उपकरण है। JSDoc में परिभाषित प्रकारों की जाँच करने के लिए, टाइपस्क्रिप्ट में देखें , जो JSDoc टैग को पार्स कर सकता है ।

  2. में पैरामीटर से पहले टाइप सही निर्दिष्ट करके hinting प्रकार का उपयोग करें
    /* comment */:

    वेबस्टॉर्म में जावास्क्रिप्ट टाइप हिंटिंग

    यह एक बहुत व्यापक तकनीक है, उदाहरण के लिए ReactJS द्वारा उपयोग किया जाता है । 3 पार्टी पुस्तकालयों को दिए गए कॉलबैक के मापदंडों के लिए बहुत आसान है।

टाइपप्रति

वास्तविक प्रकार की जाँच के लिए, निकटतम समाधान जावास्क्रिप्ट का टाइपस्क्रिप्ट (( अधिकतर ) सुपरसेट का उपयोग करना है। यहां 5 मिनट में टाइपस्क्रिप्ट है


8
यह कैसे प्राप्त करें VSCode?
आनंद अडाविया

2
धन्यवाद। हालांकि यह आईडीई पर निर्भर करता है। मैं VI का उपयोग करता हूं और काम नहीं करूंगा।
negrotico19

@ negrotico19: viएक अत्यधिक दुर्व्यवहार करने वाला संपादक है, न कि एक आईडीई। आप बहुत सारे सामान viकर सकते हैं, जैसे आप एक्सेल में संगीत वीडियो बना सकते हैं । अच्छा विचार? शायद ऩही। इस काम के लिए सही उपकरण का उपयोग करें।
डैन डस्केल्सस्कु

23

फेसबुक से नई फ्लो लाइब्रेरी की जाँच करें, "एक स्थिर प्रकार चेकर, जिसे जावास्क्रिप्ट कार्यक्रमों में टाइप एरर खोजने के लिए डिज़ाइन किया गया है"

परिभाषा:

/* @flow */
function foo(x: string, y: number): string {
  return x.length * y;
}
foo('Hello', 42);

प्रकार की जाँच:

$> flow
hello.js:3:10,21: number
This type is incompatible with
  hello.js:2:37,42: string

और यहां इसे चलाने का तरीका बताया गया है


यदि x दिनांक प्रकार था तो टाइप परिभाषा कैसे जोड़ें? अर्थात फू (x: तिथि): स्ट्रिंग {}। क्या यह करने का सही तरीका है?
आकाश सिगेल

12

नहीं, इसके बजाय आपको अपनी आवश्यकताओं के आधार पर ऐसा कुछ करने की आवश्यकता होगी:

function myFunction(myDate, myString) {
  if(arguments.length > 1 && typeof(Date.parse(myDate)) == "number" && typeof(myString) == "string") {
    //Code here
  }
}

12

आप एक ऐसी प्रणाली को लागू कर सकते हैं जो आपके फ़ंक्शन में एक आवरण का उपयोग करके, स्वचालित रूप से प्रकार के चेक को संभालती है

इस दृष्टिकोण के साथ, आप एक पूर्ण निर्माण कर सकते हैं declarative type check systemजो आपके लिए टाइप चेक का प्रबंधन करेगा। यदि आप इस अवधारणा को अधिक गहराई से देखना चाहते हैं, तो फंक्शनल लाइब्रेरी देखें

निम्नलिखित कार्यान्वयन एक सरल, लेकिन ऑपरेटिव तरीके से मुख्य विचार को दिखाता है :

/*
 * checkType() : Test the type of the value. If succeds return true, 
 * if fails, throw an Error
 */
function checkType(value,type, i){
  // perform the appropiate test to the passed 
  // value according to the provided type
  switch(type){
    case Boolean : 
      if(typeof value === 'boolean') return true;
      break;
    case String : 
      if(typeof value === 'string') return true;
      break;
    case Number : 
      if(typeof value === 'number') return true;
      break;
    default :
      throw new Error(`TypeError : Unknown type provided in argument ${i+1}`);
  }
  // test didn't succeed , throw error
  throw new Error(`TypeError : Expecting a ${type.name} in argument ${i+1}`);
}


/*
 * typedFunction() : Constructor that returns a wrapper
 * to handle each function call, performing automatic 
 * arguments type checking
 */
function typedFunction( parameterTypes, func ){
  // types definitions and function parameters 
  // count must match
  if(parameterTypes.length !== func.length) throw new Error(`Function has ${func.length} arguments, but type definition has ${parameterTypes.length}`);
  // return the wrapper...
  return function(...args){
    // provided arguments count must match types
    // definitions count
    if(parameterTypes.length !== args.length) throw new Error(`Function expects ${func.length} arguments, instead ${args.length} found.`);
    // iterate each argument value, and perform a
    // type check against it, using the type definitions
    // provided in the construction stage
    for(let i=0; i<args.length;i++) checkType( args[i], parameterTypes[i] , i)
    // if no error has been thrown, type check succeed
    // execute function!
    return func(...args);
  }
}

// Play time! 
// Declare a function that expects 2 Numbers
let myFunc = typedFunction( [ Number, Number ],  (a,b)=>{
  return a+b;
});

// call the function, with an invalid second argument
myFunc(123, '456')
// ERROR! Uncaught Error: TypeError : Expecting a Number in argument 2


11

संपादित करें: सात साल बाद, यह उत्तर अभी भी कभी-कभी उठता है। यदि आप रनटाइम चेकिंग की तलाश कर रहे हैं तो यह ठीक है, लेकिन अब मैं टाइपस्क्रिप्ट, या संभवतः फ्लो का उपयोग करके संकलन-समय प्रकार की जाँच करने की सलाह दूंगा। अधिक के लिए https://stackoverflow.com/a/31420719/610585 ऊपर देखें ।

मूल उत्तर:

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

typedFunction = function(paramsList, f){
    //optionally, ensure that typedFunction is being called properly  -- here's a start:
    if (!(paramsList instanceof Array)) throw Error('invalid argument: paramsList must be an array');

    //the type-checked function
    return function(){
        for(var i=0,p,arg;p=paramsList[i],arg=arguments[i],i<paramsList.length; i++){
            if (typeof p === 'string'){
                if (typeof arg !== p) throw new Error('expected type ' + p + ', got ' + typeof arg);
            }
            else { //function
                if (!(arg instanceof p)) throw new Error('expected type ' + String(p).replace(/\s*\{.*/, '') + ', got ' + typeof arg);
            }
        }
        //type checking passed; call the function itself
        return f.apply(this, arguments);
    }
}

//usage:
var ds = typedFunction([Date, 'string'], function(d, s){
    console.log(d.toDateString(), s.substr(0));
});

ds('notadate', 'test');
//Error: expected type function Date(), got string
ds();
//Error: expected type function Date(), got undefined
ds(new Date(), 42);
//Error: expected type string, got number
ds(new Date(), 'success');
//Fri Jun 14 2013 success

5

यह आसानी से ArgueJS के साथ किया जा सकता है :

function myFunction ()
{
  arguments = __({myDate: Date, myString: String});
  // do stuff
};

2
एक महान पुस्तकालय की तरह लग रहा है। बधाई।
FRD

1

उपयोग typeofया instanceof:

const assert = require('assert');

function myFunction(Date myDate, String myString)
{
    assert( typeof(myString) === 'string',  'Error message about incorrect arg type');
    assert( myDate instanceof Date,         'Error message about incorrect arg type');
}

0

शायद इस तरह एक सहायक कार्य करता है। लेकिन अगर आप खुद को नियमित रूप से ऐसे वाक्यविन्यास का उपयोग करते हुए देखते हैं, तो आपको शायद टाइपस्क्रिप्ट पर स्विच करना चाहिए।

function check(caller_args, ...types) {
    if(!types.every((type, index) => {
        if(typeof type === 'string')
            return typeof caller_args[index] === type
        return caller_args[index] instanceof type;
    })) throw Error("Illegal argument given");
}

function abc(name, id, bla) {
   check(arguments, "string", "number", MyClass)
   // code
}

0

मैं इस बारे में भी सोच रहा हूं। C बैकग्राउंड से, आप फ़ंक्शन रिटर्न कोड प्रकारों के साथ-साथ पैरामीटर प्रकारों का अनुकरण भी कर सकते हैं, जैसे कि निम्नलिखित कुछ का उपयोग करके:

function top_function() {
    var rc;
    console.log("1st call");
    rc = Number(test_function("number", 1, "string", "my string"));
    console.log("typeof rc: " + typeof rc + "   rc: " + rc);
    console.log("2nd call");
    rc = Number(test_function("number", "a", "string", "my string"));
    console.log("typeof rc: " + typeof rc + "   rc: " + rc);
}
function test_function(parm_type_1, parm_val_1, parm_type_2, parm_val_2) {
    if (typeof parm_val_1 !== parm_type_1) console.log("Parm 1 not correct type");
    if (typeof parm_val_2 !== parm_type_2) console.log("Parm 2 not correct type");
    return parm_val_1;
}

कॉलिंग फ़ंक्शन से पहले नंबर एक नंबर प्रकार देता है, भले ही वास्तविक मूल्य के प्रकार की परवाह किए बिना, जैसा कि 2 कॉल में देखा गया है जहां टाइपो आरसी = संख्या लेकिन मान NaN है

कंसोल। ऊपर के लिए है:

1st call
typeof rc: number   rc: 1
2nd call
Parm 1 not correct type
typeof rc: number   rc: NaN

0

टाइपस्क्रिप्ट अब के लिए सबसे अच्छा समाधान में से एक है

टाइपस्क्रिप्ट भाषा में प्रकार जोड़कर जावास्क्रिप्ट का विस्तार करते हैं।

https://www.typescriptlang.org/

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.