扩展Javascript对象而不为原型分配属性?

时间:2014-11-09 16:21:23

标签: javascript prototype declaration extend

我一直试图看看是否有一种绕过扩展对象的典型过程的方法,它表明它将扩展属性分配给对象的原型,但附加到'延伸'方法本身就当前对象。我希望在当前对象上直接分配属性(即" this.property"而不是" this.extend.property")。让我解释一下:

据我所知,有两种方法可以扩展" Javascript中的一个对象:


1)全球职能:

function extend(a, b){
    for(var key in b)
        if(b.hasOwnProperty(key))
            a[key] = b[key];
    return a;
}

然后我可以将此代码运行到"扩展"我的App对象:

function App() {

    extend(this, {
        command: function () {
            alert('command!');
        }
    });

    console.log(this);

    return this;
}


2)扩展的另一种方法是直接使用Object原型,即:

Object.prototype.extend = function(obj) {
   for(i in obj)
      this[i] = obj[i];
};

然后使用以下内容扩展App:

function App() {

    this.extend({
        command: function () {
            alert('command!');
        }
    });

    console.log(this);

    return this;
}

<小时/> 但是,虽然&#39;命令&#39;现在可以在上面的任何一种情况下在App对象上访问该函数,它们都显示命令函数是&#39; extend&#39;的扩展。 App原型中的方法。这两个显示的控制台输出:     (为简洁起见隐藏其他App属性):

command: function () {
    arguments: null, 
    caller: null, 
    length: 0, 
    name: "", 
    prototype: App.extend.command
}

请注意&#39; App.extend.command&#39;?我想知道是否有任何方法来扩展属性,使它们是App对象的DIRECT属性,因此原型将显示:&#34; prototype:App.command&#34;。

如果我将属性直接分配给&#34;这个&#34;,我可以做到这一点,如:

function App() {

    this.command = function () {
        alert('command!');
    }

    console.log(this);

    return this;
}

哪个输出:

command: function () {
    arguments: null, 
    caller: null, 
    length: 0, 
    name: "", 
    prototype: App.command
}

但是,我不想使用&#34; this.blah = function()&#34;的格式。我所有的财产。我宁愿只使用JSON属性列表扩展当前对象,如前两个示例所示。无论如何要做到这一点,以便我仍然可以保持我的新的&#39;函数声明?

我将补充一点,不要使用原型方法,因为这会增加&#39;扩展&#39;属性到应用程序中的所有对象,这对某些对象来说是不可取的。

感谢阅读!

1 个答案:

答案 0 :(得分:1)

为了更清楚地了解你应该检查你在Firefox中使用Firebug发布的所有三种方式。 webkit-consoles输出的内容与App.prototype无关,而是所有函数的层次结构,用于设置command - 属性。您在App.__proto__下找到的App.prototype。

用你的方式1)你肯定将对象b的所有属性设置为每个App实例的自己的属性(= this)。这些道具以及功能extend()变为部分App 原型。你可以看一下:

console.log(App.prototype);
// or you create an instance of App and search for its prototype:
var myapp = new App(); console.log(Object.getPrototypeOf(myapp));

当您在App构造函数中合并函数extend()时,您获得与1)完全相同的结果:

function App(b) {
    if (typeof b == 'object') for (var key in b) this[key] = b[key];
    console.log(this);
    // Aside: you don't need 'return this', it's done automatically when you use 'new App()'
}
var obj = {command: function () {alert('command!');}};
var myapp = new App(obj);

我更喜欢这种方法,因为很容易通过将它们作为参数传递来规定哪个App对象获取了哪些属性。

只有你的方式2)函数extend()成为App.prototype的属性,因为你明确地定义它。然后它继承了所有App实例。