[解決済み】オブジェクトの型の名前を取得する
質問
はあるのでしょうか?
JavaScript
に相当します。
ジャワ
's
class.getName()
?
解決方法は?
<ブロッククオート
Java の
class.getName()
?
いいえ .
ES2015 アップデート
:
の名前
class Foo {}
は
Foo.name
. の名前は
thing
のクラスに関係なく
thing
のタイプは
thing.constructor.name
. ES2015 環境の組み込みコンストラクタには、正しい
name
プロパティがあります。
(2).constructor.name
は
"Number"
.
しかし、ここでは様々なハックを紹介しますが、どれも一長一短で破綻しています。
このハックは、オブジェクトのプロトタイプを変更するもので、人々が嫌がるものです。
Object.prototype.getName = function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
これで、すべてのオブジェクトが機能を持つようになります。
getName()
これはコンストラクタの名前を文字列として返します。私は、これを
FF3
と
IE7
他の実装のことは言えません。
それが嫌なら、JavaScriptで型を決定する様々な方法についての議論を紹介します...。
最近、もう少し網羅的になるように更新したのですが、まだまだです。訂正は大歓迎です...
を使用することで
constructor
プロパティを使用します。
すべて
object
には、その
constructor
プロパティがありますが、その方法によっては
object
が構築され、その値で何をしたいかによって、役に立つか立たないかが決まります。
一般的には
constructor
プロパティを使って、このようにオブジェクトの型をテストすることができます。
var myArray = [1,2,3];
(myArray.constructor == Array); // true
ですから、ほとんどのニーズにはこれで十分です。とはいえ...
注意事項
動作しない すべて 多くの場合
このパターン、壊れているとはいえ、結構あるんですよね。
function Thingy() {
}
Thingy.prototype = {
method1: function() {
},
method2: function() {
}
};
Objects
を介して構築された
new Thingy
を持つことになります。
constructor
を指すプロパティです。
Object
ではなく
Thingy
. というわけで、冒頭から失敗です。
constructor
を、自分が管理していないコードベースで使うことができるのです。
多重継承
あまり知られていない例として、多重継承があります。
function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a
今、物事はあなたが期待するように動作しません。
var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true
そのため、もし
object
テストしている
object
として設定します。
prototype
. これを回避する方法は、この議論の範囲外です。
には、他にも使い道があります。
constructor
プロパティは、面白いものもあれば、そうでないものもあります。今のところ、この議論とは関係ないので、それらの用途について掘り下げることはしません。
クロスフレームやクロスウィンドウでは動作しない
使用方法
.constructor
からのオブジェクトの型をチェックしたい場合、型チェックのために使用すると、壊れてしまいます。
window
オブジェクト、例えば iframe やポップアップウィンドウのようなものです。これは、それぞれのコアタイプに異なるバージョンが存在するためです。
constructor
をそれぞれの `window' で、すなわち
iframe.contentWindow.Array === Array // false
を使用しています。
instanceof
演算子...
は
instanceof
演算子は
object
型と同様に、潜在的な問題があります。
constructor
プロパティを使用します。
var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true
しかし
instanceof
はリテラル値に対して機能しません(なぜならリテラルは
Objects
)
3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false
リテラルは
Object
のために
instanceof
が機能するように、例えば
new Number(3) instanceof Number // true
は
.constructor
のチェックは、リテラルに対してうまく機能します。
.
メソッド呼び出しは、暗黙のうちにリテラルをそれぞれのオブジェクト型にラップしています。
3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true
なぜ3が2つのドットなのか?Javascriptが最初のドットを小数点以下として解釈するからです ;)
クロスフレーム、クロスウィンドウは動作しません。
instanceof
と同じ理由で、異なるウィンドウをまたいで動作することはありません。
constructor
プロパティのチェックを行います。
を使用することで
name
プロパティの
constructor
プロパティを...
動作しない すべて 多くの場合
これも上記を参照。
constructor
は、まったくもって、間違っていて、役に立たない。
IE9では動作しません。
使用方法
myObjectInstance.constructor.name
の名前を含む文字列が得られます。
constructor
関数が使用されますが、この関数に関する注意事項に従います。
constructor
プロパティを使用します。
IE9以上の場合は モンキーパッチ対応 :
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var funcNameRegex = /function\s+([^\s(]+)\s*\(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1] : "";
},
set: function(value) {}
});
}
更新されたバージョン を当該記事より引用。これは記事が公開されてから3ヶ月後に追加されたもので、記事の著者であるMatthew Scharleyが使用を推奨しているバージョンです。この変更は、以下から着想を得ています。 潜在的な落とし穴を指摘するコメント を追加しました。
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var funcNameRegex = /function\s([^(]{1,})\(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1].trim() : "";
},
set: function(value) {}
});
}
Object.prototype.toStringの使用
ということが判明しました。
この記事の詳細
を使用することができます。
Object.prototype.toString
- の低レベルで汎用的な実装である
toString
- すべての組み込み型に対して型を取得するために
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
次のような短いヘルパー関数を書くことができます。
function type(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}
を削除し、型名のみを取得します。
type('abc') // String
しかし、それは
Object
は、すべてのユーザー定義型に対応します。
すべての人のための注意事項...
これらはすべて、1つの潜在的な問題を含んでいます。それは、問題のオブジェクトがどのように構築されたかという問題です。ここでは、さまざまなオブジェクトの構築方法と、さまざまな型チェックの方法が返す値について説明します。
// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // true
(obj.constructor.name == "Foo"); // true
// let's add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // false
(obj.constructor.name == "Foo"); // false
// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object); // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == ""); // true
// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // true
(obj.constructor.name == ""); // true
// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object); // true
(obj.constructor == Object); // true
(obj.constructor.name == "Object"); // true
この例にはすべての組み合わせが含まれているわけではありませんが、あなたのニーズによって物事がどのように混乱するのかを知るには十分な数であることを願っています。もし、あなたが何を求めているかを正確に理解していなければ、微妙な点を理解することができないため、予想外のところでコードが壊れてしまうかもしれません。
注意事項
の議論
typeof
演算子は、一見すると見過ごされているように見えますが、実際には
object
は、非常に単純化されたものであるため、与えられた型である。というのは、非常に単純だからです。
typeof
は重要ですが、今のところ、この議論にはあまり関係がないように感じています。しかし、私の心は、変化することにオープンです。)
関連
-
[解決済み】コンソールがUnterminated JSX contentsエラーを投げる【終了しました
-
[解決済み】PhantomJS 2.1.1を使用してReactJSアプリケーションをレンダリングできない理由とは?
-
[解決済み] 配列から特定の項目を削除するにはどうすればよいですか?
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] あるJavaScriptファイルを他のJavaScriptファイルにインクルードするにはどうすればよいですか?
-
[解決済み] JavaScriptでメールアドレスを検証するのに最適な方法は何ですか?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] JavaScriptで複数行の文字列を作成する
-
[解決済み】別のウェブページにリダイレクトするにはどうすればいいですか?
-
[解決済み】JavaScriptの比較では、どちらの等号演算子(== vs ===)を使うべきですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】TypeError: 'undefined'はオブジェクトではありません。
-
[解決済み】Javascriptのコールバック関数がFirefoxで「Callback is not a function」というエラーを投げる
-
[解決済み】JavaScript ランタイムエラー:'$'が未定義です。
-
[解決済み] ローカルファイルを開くことができません - Chrome: ローカルリソースのロードが許可されていません
-
[解決済み】Uncaught TypeError: 未定義のプロパティ 'msie' を読み取れない - jQuery tools
-
[解決済み】module.exports "モジュールが定義されていません"
-
[解決済み] JavaScriptのオブジェクトのクラスを取得する方法は?
-
[解決済み】ランタイムにオブジェクトのクラス名を取得する
-
[解決済み】Javascriptの変数の型を取得するためのより良い方法?
-
[解決済み] JSオブジェクトの型を確認する最も正確な方法?