JavaScriptオブジェクトを作成しましたが、そのオブジェクトのクラスをどのように判別できますか?
Javaの.getClass()
方法に似たものが欲しいのですが。
class
タイプがありません。それはありません持っているclass
キーワードとclass
方法がより簡単にアクセスすることが可能なプロトタイプを作成するための構文をsuper
。
JavaScriptオブジェクトを作成しましたが、そのオブジェクトのクラスをどのように判別できますか?
Javaの.getClass()
方法に似たものが欲しいのですが。
class
タイプがありません。それはありません持っているclass
キーワードとclass
方法がより簡単にアクセスすることが可能なプロトタイプを作成するための構文をsuper
。
回答:
getClass()
JavaScriptでのJavaに正確に対応するものはありません。ほとんどは、JavaScriptがプロトタイプベースの言語であるためです。Javaがクラスではなく、であるです。
必要なものに応じてgetClass()
、JavaScriptにはいくつかのオプションがあります。
typeof
instanceof
obj.
constructor
func.
prototype
、proto
。isPrototypeOf
いくつかの例:
function Foo() {}
var foo = new Foo();
typeof Foo; // == "function"
typeof foo; // == "object"
foo instanceof Foo; // == true
foo.constructor.name; // == "Foo"
Foo.name // == "Foo"
Foo.prototype.isPrototypeOf(foo); // == true
Foo.prototype.bar = function (x) {return x+x;};
foo.bar(21); // == 42
注:Uglifyを使用してコードをコンパイルしている場合は、グローバルでないクラス名が変更されます。これを防ぐために、Uglifyを持っている--mangle
あなたが使用しているfalseに設定することができていることのparam ゴクゴクやうなり声を。
func.prototype
(はい、関数はオブジェクトですが、prototype
プロパティは関数オブジェクトにのみ関連します)。
instanceof
/ isPrototypeOf()
そして非標準に言及したいかもしれません__proto__
Object.getPrototypeOf()
constructor.name
コードが縮小化されているかどうかに依存しないでください。関数名は任意に変更されます。
construction.name
無視される/最小化されないトークンとして認識されます。(すべてではないにしても)ほとんどの縮小ソフトウェアは例外ルールを提供します。
obj.constructor.name
最新のブラウザでは信頼できる方法です。Function.name
ES6の標準に正式に追加され、JavaScriptオブジェクトの「クラス」を文字列として取得する標準準拠の手段になりました。オブジェクトが次のようにインスタンス化されている場合var obj = new MyClass()
「MyClass」を返します。
数値の場合は「Number」、配列の場合は「Array」、関数の場合は「Function」などが返されます。通常、期待どおりに動作します。失敗するのは、オブジェクトがを介してプロトタイプなしで作成された場合Object.create( null )
、またはオブジェクトが匿名で定義された(名前のない)関数からインスタンス化された場合のみです。
また、コードを縮小する場合、ハードコードされた型文字列と比較するのは安全ではないことにも注意してください。たとえばobj.constructor.name == "MyType"
、ifをチェックする代わりに、代わりにチェックしobj.constructor.name == MyType.name
ます。または、コンストラクタ自体を比較するだけですが、各DOMにはコンストラクタ関数の異なるインスタンスがあるため、これはDOMの境界を越えて機能しません。したがって、それらのコンストラクタでオブジェクト比較を実行しても機能しません。
Function.name
(まだ)JavaScript標準の一部ではありません。現在ChromeとFirefoxでサポートされていますが、IE(10)ではサポートされていません。
obj.constructor.name
名前付き関数でのみ機能します。つまり、を定義するvar Foo = function() {}
と、for var foo = new Foo()
はfoo.constructor.name
空の文字列を返します。
constructor.name
コードが縮小化されているかどうかに依存しないでください。関数名は任意に変更されます。
constructor.name
ES6の新しいクラスサポートで期待どおりに動作することを知っておくと便利です。
この関数は"Undefined"
、未定義の値と"Null"
null に対して戻ります。
他のすべての値の場合、CLASSNAME
-partはから抽出されます[object CLASSNAME]
。これはを使用した結果ですObject.prototype.toString.call(value)
。
function getClass(obj) {
if (typeof obj === "undefined") return "Undefined";
if (obj === null) return "Null";
return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
}
getClass("") === "String";
getClass(true) === "Boolean";
getClass(0) === "Number";
getClass([]) === "Array";
getClass({}) === "Object";
getClass(null) === "Null";
// etc...
"Object"
ます。
return obj.constructor.name
。同じ結果が得られ、さらに非ネイティブオブジェクトも処理されます。
「疑似クラス」を取得するには、次のようにしてコンストラクター関数を取得できます。
obj.constructor
constructor
継承を行うときにが正しく設定されていると仮定します-これは次のようなものです
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
そして、これらの2行と一緒に:
var woofie = new Dog()
がwoofie.constructor
ポイントになりDog
ます。注Dog
コンストラクタ関数で、あるFunction
オブジェクト。しかし、あなたはできるif (woofie.constructor === Dog) { ... }
。
クラス名を文字列として取得したい場合は、次のコードがうまく機能していることがわかりました。
http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects
function getObjectClass(obj) {
if (obj && obj.constructor && obj.constructor.toString) {
var arr = obj.constructor.toString().match(
/function\s*(\w+)/);
if (arr && arr.length == 2) {
return arr[1];
}
}
return undefined;
}
コンストラクター関数を取得して文字列に変換し、コンストラクター関数の名前を抽出します。
obj.constructor.name
うまくいくかもしれないが、それは標準ではないことに注意してください。これはChromeとFirefoxにありますが、IE 9またはIE 10 RTMを含むIEにはありません。
オブジェクトを作成したコンストラクター関数への参照は、constructorプロパティを使用して取得できます。
function MyObject(){
}
var obj = new MyObject();
obj.constructor; // MyObject
実行時にオブジェクトのタイプを確認する必要がある場合は、instanceof演算子を使用できます。
obj instanceof MyObject // true
後方互換性の絶え間ない記録であるECMAScript 6を維持するために、JavaScriptにはまだclass
型がありません(すべての人がこれを理解しているわけではありません)。それはありません持っているclass
そのの一部としてキーワードをclass
プロトタイプ-が、作成するための構文クラスと呼ばれる、まだありません事を。JavaScriptは現在ではなく、かつて古典的なOOP言語ではありませんでした。クラスの観点からJSを話すことは、誤解を招くか、またはプロトタイプの継承をまだグロッキン化していないことを示しているだけです(それを現実に保つだけです)。
つまりthis.constructor
、constructor
関数への参照を取得するための優れた方法です。そして、this.constructor.prototype
試作品自体にアクセスする方法です。これはJavaではないので、クラスではありません。これは、インスタンスがインスタンス化されたプロトタイプオブジェクトです。ES6構文糖を使用してプロトタイプチェーンを作成する例を次に示します。
class Foo {
get foo () {
console.info(this.constructor, this.constructor.name)
return 'foo'
}
}
class Bar extends Foo {
get foo () {
console.info('[THIS]', this.constructor, this.constructor.name, Object.getOwnPropertyNames(this.constructor.prototype))
console.info('[SUPER]', super.constructor, super.constructor.name, Object.getOwnPropertyNames(super.constructor.prototype))
return `${super.foo} + bar`
}
}
const bar = new Bar()
console.dir(bar.foo)
これはそれを使用して出力するものですbabel-node
:
> $ babel-node ./foo.js ⬡ 6.2.0 [±master ●]
[THIS] [Function: Bar] 'Bar' [ 'constructor', 'foo' ]
[SUPER] [Function: Foo] 'Foo' [ 'constructor', 'foo' ]
[Function: Bar] 'Bar'
'foo + bar'
そこにあります!2016年、class
JavaScriptにはキーワードがありますが、それでもクラスタイプはありません。this.constructor
コンストラクタ関数this.constructor.prototype
を取得する最良の方法であり、プロトタイプ自体にアクセスする最良の方法です。
私は今ジェネリックで動作する状況があり、これを使用しました:
class Test {
// your class definition
}
nameByType = function(type){
return type.prototype["constructor"]["name"];
};
console.log(nameByType(Test));
これが、オブジェクトのインスタンスがない場合にタイプ入力によってクラス名を取得する唯一の方法です。
(ES2017で作成)
ドット表記もうまくいきます
console.log(Test.prototype.constructor.name); // returns "Test"
ES6のJavaScriptクラスでは、を使用できますobject.constructor
。以下のサンプルクラスでは、getClass()
メソッドは期待どおりにES6クラスを返します。
var Cat = class {
meow() {
console.log("meow!");
}
getClass() {
return this.constructor;
}
}
var fluffy = new Cat();
...
var AlsoCat = fluffy.getClass();
var ruffles = new AlsoCat();
ruffles.meow(); // "meow!"
getClass
メソッドからクラスをインスタンス化する場合は、必ずブラケットで囲むようにしてください。ruffles = new ( fluffy.getClass() )( args... );
私は丁目で返されるのではなく、IEでobject.constructor.toString()
返却を見つけます。だから、私はhttp://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objectsのコードがIEでうまく機能しない可能性があると思います。次のようにコードを修正しました。[object objectClass]
function objectClass () {}
var getObjectClass = function (obj) {
if (obj && obj.constructor && obj.constructor.toString()) {
/*
* for browsers which have name property in the constructor
* of the object,such as chrome
*/
if(obj.constructor.name) {
return obj.constructor.name;
}
var str = obj.constructor.toString();
/*
* executed if the return of object.constructor.toString() is
* "[object objectClass]"
*/
if(str.charAt(0) == '[')
{
var arr = str.match(/\[\w+\s*(\w+)\]/);
} else {
/*
* executed if the return of object.constructor.toString() is
* "function objectClass () {}"
* for IE Firefox
*/
var arr = str.match(/function\s*(\w+)/);
}
if (arr && arr.length == 2) {
return arr[1];
}
}
return undefined;
};
JavaScriptにはクラスはありませんが、コンストラクター名obj.constructor.toString()
が必要で、必要なものを教えてくれると思います。
.name
です。
.name
でもIE 9で定義されていません
dfaに同意します。そのため、名前付きクラスが見つからない場合は、prototyeをクラスと見なします。
Eli Greyが投稿した機能を、私の考え方に合わせてアップグレードしたものです。
function what(obj){
if(typeof(obj)==="undefined")return "undefined";
if(obj===null)return "Null";
var res = Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
if(res==="Object"){
res = obj.constructor.name;
if(typeof(res)!='string' || res.length==0){
if(obj instanceof jQuery)return "jQuery";// jQuery build stranges Objects
if(obj instanceof Array)return "Array";// Array prototype is very sneaky
return "Object";
}
}
return res;
}
クラスを取得するだけでなく、インスタンスだけから拡張する必要がある場合は、次のように記述します。
持ってみましょう
class A{
constructor(name){
this.name = name
}
};
const a1 = new A('hello a1');
したがって、インスタンスのみを使用してAを拡張するには、
const a2 = new ((Object.getPrototypeOf(a)).constructor())('hello a2')
// the analog of const a2 = new A()
console.log(a2.name)//'hello a2'
私は使用することをお勧めしObject.prototype.constructor.name
ます:
Object.defineProperty(Object.prototype, "getClass", {
value: function() {
return this.constructor.name;
}
});
var x = new DOMParser();
console.log(x.getClass()); // `DOMParser'
var y = new Error("");
console.log(y.getClass()); // `Error'
getClass()
とgetInstance()
を使用して、オブジェクトのクラスの参照を取得できthis.constructor
ます。
function A() {
this.getClass = function() {
return this.constructor;
}
this.getNewInstance = function() {
return new this.constructor;
}
}
var a = new A();
console.log(a.getClass()); // function A { // etc... }
// you can even:
var b = new (a.getClass());
console.log(b instanceof A); // true
var c = a.getNewInstance();
console.log(c instanceof A); // true
function A() {};
A.getClass = function() {
return this;
}
A.getInstance() {
return new this;
}
this.constructor
ですか?
このようなこともできます
class Hello {
constructor(){
}
}
function isClass (func) {
return typeof func === 'function' && /^class\s/.test(Function.prototype.toString.call(func))
}
console.log(isClass(Hello))
これは、入力がクラスかどうかを教えてくれます
JavaScriptはクラスのない言語です。Javaのようにクラスの動作を静的に定義するクラスはありません。JavaScriptは、メソッドや継承などのオブジェクトプロパティを定義するために、クラスではなくプロトタイプを使用します。JavaScriptのプロトタイプを使用して、多くのクラスベースの機能をシミュレートすることが可能です。
class
タイプがありません。それはありません持っているclass
キーワードとclass
方法がより簡単にアクセスすることが可能なプロトタイプを作成するための構文をsuper
。
質問はすでに回答されているようですが、Javaの場合と同様に、OPはオブジェクトのクラスにアクセスする必要があり、選択した回答では不十分です(私見)。
次の説明で、オブジェクトのクラスを取得できます(実際にはJavaScriptではプロトタイプと呼ばれます)。
var arr = new Array('red', 'green', 'blue');
var arr2 = new Array('white', 'black', 'orange');
次のようなプロパティを追加できます。
Object.defineProperty(arr,'last', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
ただし、.last
プロパティはarr
、配列プロトタイプからインスタンス化された ' 'オブジェクトでのみ使用できます。したがって、.last
プロパティをArrayプロトタイプからインスタンス化されたすべてのオブジェクトで使用できるようにするには.last
、Arrayプロトタイプのプロパティを定義する必要があります。
Object.defineProperty(Array.prototype,'last', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
console.log(arr2.last) // orange
ここでの問題は、 ' arr
'および ' arr2
'変数がどのオブジェクトタイプ(プロトタイプ)に属するかを知っている必要があることです。つまり、 ' arr
'オブジェクトのクラスタイプ(プロトタイプ)がわからない場合、それらのプロパティを定義することはできません。上記の例では、arrがArrayオブジェクトのインスタンスであることを認識しているため、Array.prototypeを使用してArrayのプロパティを定義しました。しかし、 ' arr
'のクラス(プロトタイプ)を知らなかった場合はどうなりますか?
Object.defineProperty(arr.__proto__,'last2', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
console.log(arr2.last) // orange
ご覧のとおり、「arr
」が配列であることを知らなくても、「arr
」を使用して「arr.__proto__
」のクラスを参照するだけの新しいプロパティを追加できます。
' arr
'のプロトタイプにアクセスしたのは、それがArrayのインスタンスであることを知らずに、OPが要求したことだと思います。
__proto__
プロパティは廃止されており、prototype
プロパティに対する利点はほとんどありません。