javascript - 扩展 Javascript 对象而不将属性分配给原型(prototype)?

标签 javascript prototype declaration extend

我一直在尝试查看是否有一种方法可以绕过扩展对象的典型过程,它表明它将扩展属性分配给对象的原型(prototype),但附加到当前的“扩展”方法本身目的。我希望直接在当前对象上分配属性(即“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;
}

然后我可以运行此代码来“扩展”我的应用程序对象:

function App() {

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

    console.log(this);

    return this;
}


2)另一种扩展方式是直接使用Object原型(prototype),即:

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

然后扩展应用程序:

function App() {

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

    console.log(this);

    return this;
}

<小时/> 然而,虽然现在在上述任一情况下都可以在 App 对象上访问“command”函数,但它们仍然表明命令函数是 App 原型(prototype)中“extend”方法的扩展。这两个的控制台输出显示: (为了简洁隐藏其他应用程序属性):

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

注意到“App.extend.command”了吗?我想知道是否有任何方法可以扩展属性,使它们成为 App 对象的直接属性,以便原型(prototype)将显示:“prototype:App.command”。

如果我将属性直接分配给“this”,我就可以实现这一点,例如:

function App() {

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

    console.log(this);

    return this;
}

哪些输出:

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

但是,我不想对我的所有属性都使用“this.blah = function()”的格式。我宁愿只使用 JSON 属性列表来扩展当前对象,如前两个示例所示。有没有办法做到这一点,以便我仍然可以保留我的“可更新”函数声明?

我要补充的是,最好不要使用原型(prototype)方法,因为这会将“扩展”属性添加到应用程序中的所有对象,这对于某些对象来说是不可取的。

感谢您的阅读!

最佳答案

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

按照你的方式1)你肯定将对象b的所有属性设置为每个App实例(= this)的自己的属性。这些 Prop 和函数 extend() 不再是应用原型(prototype)的一部分。您可以查看一下:

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实例。

关于javascript - 扩展 Javascript 对象而不将属性分配给原型(prototype)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26830314/

相关文章:

javascript - 剑道击倒 : Window does not close correctly

javascript - 哈希标签、查询字符串和 Ajax 化搜索结果

JavaScript __proto__ 会影响Object中原来的函数吗?

c - 允许静态声明后跟非静态声明的基本原理,但反之则不然

c - 这个数组可以用C语言实现吗?还有其他办法吗?

c - 存储类声明

javascript - 每个对象?

javascript - 为什么这个 JavaScript 函数返回 : "0:0function toString() { [native code] }"?

javascript - 原型(prototype)继承: Can you chain Object.创建?

javascript - AngularJS:TypeScript 编译过程和 gulp-uglify - 有没有办法强制 TS 使用 IIFE 生成函数而不是变量?