DNB*_*ims 665 javascript oop
我创建了一个JavaScript对象,但是我如何确定该对象的类?
我想要类似于Java的.getClass()
方法.
ear*_*arl 930
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
Run Code Online (Sandbox Code Playgroud)
注意:如果您使用Uglify编译代码,它将更改非全局类名.为了防止这种情况,Uglify有一个--mangle
可以设置为false的参数是使用gulp或grunt.
dev*_*os1 273
obj.constructor.name
Run Code Online (Sandbox Code Playgroud)
是现代浏览器中的可靠方法.Function.name
被正式添加到ES6的标准中,使其成为符合标准的手段,将JavaScript对象的"类"作为字符串.如果对象被实例化var obj = new MyClass()
,它将返回"MyClass".
它将为数字返回"Number",为数组返回"Array",为函数返回"Function"等.它通常按预期运行.它失败的唯一情况是如果创建的对象没有原型,通过Object.create( null )
,或者对象是从匿名定义的(未命名的)函数实例化的.
另请注意,如果要缩小代码,则与硬编码类型字符串进行比较是不安全的.例如,而不是检查是否obj.constructor.name == "MyType"
,而不是检查obj.constructor.name == MyType.name
.或者只是比较构造函数本身,但是这不会跨DOM边界工作,因为每个DOM上有不同的构造函数实例,因此在它们的构造函数上进行对象比较是行不通的.
奇怪的是,Function.name
返回原型链中使用的最基本函数的名称,遗憾的是这不是直观的.例如,如果var obj = new MyClass()
从prototypically导出Object.create( null )
和创建的新实例obj.constructor.name == "MyType"
,obj.constructor.name == MyType.name
,Function.name
返回"A",这似乎是错误的.然而,它确实适用于单级原型和所有原语.
Mak*_*dyk 33
我们可以通过执行“instance.constructor.name”来读取实例的类名称,如下例所示:
class Person {
type = "developer";
}
let p = new Person();
p.constructor.name // Person
Run Code Online (Sandbox Code Playgroud)
Eli*_*rey 28
该函数返回"undefined"
,"null"
或者"class"
在[object class]
从Object.prototype.toString.call(someObject)
.
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...
Run Code Online (Sandbox Code Playgroud)
nop*_*ole 18
要获得"伪类",可以通过获取构造函数
obj.constructor
Run Code Online (Sandbox Code Playgroud)
假设在constructor
执行继承时正确设置 - 这类似于:
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
Run Code Online (Sandbox Code Playgroud)
和这两行,以及:
var woofie = new Dog()
Run Code Online (Sandbox Code Playgroud)
会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;
}
Run Code Online (Sandbox Code Playgroud)
它获取构造函数,将其转换为字符串,并提取构造函数的名称.
请注意,obj.constructor.name
本来可以运作良好,但它不是标准的.它在Chrome和Firefox上,但不在IE上,包括IE 9或IE 10 RTM.
CMS*_*CMS 12
您可以使用构造函数属性获取对创建该对象的构造函数的引用:
function MyObject(){
}
var obj = new MyObject();
obj.constructor; // MyObject
Run Code Online (Sandbox Code Playgroud)
如果需要在运行时确认对象的类型,可以使用instanceof运算符:
obj instanceof MyObject // true
Run Code Online (Sandbox Code Playgroud)
我现在有一种情况可以通用工作,并使用了以下方法:
class Test {
// your class definition
}
nameByType = function(type){
return type.prototype["constructor"]["name"];
};
console.log(nameByType(Test));
Run Code Online (Sandbox Code Playgroud)
如果您没有对象的实例,那就是我发现通过类型输入获取类名称的唯一方法。
(用ES2017编写)
点符号也可以
console.log(Test.prototype.constructor.name); // returns "Test"
Run Code Online (Sandbox Code Playgroud)
对于 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!"
Run Code Online (Sandbox Code Playgroud)
如果您从getClass
方法实例化类,请确保将其包装在括号中,例如ruffles = new ( fluffy.getClass() )( args... );
为了保持其向后兼容的不间断记录ECMAScript 6,JavaScript仍然没有class
类型(尽管不是每个人都理解这一点)。它确实在创建原型时将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)
Run Code Online (Sandbox Code Playgroud)
这是使用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'
Run Code Online (Sandbox Code Playgroud)
你有它!在2016年,class
JavaScript中有一个关键字,但仍然没有类类型。this.constructor
是获取构造函数this.constructor.prototype
的最佳方法,也是访问原型本身的最佳方法。
不要使用o.constructor
,因为它可以被对象内容更改。相反,使用Object.getPrototypeOf()?.constructor
.
const fakedArray = JSON.parse('{ "constructor": { "name": "Array" } }');
// returns 'Array', which is faked.
fakedArray.constructor.name;
// returns 'Object' as expected
Object.getPrototypeOf(fakedArray)?.constructor?.name;
Run Code Online (Sandbox Code Playgroud)
如果您不仅需要 GET 类,还需要从只有一个实例的角度扩展它,请编写:
让我们
class A{
constructor(name){
this.name = name
}
};
const a1 = new A('hello a1');
Run Code Online (Sandbox Code Playgroud)
因此,要扩展 A 仅使用实例:
const a2 = new (Object.getPrototypeOf(a1)).constructor('hello from a2')
// the analog of const a2 = new A()
console.log(a2.name)//'hello from a2'
Run Code Online (Sandbox Code Playgroud)