Lấy tên của đối tượng hoặc lớp


204

Có giải pháp nào để lấy tên hàm của một đối tượng không?

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) {...}- không có thông tin về classNamehoặc ObjectName. Có thể có được một trong số họ?


Bạn có thể muốn thấy điều này: stackoverflow.com/questions/789675/
Kẻ

Câu trả lời:


348

Nhận chức năng xây dựng của đối tượng của bạn và sau đó kiểm tra thuộc tính tên của nó .

myObj.constructor.name

Trả về "myClass".


174
Coi chừng! Nếu bạn giảm bớt JavaScript, tên của hàm tạo sẽ thay đổi.
dB.

34
Tiện dụng, nhưng có một cảnh báo khác: nếu đối tượng của bạn có chuỗi nguyên mẫu (ngoài Object), bạn sẽ nhận được tên của liên kết đầu tiên trong chuỗi đó, không phải tên của nhà xây dựng được sử dụng để tạo đối tượng. Lấy ví dụ sau : function Daddy() {}; function Me() {}; Me.prototype = new Daddy; me = new Me;. me.constructor.nameSau đó bất ngờ trở lại 'Daddy', không 'Me'.
mkuity0

7
Cũng đáng biết rằng thuộc tính tên không được hỗ trợ trong <IE9
Jason

9
Và điều này sẽ trả về chuỗi rỗng, nếu được sử dụng trên các đối tượng được khai báo thông qua biến : var Foo = function() {};.
Alexanderr Makov

3
Bảng điều khiển Chrome biết một số thứ bạn không biết: > myclass=(function(){}); new myclassinmyclass {}
Hugh Allen

26

Thí dụ:

function Foo () { console.log('Foo function'); }
var Bar = function () { console.log('Bar function'); };
var Abc = function Xyz() { console.log('Abc function'); };

var f = new Foo();
var b = new Bar();
var a = new Abc();

console.log('f', f.constructor.name); // -> "Foo"
console.log('b', b.constructor.name); // -> "Function"
console.log('a', a.constructor.name); // -> "Xyz"


trông giống như khi sử dụng mẫu mô-đun tiết lộ, bạn sẽ luôn nhận được "Đối tượng". function Foo() { return {'foo':'bar'} }; var f = new Foo(); :(
Brad Kent

5

Nếu bạn sử dụng IIFE tiêu chuẩn (ví dụ với 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 = {}));

bạn có thể chú thích các nguyên mẫu trả trước với

setupReflection(Zamboch, 'Zamboch', 'Zamboch');

và sau đó sử dụng các trường _fullname và _groupname.

var app=new Zamboch.Web.Common.App();
console.log(app._fullname);

chức năng chú thích ở đây:

function setupReflection(ns, fullname, name) {
    // I have only classes and namespaces starting with capital letter
    if (name[0] >= 'A' && name[0] &lt;= '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;
        }
    }
}

JsFiddle


4

Vì điều này đã được trả lời, tôi chỉ muốn chỉ ra sự khác biệt trong cách tiếp cận về việc xây dựng hàm của một đối tượng trong JavaScript. Có một sự khác biệt giữa hàm tạo và tên đối tượng / lớp thực tế. Nếu những điều sau đây làm tăng thêm sự phức tạp cho quyết định của bạn thì có lẽ bạn đang tìm kiếm instanceof. Hoặc có lẽ bạn nên tự hỏi "Tại sao tôi làm điều này? Đây thực sự là những gì tôi đang cố gắng giải quyết?"

Ghi chú:

Các obj.constructor.namekhông có sẵn trên các trình duyệt cũ. Kết hợp (\w+)phải đáp ứng các lớp phong cách ES6.

Mã số:

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));

Kết quả:

nhập mô tả hình ảnh ở đây

Mã: https://jsbin.com/wikiji/edit?js,console


3

Tôi đã phải đối mặt với một khó khăn tương tự và không có giải pháp nào được trình bày ở đây là tối ưu cho những gì tôi đang làm. Những gì tôi có là một loạt các hàm để hiển thị nội dung theo một phương thức và tôi đã cố gắng cấu trúc lại nó theo một định nghĩa đối tượng duy nhất tạo ra các hàm, phương thức của lớp. Vấn đề xuất hiện khi tôi tìm thấy một trong các phương thức tạo ra một số nút điều hướng bên trong phương thức sử dụng một onClick cho một trong các hàm - giờ là một đối tượng của lớp. Tôi đã xem xét (và vẫn đang xem xét) các phương thức khác để xử lý các nút điều hướng này, nhưng tôi đã có thể tìm tên biến cho chính lớp đó bằng cách quét các biến được định nghĩa trong cửa sổ cha. Những gì tôi đã làm là tìm kiếm bất cứ thứ gì phù hợp với 'thể hiện' lớp của tôi và trong trường hợp có thể có nhiều hơn một,

var myClass = function(varName)
{
    this.instanceName = ((varName != null) && (typeof(varName) == 'string') && (varName != '')) ? varName : null;

    /**
     * caching autosweep of window to try to find this instance's 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;
    }
}

1

Thử cái này:

var classname = ("" + obj.constructor).split("function ")[1].split("(")[0];

1
Có trường hợp nào trong đó điều này sẽ chính xác hơn obj.constructor.name không? Tôi chỉ không thấy bất kỳ lý do cho sự phức tạp này.
JHH

1

Tất cả chúng ta cần:

  1. Bọc một hằng số trong một hàm (trong đó tên của hàm bằng với tên của đối tượng chúng ta muốn lấy)
  2. Sử dụng các hàm mũi tên bên trong đối tượng

console.clear();
function App(){ // name of my constant is App
  return {
  a: {
    b: {
      c: ()=>{ // very important here, use arrow function 
        console.log(this.constructor.name)
      }
    }
  }
}
}
const obj = new App(); // usage

obj.a.b.c(); // App

// usage with react props etc, 
// For instance, we want to pass this callback to some component

const myComponent = {};
myComponent.customProps = obj.a.b.c;
myComponent.customProps(); // App

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.