460

私の特定のケースでは:

callback instanceof Function

また

typeof callback == "function"

違いは何ですか?

追加リソース:

JavaScript-Garden typeofinstanceof

4

25 に答える 25

622

instanceofカスタム タイプに使用します。

var ClassFirst = function () {};
var ClassSecond = function () {};
var instance = new ClassFirst();
typeof instance; // object
typeof instance == 'ClassFirst'; // false
instance instanceof Object; // true
instance instanceof ClassFirst; // true
instance instanceof ClassSecond; // false 

typeof単純な組み込み型に使用します。

'example string' instanceof String; // false
typeof 'example string' == 'string'; // true

'example string' instanceof Object; // false
typeof 'example string' == 'object'; // false

true instanceof Boolean; // false
typeof true == 'boolean'; // true

99.99 instanceof Number; // false
typeof 99.99 == 'number'; // true

function() {} instanceof Function; // true
typeof function() {} == 'function'; // true

instanceof複雑な組み込み型に使用します。

/regularexpression/ instanceof RegExp; // true
typeof /regularexpression/; // object

[] instanceof Array; // true
typeof []; //object

{} instanceof Object; // true
typeof {}; // object

最後のものは少しトリッキーです:

typeof null; // object
于 2011-07-08T14:30:26.040 に答える
106

typeof を使用する正当な理由は、変数が未定義である可能性がある場合です。

alert(typeof undefinedVariable); // alerts the string "undefined"
alert(undefinedVariable instanceof Object); // throws an exception

instanceof を使用する正当な理由は、変数が null の可能性がある場合です。

var myNullVar = null;
alert(typeof myNullVar ); // alerts the string "object"
alert(myNullVar  instanceof Object); // alerts "false"

したがって、私の意見では、チェックしている可能性のあるデータのタイプによって異なります。

于 2010-01-20T16:35:17.860 に答える
44

物事を明確にするために、次の 2 つの事実を知っておく必要があります。

  1. instanceof演算子は、コンストラクターのプロトタイプ プロパティがオブジェクトのプロトタイプ チェーンのどこかに現れるかどうかをテストします。ほとんどの場合、これは、このコンストラクターまたはその子孫を使用してオブジェクトが作成されたことを意味します。ただし、プロトタイプは、メソッド (ECMAScript 2015) またはプロパティ (古いブラウザー、非推奨) によって明示的に設定することもできます。ただし、パフォーマンスの問題があるため、オブジェクトのプロトタイプを変更することはお勧めしません。 Object.setPrototypeOf()__proto__

したがって、instanceof はオブジェクトにのみ適用されます。ほとんどの場合、コンストラクターを使用して文字列や数値を作成することはありません。あなたはできる。しかし、あなたはほとんどそうしません。

また、 instanceof は、オブジェクトの作成に使用されたコンストラクターを正確に確認することはできませんが、オブジェクトがチェックされているクラスから派生している場合でも、true を返します。ほとんどの場合、これは望ましい動作ですが、そうでない場合もあります。ですから、その心を保つ必要があります。

もう 1 つの問題は、スコープごとに実行環境が異なることです。これは、それらが異なる組み込み (異なるグローバル オブジェクト、異なるコンストラクターなど) を持っていることを意味します。これにより、予期しない結果が生じる場合があります。

たとえば、[] instanceof window.frames[0].Arrayは を返します。falseこれArray.prototype !== window.frames[0].Arrayは、配列が前者から継承されているためです。
また、プロトタイプがないため、未定義の値には使用できません。

  1. typeof演算子は、値が次の 6 つの基本型のいずれかに属しているかどうかをテストします: " number "、" string "、" boolean "、" object "、" function "、または " undefined "。文字列「object」はすべてのオブジェクト (オブジェクトであるが、typeof 演算子に独自の値を持つ関数を除く) に属し、「null」値と配列 (「null」の場合はバグですが、このバグは非常に古いものです)ので、スタンダードになっています。)コンストラクターに依存せず、値が未定義の場合でも使用できます。しかし、それはオブジェクトに関する詳細を提供しません。必要な場合は、instanceof に移動します。

