Ответ 1
Получить объект constructor, а затем проверить его name.
myObj.constructor.name
Возвращает "myClass".
есть ли какое-либо решение для получения имени функции для объекта?
function alertClassOrObject (o) {
window.alert(o.objectName); //"myObj" OR "myClass" as a String
}
function myClass () {
this.foo = function () {
alertClassOrObject(this);
}
}
var myObj = new myClass();
myObj.foo();
for (var k in this) {...} - нет информации о className или ObjectName. Можно ли получить один из них? В PHP это возможно - но я не нашел никакого решения в Интернете, чтобы получить его в javascript.
Получить объект constructor, а затем проверить его name.
myObj.constructor.name
Возвращает "myClass".
Пример:
function Foo () { ... }
var Bar = function () { ... }
var Abc = function Xyz() { ... }
var f = new Foo();
var b = new Bar();
var c = new Abc();
alert(f.constructor.name); // -> "Foo"
alert(b.constructor.name); // -> "Function"
alert(c.constructor.name); // -> "Xyz"
Если вы используете стандартный IIFE (например, с TypeScript)
var Zamboch;
(function (_Zamboch) {
(function (Web) {
(function (Common) {
var App = (function () {
function App() {
}
App.prototype.hello = function () {
console.log('Hello App');
};
return App;
})();
Common.App = App;
})(Web.Common || (Web.Common = {}));
var Common = Web.Common;
})(_Zamboch.Web || (_Zamboch.Web = {}));
var Web = _Zamboch.Web;
})(Zamboch || (Zamboch = {}));
вы могли бы аннотировать прототипы заранее с помощью
setupReflection(Zamboch, 'Zamboch', 'Zamboch');
а затем используйте поля _fullname и _classname.
var app=new Zamboch.Web.Common.App();
console.log(app._fullname);
здесь:
function setupReflection(ns, fullname, name) {
// I have only classes and namespaces starting with capital letter
if (name[0] >= 'A' && name[0] <= 'Z') {
var type = typeof ns;
if (type == 'object') {
ns._refmark = ns._refmark || 0;
ns._fullname = fullname;
var keys = Object.keys(ns);
if (keys.length != ns._refmark) {
// set marker to avoid recusion, just in case
ns._refmark = keys.length;
for (var nested in ns) {
var nestedvalue = ns[nested];
setupReflection(nestedvalue, fullname + '.' + nested, nested);
}
}
} else if (type == 'function' && ns.prototype) {
ns._fullname = fullname;
ns._classname = name;
ns.prototype._fullname = fullname;
ns.prototype._classname = name;
}
}
}
Попробуйте следующее:
var classname = ("" + obj.constructor).split("function ")[1].split("(")[0];
Как уже было сказано, я просто хотел указать на различия в подходах к получению конструктора объекта в JavaScript.
Существует разница между конструктором и фактическим именем объекта/класса. Если следующее дополнение усложняет ваше решение, возможно, вы ищете instanceof
. Или, может быть, вы должны спросить себя: "Почему я это делаю? Неужели это то, что я пытаюсь решить?"
Примечания:
obj.constructor.name
недоступен в старых браузерах.
Соответствие (\w+)
должно удовлетворять классам стиля ES6.
Код:
var what = function(obj) {
return obj.toString().match(/ (\w+)/)[1];
};
var p;
// Normal obj with constructor.
function Entity() {}
p = new Entity();
console.log("constructor:", what(p.constructor), "name:", p.constructor.name , "class:", what(p));
// Obj with prototype overriden.
function Player() { console.warn('Player constructor called.'); }
Player.prototype = new Entity();
p = new Player();
console.log("constructor:", what(p.constructor), "name:", p.constructor.name, "class:", what(p));
// Obj with constructor property overriden.
function OtherPlayer() { console.warn('OtherPlayer constructor called.'); }
OtherPlayer.constructor = new Player();
p = new OtherPlayer();
console.log("constructor:", what(p.constructor), "name:", p.constructor.name, "class:", what(p));
// Anonymous function obj.
p = new Function("");
console.log("constructor:", what(p.constructor), "name:", p.constructor.name, "class:", what(p));
// No constructor here.
p = {};
console.log("constructor:", what(p.constructor), "name:", p.constructor.name, "class:", what(p));
// ES6 class.
class NPC {
constructor() {
}
}
p = new NPC();
console.log("constructor:", what(p.constructor), "name:", p.constructor.name , "class:", what(p));
// ES6 class extended
class Boss extends NPC {
constructor() {
super();
}
}
p = new Boss();
console.log("constructor:", what(p.constructor), "name:", p.constructor.name , "class:", what(p));
Результат:
Я столкнулся с подобной трудностью, и ни одно из представленных здесь решений не было оптимальным для того, над чем я работал. У меня была серия функций для отображения контента в модальном режиме, и я пытался реорганизовать его под одним определением объекта, создавая функции, методы класса. Проблема возникла, когда я обнаружил, что один из методов создал некоторые навигационные кнопки внутри самих модалов, которые использовали onClick для одной из функций - теперь объект класса. Я рассмотрел (и все еще рассматриваю) другие методы обработки этих кнопок навигации, но мне удалось найти имя переменной для самого класса, поместив переменные, определенные в родительском окне. То, что я сделал, это поиск чего-либо, соответствующего "экземпляру" моего класса, и в случае, если может быть больше одного, я сравнил конкретное свойство, которое, вероятно, было бы уникальным для каждого экземпляра:
var myClass = function(varName)
{
this.instanceName = ((varName != null) && (typeof(varName) == 'string') && (varName != '')) ? varName : null;
/**
* caching autosweep of window to try to find this instance variable name
**/
this.getInstanceName = function() {
if(this.instanceName == null)
{
for(z in window) {
if((window[z] instanceof myClass) && (window[z].uniqueProperty === this.uniqueProperty)) {
this.instanceName = z;
break;
}
}
}
return this.instanceName;
}
}