Làm cách nào để kiểm tra xem hàm có tồn tại trong JavaScript không?


534

Mã của tôi là

function getID( swfID ){
     if(navigator.appName.indexOf("Microsoft") != -1){
          me = window[swfID];
     }else{
          me = document[swfID];
     }
}

function js_to_as( str ){
     me.onChange(str);
}

Tuy nhiên, đôi khi tôi onChangekhông tải. Lỗi Firebird với

me.onChange không phải là một chức năng

Tôi muốn xuống cấp một cách duyên dáng bởi vì đây không phải là tính năng quan trọng nhất trong chương trình của tôi. typeofđưa ra lỗi tương tự.

Bất kỳ đề xuất về làm thế nào để đảm bảo rằng nó tồn tại và sau đó chỉ thực hiện onChange?

(Không có phương pháp nào dưới đây ngoại trừ thử bắt một tác phẩm)


1
@SteveChambers Tôi đã làm điều đó. Cảm ơn bạn đã nhắc nhở tôi.
Alec Smart


bắt ngoại lệ. kiểm tra câu trả lời của tôi
Matteus Barbosa

Câu trả lời:


1226

Hãy thử một cái gì đó như thế này:

if (typeof me.onChange !== "undefined") { 
    // safe to use the function
}

hoặc tốt hơn nữa (theo nhận xét nâng cấp của UpTheCalet)

if (typeof me.onChange === "function") { 
    // safe to use the function
}

249
=== 'chức năng' sẽ tốt hơn! = 'Không xác định'
UpTheCalet

3
@James, vì tuyên bố đó thực sự ném một undefinedngoại lệ trong JavaScript. Tôi đã thử nó.
Mike Perrenoud

8
@UpTheCreek, nó sẽ là một chút nguy hiểm như một giải pháp chung kể từ khi phiên bản cũ của trình duyệt IE trị chức năng nhất định như các đối tượng, ví dụ typeof window.alert === 'object'.
Noyo

1
Tại sao không chỉ sử dụng if (me.onChange) { // do something }?
Sinh ra ToCode

3
@BornToCode bởi vì sau đó me.onChangecó thể là bất cứ thứ gì được đánh giá true, không nhất thiết phải là một hàm (ví dụ: nó có thể là boolean, chuỗi, v.v.). Ví dụ, xem jsfiddle.net/j5KAF/1
Ohad Schneider

108

Tôi đã có vấn đề này.

if (obj && typeof obj === 'function') { ... }

tiếp tục ném một lỗi tham chiếu nếu obj tình cờ không được xác định.

Cuối cùng, tôi đã làm như sau:

if (typeof obj !== 'undefined' && typeof obj === 'function') { ... }

Một đồng nghiệp chỉ ra cho tôi rằng kiểm tra nếu nó !== 'undefined'và sau đó === 'function'là không cần thiết của khóa học.

Đơn giản hơn:

if (typeof obj === 'function') { ... }

Sạch hơn nhiều và hoạt động tuyệt vời.


1
Bất cứ ai cũng có ý tưởng tại sao đoạn mã đầu tiên ném ReferenceError? Điều đó có vẻ phi logic với tôi.
saidfagan

@saidfagan Xem định nghĩa của ReferenceError developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/
Kẻ

cái này hiệu quả với tôi
NewBie1234

1
Bất kỳ động cơ tại sao typeof obj == 'function' sẽ không đủ? ;-) Nhắc nhở: Toán tử kiểm tra đẳng thức nghiêm ngặt chỉ có ý nghĩa khi toán hạng tĩnh trống hoặc null hoặc 0 hoặc chịu bất kỳ sự trộn lẫn nào như thế này.
Fabien Haddadi

16

Nếu bạn đang sử dụng eval để chuyển đổi một chuỗi thành chức năng và bạn muốn kiểm tra xem phương thức eval'd này có tồn tại hay không, bạn sẽ muốn sử dụng typeof và chuỗi chức năng của bạn trong một eval :