ここで、1 つのトリッキーなことについて話しましょう。コンストラクターを使用してプリミティブ型を作成するとどうなりますか?

let num = new Number(5);
console.log(num instanceof Number); // print true
console.log(typeof num); // print object
num++; //num is object right now but still can be handled as number
//and after that:
console.log(num instanceof Number); // print false
console.log(typeof num); // print number

魔法のようです。そうではありません。これは、いわゆるボックス化 (オブジェクトごとにプリミティブ値をラップすること) とアンボックス化 (ラップされたプリミティブ値をオブジェクトから抽出すること) です。この種のコードは「少し」壊れやすいようです。もちろん、コンストラクターでプリミティブ型を作成することは避けられます。しかし、ボクシングがあなたを襲うかもしれない別の状況が考えられます。プリミティブ型で Function.call() または Function.apply() を使用する場合。

function test(){
  console.log(typeof this);
} 
test.apply(5);

これを回避するには、厳密モードを使用できます。

function test(){
  'use strict';
  console.log(typeof this);
} 
test.apply(5);

upd: ECMAScript 2015 以降、独自の typeof == "symbol"を持つ Symbol と呼ばれる型がもう 1 つあります。

console.log(typeof Symbol());
// expected output: "symbol"

MDN でそれについて読むことができます: ( Symbol , typeof )。

于 2016-01-29T09:32:07.760 に答える
17

Safari5とInternetExplorer9で、非常に興味深い(「恐ろしい」と読まれる)動作を発見しました。これを使用して、ChromeとFirefoxで大成功を収めました。

if (typeof this === 'string') {
    doStuffWith(this);
}

次に、IE9でテストしましたが、まったく機能しません。ビッグサプライズ。しかし、Safariでは断続的です!だから私はデバッグを開始し、InternetExplorerが常にを返していることがわかりましたfalse。しかし、最も奇妙なことは、SafariがJavaScript VMで何らかの最適化を行っているように見えることです。これはtrue初めてですが、false リロードを押すたびに!

私の脳はほとんど爆発した。

だから今私はこれに落ち着きました:

if (this instanceof String || typeof this === 'string')
    doStuffWith(this.toString());
}

そして今、すべてがうまく機能しています。呼び出すことができ"a string".toString()、文字列のコピーを返すだけであることに注意してください。

"a string".toString() === new String("a string").toString(); // true

なので、これからは両方使っていきます。

于 2011-11-22T00:28:53.253 に答える
9

その他の重要な実用上の違い:

// Boolean

var str3 = true ;

alert(str3);

alert(str3 instanceof Boolean);  // false: expect true  

alert(typeof str3 == "boolean" ); // true

// Number

var str4 = 100 ;

alert(str4);

alert(str4 instanceof Number);  // false: expect true   

alert(typeof str4 == "number" ); // true
于 2011-01-20T09:20:44.870 に答える
7

instanceofcallbackが のサブタイプの場合にも機能しFunctionます。

于 2009-05-22T19:27:55.990 に答える
3

instanceofプリミティブでは機能しません。たとえば、"foo" instanceof Stringが返されますがfalsetypeof "foo" == "string"は返されtrueます。

一方、typeofカスタムオブジェクト(またはクラス、あなたがそれらを呼びたいものは何でも)に関しては、おそらくあなたが望むことをしないでしょう。例えば:

function Dog() {}
var obj = new Dog;
typeof obj == 'Dog' // false, typeof obj is actually "object"
obj instanceof Dog  // true, what we want in this case

関数が「関数」プリミティブと「関数」のインスタンスの両方であることがたまたまあります。これは、他のプリミティブ型のように機能しないことを考えると、少し奇妙です。

(typeof function(){} == 'function') == (function(){} instanceof Function)

しかし

(typeof 'foo' == 'string') != ('foo' instanceof String)
于 2012-02-03T09:42:48.667 に答える
3

