Memeriksa apakah sebuah variabel dari tipe fungsi

Misalkan aku punya variabel, yang didefinisikan sebagai berikut:

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

Saya ingin fungsi yang memeriksa apakah tipe dari variabel adalah fungsi-suka. yaitu :

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

Bagaimana saya bisa memeriksa apakah variabel a adalah dari jenis Fungsi dalam cara yang dijelaskan di atas?

Mengomentari pertanyaan (2)
if (typeof v === "function") {
    // do something
}
Komentar (6)
Larutan

Yakin menggarisbawahi's cara yang lebih efisien, tapi cara terbaik untuk memeriksa, ketika efisiensi isn't masalah, yang tertulis pada garis bawah's halaman dihubungkan oleh @Paul Rosania.

Terinspirasi oleh garis bawah, final isFunction fungsi adalah sebagai berikut:

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

Underscore.js menggunakan lebih rumit tapi sangat performant tes:

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

Lihat: http://jsperf.com/alternative-isfunction-implementations

EDIT: diperbarui tes menunjukkan bahwa typeof mungkin akan lebih cepat, lihat http://jsperf.com/alternative-isfunction-implementations/4

Komentar (6)

Ada beberapa cara agar saya akan meringkas mereka semua

  1. cara Terbaik adalah:

    fungsi foo(v) {if (v instanceof Fungsi) {/ lakukan sesuatu /} };

    Paling performant (tidak ada perbandingan string) dan elegan solusi - operator instanceof telah didukung dalam browser untuk waktu yang sangat lama, jadi don't khawatir - itu akan bekerja di IE 6.
  2. cara terbaik adalah:

    fungsi foo(v) {if (typeof v === "fungsi") {/ lakukan sesuatu /} };

    kelemahan dari jenis adalah bahwa hal itu lebih rentan untuk diam kegagalan, buruk, jadi jika anda memiliki kesalahan ketik (misalnya "finction") - dalam hal ini `jika` hanya akan kembali palsu dan anda tidak't tahu anda memiliki kesalahan sampai kemudian dalam kode anda
  3. cara terbaik berikutnya adalah:

    fungsi isFunction(functionToCheck) { var getType = {}; kembali functionToCheck && getType.toString.panggilan(functionToCheck) === '[objek Fungsi]'; }

    Ini memiliki keuntungan lebih dari solusi #1 atau #2, tetapi adalah jauh lebih mudah dibaca. Sebuah versi perbaikan dari hal ini adalah

    fungsi isFunction(x) { kembali Objek.prototipe.toString.panggilan(x) == '[objek Fungsi]'; }

    tapi masih banyak yang kurang semantik dari solusi #1

Komentar (2)

jQuery (sudah ditinggalkan sejak versi 3.3) Referensi

$.isFunction(functionName);

AngularJS Referensi

angular.isFunction(value);

Lodash Referensi

_.isFunction(value);

Menggarisbawahi Referensi

_.isFunction(object); 

Node.js tak berlaku lagi sejak v4.0.0 Referensi

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

@grandecomplex: Ada's cukup bertele-tele untuk solusi anda. Itu akan menjadi lebih jelas jika ditulis seperti ini:

function isFunction(x) {
  return Object.prototype.toString.call(x) == '[object Function]';
}
Komentar (1)
var foo = function(){};
if (typeof foo === "function") {
  alert("is function")
}
Komentar (1)

Mencoba instanceof operator: tampaknya bahwa semua fungsi mewarisi dari Fungsi kelas:

// 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
Komentar (0)

Sesuatu dengan lebih banyak dukungan browser dan juga mencakup async fungsi bisa:

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

dan kemudian mengujinya seperti:

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
Komentar (0)

Yang lain cukup dengan cara:

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

Bagi mereka yang's tertarik pada gaya fungsional, atau terlihat lebih ekspresif pendekatan untuk memanfaatkan dalam meta pemrograman (seperti jenis pemeriksaan), itu bisa menjadi menarik untuk melihat Ramda perpustakaan untuk menyelesaikan tugas tersebut.

Berikutnya kode hanya berisi murni dan pointfree fungsi:

const R = require('ramda');

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

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

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

Sebagai ES2017, async fungsi yang tersedia, sehingga kita dapat memeriksa terhadap mereka serta:

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

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

Dan kemudian menggabungkan mereka bersama-sama:

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

Tentu saja, fungsi harus dilindungi terhadap null dan undefined nilai-nilai, sehingga untuk membuat "aman":

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

Dan, lengkap cuplikan singkatnya:

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

Namun, catatan larutan ini bisa menunjukkan kinerja kurang dari pilihan lain yang tersedia karena penggunaan yang luas dari tingkat tinggi fungsi.

Komentar (0)

Jika anda menggunakan Lodash anda dapat melakukannya dengan _.isFunction.

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

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

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

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

Metode ini mengembalikan true jika nilai adalah fungsi, yang lain palsu.

Komentar (0)

Di bawah ini tampaknya bekerja untuk saya juga (diuji dari node.js):

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

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

Saya menemukan bahwa ketika pengujian browser asli fungsi di IE8, menggunakan toString, instanceof, dan jenis tidak bekerja. Berikut ini adalah metode yang bekerja dengan baik di IE8 (sejauh yang saya tahu):

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

Atau, anda dapat memeriksa untuk fungsi asli menggunakan:

"getElementById" in document

Meskipun, saya telah membaca di suatu tempat bahwa ini tidak akan selalu bekerja di IE7 dan di bawah ini.

Komentar (0)

Saya pikir anda hanya dapat menentukan bendera pada prototipe Fungsi dan memeriksa jika misalnya anda ingin menguji warisan yang

menetapkan bendera:

Function.prototype.isFunction = true; 

dan kemudian memeriksa jika ada

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

The downside adalah bahwa lain prototipe dapat menentukan bendera yang sama dan kemudian's tidak berharga, tetapi jika anda memiliki kontrol penuh atas termasuk modul ini adalah cara termudah

Komentar (1)

Sejak node v0.11 anda dapat menggunakan standar util fungsi :

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

anda harus menggunakan jenis operator di js.

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

Solusi seperti beberapa jawaban sebelumnya telah menunjukkan adalah dengan menggunakan typeof. berikut adalah potongan kode Di 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]();
  }
Komentar (0)