【问题标题】:Javascript: Instance name in a class methodJavascript:类方法中的实例名称
【发布时间】:2014-01-25 13:13:47
【问题描述】:
<html>
<body>
<div id="output"></div>

<script>
    function jExgTrend(){

    }

    jExgTrend.prototype.Start = function(text)
    {
        //this must return Instance name : "TestObj"
        var InstanceName = "TestObj";

        document.getElementById("output").innerHTML = "<a href=\"javascript:"+InstanceName+".Notify('"+text+"');\">"+text+"</a>";

    }

    jExgTrend.prototype.Notify = function(msg)
    {
        alert(msg);
    }

    var TestObj = new jExgTrend();
    TestObj.Start("Text of the link");

</script>


</body>
</html>

我该怎么做这样的事情? “Start”方法应该返回类实例的名称。

我知道这个问题很愚蠢:-(

【问题讨论】:

标签: javascript class object


【解决方案1】:

也许你真正需要的是一个 ID,而不是一个名字。
提供 id 是您可以通过添加到 Object 的原型或仅添加到您感兴趣的类的方法轻松添加的东西:

var idGetter = (function() {
       var currentId = 0;
       return function() {
               // 1. replace 'id' with a readonly property
               //      that will return id for this object
               var thisId = currentId ;
               Object.defineProperty( this, 'id', 
                       { get : function () { return thisId; } } ) ;
               // 2. for the first run of id, return object id
               return currentId++;
       }
}());

Object.defineProperty( Object.prototype, 'id', { get : idGetter } );

使用小例子:

var someObject = {};
console.log(someObject.id);  // outputs 0

var someObject2 = {};
console.log(someObject2.id); // outputs 1

请注意 Object.defineProperty 默认为不可枚举的属性,因此您的对象不会被此属性“污染”(例如,使用 for..in 时)。

【讨论】:

  • "也许你真正需要的是一个 id,而不是一个名字。"此代码将为所有对象添加“id”属性,该属性将使用唯一编号标识每个对象。这取决于您打算如何处理对象的名称/ID。如果它没有用,我将删除答案。
【解决方案2】:

你不能。您可以在实例化时指定名称:

function JExgTrend(name){ this.name = name || 'no name specified'; }
JExgTrend.prototype.Start = function () {
                              alert(this.name);
                            }

var testObj = new JExgTrend('testObj');
var otherTestObj = new JExgTrend('otherTestObj');
var anon = new JExgTrend;
testObj.Start();      //=> testObj
otherTestObj.Start(); //=> otherTestObj 
anon.Start();         //=> no name specified

一个有点异国情调的替代方案:您可以像这样编写构造函数:

function JExgTrend(name,scope) {
  name = name || ( Math.floor( 10000+Math.random()*100000000000) ).toString(16);
  if (!(this instanceof JExgTrend)) {
    return new JExgTrend(name,scope);
  }
  this.name = name;
  if (!JExgTrend.prototype.myname) { 
    JExgTrend.prototype.myname = function(){ console.log(this.name); };
  }
  return (scope || window)[this.name] = this;
}

然后像这样分配对象:

jExgTrend.call(null, 'testObj');
testObj.myname(); //=> testObj

试着摆弄@this jsFiddle

【讨论】:

  • 这是我已经使用过的解决方案......但我不喜欢它:-(
  • @epasinetti:在答案中添加了一个 jsFiddle 链接
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-19
  • 2015-01-17
  • 2019-02-27
  • 1970-01-01
  • 2020-06-30
  • 2011-01-14
相关资源
最近更新 更多