関数をチェックするときは、常に を使用する必要がありますtypeof

違いは次のとおりです。

var f = Object.create(Function);

console.log(f instanceof Function); //=> true
console.log(typeof f === 'function'); //=> false

f(); // throws TypeError: f is not a function

instanceofこれが、関数をチェックするために決して使用してはならない理由です。

于 2016-07-19T23:38:33.913 に答える
3

Performance

typeof is faster than instanceof in situations where both are applicable.

Depending on your engine, the performance difference in favor of typeof could be around 20%. (Your mileage may vary)

Here is a benchmark testing for Array:

var subject = new Array();
var iterations = 10000000;

var goBenchmark = function(callback, iterations) {
    var start = Date.now();
    for (i=0; i < iterations; i++) { var foo = callback(); }
    var end = Date.now();
    var seconds = parseFloat((end-start)/1000).toFixed(2);
    console.log(callback.name+" took: "+ seconds +" seconds.");
    return seconds;
}

// Testing instanceof
var iot = goBenchmark(function instanceofTest(){
     (subject instanceof Array);
}, iterations);

// Testing typeof
var tot = goBenchmark(function typeofTest(){
     (typeof subject == "object");
}, iterations);

var r = new Array(iot,tot).sort();
console.log("Performance ratio is: "+ parseFloat(r[1]/r[0]).toFixed(3));

Result

instanceofTest took: 9.98 seconds.
typeofTest took: 8.33 seconds.
Performance ratio is: 1.198
于 2015-08-28T13:25:17.247 に答える
2

重要な実用上の違い:

var str = 'hello word';

str instanceof String   // false

typeof str === 'string' // true

理由を聞かないでください。

于 2010-08-20T14:07:56.597 に答える
-1

もちろん大事に……!

例を挙げて説明しましょう。この例では、関数を 2 つの異なる方法で宣言します。

function declarationFunction Constructorの両方を使用します。これら 2 つの異なるシナリオでどのようtypeofに動作するかを確認します。instanceof

関数宣言を使用して関数を作成します。

function MyFunc(){  }

typeof Myfunc == 'function' // true

MyFunc instanceof Function // false

このような異なる結果の考えられる説明は、関数宣言を行ったのでtypeof、それが関数であることを理解できることですtypeof。 typeof が操作される式であるかどうかをチェックするため、この場合はCall Methodが実装されているどうか。それがメソッドを実装する場合、それは関数です。それ以外の場合はそうではありませMyFunc Call

関数コンストラクターを使用して関数を作成します。

var MyFunc2 = new Function('a','b','return a+b') // A function constructor is used 

typeof MyFunc2 == 'function' // true

MyFunc2 instanceof Function // true

ここでは、 が関数であると同時に演算子であるtypeofと主張します。メソッドが実装されているかどうかを確認することは既にわかっています。のインスタンスになります。そのため、にも解決されます。MyFunc2instanceoftypeofMyFunc2CallMyFunc2calltypeoffunction constructorMyFunc2Function constructorinstanceoftrue

より安全に使用できるものは何ですか?

両方のケースでわかるように、typeof演算子はここで関数を扱っていることを正常にアサートできます。より安全ですinstanceof。のインスタンスではないためinstanceof、 の場合は失敗します。function declarationfunction declarationsFunction constructor

ベストプラクティス:

Gary Raffertyが示唆したように、最善の方法は typeof と instanceof の両方を一緒に使用することです。

  function isFunction(functionItem) {

        return typeof(functionItem) == 'function' || functionItem instanceof Function;

  }

  isFunction(MyFunc) // invoke it by passing our test function as parameter
于 2018-01-04T05:55:19.907 に答える
-1

パフォーマンスを念頭に置いて、通常のハードウェアで typeof を使用することをお勧めします。1,000 万回の反復のループを含むスクリプトを作成する場合、命令: typeof str == 'string' は 9 ミリ秒かかり、'string' instanceof String は 19 ミリ秒かかります。

于 2017-09-16T22:55:38.053 に答える