var functionString = "nonexsitantFunction"
eval("typeof " + functionString) // returns "undefined" or "function"

Không đảo ngược này và thử một typeof trên eval . Nếu bạn làm ReferenceError sẽ bị ném:

var functionString = "nonexsitantFunction"
typeof(eval(functionString)) // returns ReferenceError: [function] is not defined

21
eval == evil;)
Yeti

1
Nó có thể là xấu, nhưng điều này rất hữu ích khi tên hàm nằm trong một biến.
Luke Cousins

8
Bạn có thể làm điều này mà không cần eval. Ví dụ:var a = 'alert'; window[a]('it works');
zennin

15

Làm thế nào về:

if('functionName' in Obj){
    //code
}

ví dụ

var color1 = new String("green");
"length" in color1 // returns true
"indexOf" in color1 // returns true
"blablabla" in color1 // returns false

hoặc như trường hợp của bạn:

if('onChange' in me){
    //code
}

Xem tài liệu MDN .


nhưng giải pháp này không hoạt động mọi lúc :( ví dụ nếu tôi muốn biết nó có lastIndexOf()trong chuỗi (chúng tôi biết, đó là, nhưng về mặt lý thuyết) typeof String().lastIndexOf === "function"thì đúng, nhưng 'lastIndexOf' in Stringlà sai.
iiic

10

Hãy thử typeof- Tìm kiếm 'undefined'để nói rằng nó không tồn tại, 'function'cho một chức năng. Mã xác nhận mã này

function thisishere() {
    return false;
}
alert("thisishere() is a " + typeof thisishere);
alert("thisisnthere() is " + typeof thisisnthere);

Hoặc như là một:

if (typeof thisishere === 'function') {
    // function exists
}

Hoặc với giá trị trả về, trên một dòng duy nhất:

var exists = (typeof thisishere === 'function') ? "Value if true" : "Value if false";
var exists = (typeof thisishere === 'function') // Returns true or false

9

Không thấy đề xuất này: me.onChange && me.onChange (str);

Về cơ bản nếu me.onChange không được xác định (sẽ là nếu nó chưa được khởi tạo) thì nó sẽ không thực thi phần sau. Nếu me.onChange là một hàm, nó sẽ thực thi me.onChange (str).

Bạn thậm chí có thể đi xa hơn và làm:

me && me.onChange && me.onChange(str);

trong trường hợp tôi là async là tốt.


5
//Simple function that will tell if the function is defined or not
function is_function(func) {
    return typeof window[func] !== 'undefined' && $.isFunction(window[func]);
}

//usage

if (is_function("myFunction") {
        alert("myFunction defined");
    } else {
        alert("myFunction not defined");
    }

Giải pháp của bạn không rõ ràng, vì nó gây tranh cãi, đó là điều kỳ lạ tại thời điểm này tôi nghĩ, vì vậy nó ném lỗi khi kiểm tra đơn giản.
T.Todua

@tazotodua nó là chức năng tự giải thích. nếu bạn muốn sử dụng mà không cần jquery. chỉ cần xóa phần &&. đó là một điều kiện bổ sung để kiểm tra và tránh sai sót.
Muhammad Tahir

Có phải điều kiện ở phía bên trái của việc &&chăm sóc một cái gì đó mà jQuery isFunctionở phía bên &&phải không?
SantiBailors

5

Đối với tôi cách dễ nhất:

function func_exists(fname)
{
  return (typeof window[fname] === 'function');
}

Đây là câu trả lời đúng, bởi vì đó là một chuỗi ký tự .. Tôi sẽ nói nó tốt hơn như thế này if ((typeof window["function_name"] !== 'undefined') && ((typeof window["function_name"] === 'function'))) { return true; } else { return false; }nhưng đó là một sự điều chỉnh nhỏ
Mr Heelis 20/12/18

4

Tôi sẽ đi thêm 1 bước nữa để đảm bảo tài sản thực sự là một chức năng

function js_to_as( str ){
     if (me && me.onChange && typeof me.onChange === 'function') {
         me.onChange(str);
     }
}

3
function js_to_as( str ){
     if (me && me.onChange)
         me.onChange(str);
}

3

Tôi thích sử dụng phương pháp này:

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

Sử dụng:

if ( isFunction(me.onChange) ) {
    me.onChange(str); // call the function with params
}


3
function function_exists(function_name)
{
    return eval('typeof ' + function_name) === 'function';
}
alert(function_exists('test'));
alert(function_exists('function_exists'));

HOẶC LÀ

function function_exists(func_name) {
  //  discuss at: http://phpjs.org/functions/function_exists/
  // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // improved by: Steve Clay
  // improved by: Legaev Andrey
  // improved by: Brett Zamir (http://brett-zamir.me)
  //   example 1: function_exists('isFinite');
  //   returns 1: true

  if (typeof func_name === 'string') {
    func_name = this.window[func_name];
  }
  return typeof func_name === 'function';
}

1
Xin vui lòng, một số lời giải thích.
Gufran Hasan

Trong hai trường hợp, chỉ cần gọi function_exists với tên của tham số hàm để kiểm tra sự tồn tại, trả về bool.
Mohammad Lotfi

3

Đặt dấu chấm than kép tức là !! trước tên hàm mà bạn muốn kiểm tra. Nếu nó tồn tại, nó sẽ trở lại đúng.

function abc(){
}
!!window.abc; // return true
!!window.abcd; // return false

3

Trong một vài từ: bắt ngoại lệ.

Tôi thực sự ngạc nhiên không ai trả lời hoặc nhận xét về Exception Catch trên bài đăng này.

Chi tiết: Dưới đây là một ví dụ trong đó tôi cố gắng khớp một hàm có tiền tố là mask_ và được thêm vào bởi trường tên "tên". Khi JavaScript không tìm thấy hàm, nó sẽ ném ReferenceError mà bạn có thể xử lý như bạn muốn trên phần bắt.

function inputMask(input) {
  try {
    let maskedInput = eval("mask_"+input.name);

    if(typeof maskedInput === "undefined")
        return input.value;
    else
        return eval("mask_"+input.name)(input);

  } catch(e) {
    if (e instanceof ReferenceError) {
      return input.value;
    }
  }
}


2

Không có điều kiện

me.onChange=function(){};

function getID( swfID ){
     if(navigator.appName.indexOf("Microsoft") != -1){
          me = window[swfID];
     }else{
          me = document[swfID];
     }
}

function js_to_as( str ){
     me.onChange(str);
}

2

Tôi nghi ngờ rằng mekhông được gán chính xác tải.

Di chuyển cuộc gọi get_ID vào sự kiện onclick sẽ chăm sóc nó.

Rõ ràng bạn có thể bẫy thêm như đã đề cập trước đây:

function js_to_as( str) {
  var me = get_ID('jsExample');
  if (me && me.onChange) {
    me.onChange(str);
  }
}

2

Tôi luôn kiểm tra như thế này:

if(!myFunction){return false;}

chỉ cần đặt nó trước bất kỳ mã nào sử dụng chức năng này


2

Tôi đã có trường hợp tên của hàm thay đổi theo một biến (var 'x' trong trường hợp này) được thêm vào tên hàm. Những công việc này:

if ( typeof window['afunction_'+x] === 'function' ) { window['afunction_'+x](); } 

2

Mã jQuery đơn giản này nên thực hiện thủ thuật:

if (jQuery.isFunction(functionName)) {
    functionName();
}

2

Tôi đã thử câu trả lời được chấp nhận; Tuy nhiên:

console.log(typeof me.onChange);

trả về 'không xác định'. Tôi đã nhận thấy rằng thông số kỹ thuật nêu rõ một sự kiện gọi là 'onchange' thay vì 'onChange' (chú ý đến camelCase).

Thay đổi câu trả lời được chấp nhận ban đầu thành các câu trả lời sau đây cho tôi:

if (typeof me.onchange === "function") { 
  // safe to use the function
}

2

Nếu bạn đang kiểm tra một hàm là một plugin jQuery, bạn cần sử dụng $ .fn.myfeft

if (typeof $.fn.mask === 'function') {
    $('.zip').mask('00000');
}

2

Tôi cũng đã tìm kiếm một giải pháp tao nhã cho vấn đề này. Sau nhiều suy ngẫm, tôi thấy cách tiếp cận này tốt nhất.

const func = me.onChange || (str => {}); func(str);


Nếu bạn đang đi tối thiểu, bạn cũng có thể làm điều này: (me.onChange||(_=>_))()Sẽ thực thi chức năng nếu nó tồn tại, nếu không sẽ không làm gì cả.
JSideris

Nó là tốt hơn me.onChange && me.onChange()để ngăn chặn xác định một chức năng void.
hoại tử

2

Javascript hiện đại để giải cứu!

Điều này có thể không có cơ hội lớn để được nhìn thấy với danh sách dài các câu trả lời, nhưng điều này hiện đã được giải quyết * ở cấp độ ngôn ngữ với cú pháp Chuỗi tùy chọn mới

me.onChange?.(str)

Nó đơn giản như thế - onChangechỉ được gọi nếu nó tồn tại .

Nếu onChangekhông tồn tại, không có gì xảy ra và biểu thức trả về undefined- vì vậy nếu nó có giá trị trả về mà bạn sử dụng, bạn chỉ cần kiểm tra giá trị này !== undefinedtrước khi tiếp tục.

Cảnh báo trường hợp cạnh - nếu onChange không tồn tại nhưng không phải là một chức năng, bạn nhận được mộtTypeError . Điều này đúng như bạn mong đợi, nó giống như việc cố gắng gọi bất kỳ chức năng nào không phải là một chức năng, nhưng đáng để chỉ ra một cách rõ ràng rằng Chuỗi tùy chọn không làm bất kỳ phép thuật nào để biến điều này biến mất.

* Chà, về mặt kỹ thuật, Chaining tùy chọn vẫn là đề xuất TC39 giai đoạn 4, vì vậy chưa có trong thông số ECMAScript, nhưng giai đoạn 4 có nghĩa là nó đã được hoàn thiện và về cơ bản nó được bảo đảm, nó chỉ chờ một phiên bản mới được phát hành. Bạn có thể sử dụng cú pháp trong phiên bản cuối cùng của nó ngày hôm nay thông qua Babel với sự tự tin rằng nó sẽ không thay đổi. Nó thậm chí còn trong Bản in!


1

Đây là một giải pháp đơn giản và hiệu quả để kiểm tra sự tồn tại của một chức năngkích hoạt chức năng đó một cách linh hoạt bởi một chức năng khác;

Chức năng kích hoạt

function runDynamicFunction(functionname){ 

    if (typeof window[functionname] == "function") { //check availability

        window[functionname]("this is from the function it"); // run function and pass a parameter to it
    }
}

và bây giờ bạn có thể tạo hàm một cách linh hoạt có thể sử dụng php như thế này

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

bây giờ bạn có thể gọi hàm bằng cách sử dụng sự kiện được tạo động

<?php

$name_frm_somware ="runThis_func";

echo "<input type='button' value='Button' onclick='runDynamicFunction(\"".$name_frm_somware."\");'>";

?>

mã HTML chính xác bạn cần là

<input type="button" value="Button" onclick="runDynamicFunction('runThis_func');">

0
    function sum(nb1,nb2){

       return nb1+nb2;
    }

    try{

      if(sum() != undefined){/*test if the function is defined before call it*/

        sum(3,5);               /*once the function is exist you can call it */

      }

    }catch(e){

      console.log("function not defined");/*the function is not defined or does not exists*/
    }

0

Và sau đó là ...

( document.exitPointerLock || Function )();

Xin chào Sư phụ, một người tốt, nhưng bạn nghĩ sao về việc bắt Ngoại lệ? kiểm tra câu trả lời của tôi
Matteus Barbosa

Hi cảm ơn đã lưu ý. Giải pháp của bạn thật đáng ngưỡng mộ. Tôi cố gắng tránh mô hình 'thử bắt' bất cứ khi nào có thể hoặc dễ dàng hơn, hoặc có thể nó được ngụ ý / áp đặt bởi viện trợ của bên thứ 3. 'Eval' cũng cau mày vì nhiều lý do khiến người ta thích thử bắt một cái bọc khác để trì hoãn thời gian. Có những lựa chọn thay thế cho eval có thể 'ném' quá. Tôi nghĩ rằng 'Hàm mới (parms, body)' có thể sẽ gây ra lỗi cho bạn, nhưng tôi đoán câu hỏi tiếp theo đối với tôi là so sánh tốc độ, khác là giảm kích thước mã tốt nhất (ngụ ý nhanh hơn với tôi). [Hmm cái này có vẻ mới. Tôi chưa từng thử nó jsben.ch]
Master James

Thay vào đó, điểm thú vị của mmm rly về việc gọi Chức năng mới. vui lòng gửi đề xuất thay đổi của bạn để trả lời của tôi. cảm ơn rất nhiều
Matteus Barbosa

Ý tôi là ngay cả trong bash bằng cách sử dụng 'nguồn myScript.sh' sẽ cho phép bạn 'xuất' thông qua các bí danh, v.v ... giống như các lớp và thư viện luôn là một thuộc tính vốn có của bất kỳ và tất cả các mã. Bạn nên có mã kiểm tra trình thông dịch js nếu nó không bị xử phạt. Tôi đã xây dựng một hàm trong một hàm duy nhất, đó là một thách thức thú vị khác để giúp hiểu bản chất tiên đề đơn giản nhất của mã và ngay cả thời gian chạy cũng không nằm ngoài khả năng của bất kỳ ai.
Master James

0

Hãy thử cái này:

Window.function_exists=function(function_name,scope){
//Setting default scope of none is provided
If(typeof scope === 'undefined') scope=window;
//Checking if function name is defined
If (typeof function_name === 'undefined') throw new 
Error('You have to provide an valid function name!');
//The type container
var fn= (typeof scope[function_name]);
//Function type
If(fn === 'function') return true;
//Function object type
if(fn.indexOf('function')!== false) return true; 
return false;
}

Xin lưu ý rằng tôi đã viết thư này bằng điện thoại di động của mình Có thể chứa một số vấn đề về chữ hoa và / hoặc các chỉnh sửa khác cần thiết như ví dụ tên hàm

Nếu bạn muốn một hàm như PHP kiểm tra xem var có được đặt không:

Window.isset=function (variable_con){
If(typeof variable_con !== 'undefined') return true;
return false;
}

0

Để minh họa các câu trả lời trước, ở đây một đoạn mã JSFiddle nhanh:

function test () {
console.log()

}

console.log(typeof test) // >> "function"

// implicit test, in javascript if an entity exist it returns implcitly true unless the element value is false as :
// var test = false
if(test){ console.log(true)}
else{console.log(false)}

// test by the typeof method
if( typeof test === "function"){ console.log(true)}
else{console.log(false)}


// confirm that the test is effective : 
// - entity with false value
var test2 = false
if(test2){ console.log(true)}
else{console.log(false)}

// confirm that the test is effective :
// - typeof entity
if( typeof test ==="foo"){ console.log(true)}
else{console.log(false)}

/* Expected :
function
true 
true 
false
false
*/


0
// just pass your tested function name instead of myFunctionName
if ( $.isFunction($.fn.myFunctionName) ) {
    console.log( 'write your code here.' );
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.