原型(prototype)上的 JavaScript 和默认值

标签 javascript

我对 JavaScript 很陌生。我已经进行了大量的 Google 搜索,但未能找到我想要的答案 - 可能是因为我使用了错误的术语。

前几天,我正在阅读有关创建 JavaScript 组件的基本教程:http://callmenick.com/post/javascript-objects-building-javascript-component-part-2

本教程的一部分涉及一组默认选项,这些选项被分配给类型的原型(prototype)链:

SimpleAlert.prototype.options = {
  wrapper : document.body,
  type : "default",
  message : "Default message."
}

这个想法是,如果用户在构造期间提供不同的参数,则可以使用不同的参数创建 SimpleAlert 类型 - 否则使用默认选项。

SimpleAlert 构造函数如下所示:

function SimpleAlert( options ) {
this.options = extend( {}, this.options ); // Why?
extend( this.options, options );
// start the functionality...
}

并且 extend 函数定义为:

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

我对这段代码的理解是:

创建新的 SimpleAlert 对象需要用户传入自己的 options 对象。假设我传入 { test : "Testing"} 作为 options 参数。然后 extend 函数访问 this.options (我相信它指的是 options 的原型(prototype)实例,因为没有其他 options 范围内定义的变量),本质上将共享实例中的所有内容复制到空 {} 对象,然后将其分配给共享 this.options 实例。

然后,用户提供的 options (在我的例子中 { test : "Testing"}extend int this .options 共享实例(基本上将我的额外 test 字段复制到共享实例中)

但实际上,此示例中的共享实例似乎不受影响 - 这意味着 SimpleAlert.prototype.options 声明保持不变,以便 SimpleAlert 的每个新实例code> 可以访问它(这就是我想要的)

但是,在我的实验中,我发现更改 this.options 会导致原型(prototype)值被修改...我确信我做错的任何事情都很容易修复,但我看不到。这是一个例子:

    var Animal = function(ovr) {
        if (arguments.length > 0)
        {
        this.options.mode = ovr;
        }

    };

    Animal.prototype.options = { mode: "Test" }; / I want this to be default for all instances created

    var test = new Animal("Override"); // set this test obj to use "Overide"
    console.log(test.options.mode); // outputs Override as expected
    var again = new Animal();
    console.log(again.options.mode); // also outputs Override (I want it to say "Test")

感谢您的帮助!

最佳答案

正如您在代码中所建议的,它缺少“复制”操作,因此您正在修改原型(prototype)上的共享对象。

var Animal = function(ovr) {
    if (arguments.length > 0) {
        // Copy whatever is on this.options to a blank object,
        // then assign this.options to be that newly copied object, so
        // the prototype object is masked by the instance object.
        this.options = Object.assign({}, this.options);
        this.options.mode = ovr;
    }
};

这可能有助于理解实例属性如何“掩盖”原型(prototype):

var Foo = function() {
    console.log('a', this.x);
    this.x = 100;
    console.log('b', this.x);
    delete this.x;
    console.log('c', this.x);
};

Foo.prototype.x = 1;

new Foo();

关于原型(prototype)上的 JavaScript 和默认值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37739397/

相关文章:

javascript - 错误: Failed to get Firebase project build. 请确保该项目存在并且您的帐户有权限访问它

javascript - 如何仅在图库内显示“提升缩放”

javascript - CSS Flexbox 显示问题

javascript - 如何从 AdWords 脚本的电子表格应用程序中提取值。 'undefined' 对象的问题

javascript - JSON 编码的多维数组返回错误的语法(意外的])

javascript - 替换 dojo/dijit TabContainer 中特定选项卡的内容?

javascript - Mongodb 在使用异步时保持一致的顺序

javascript - 如何在 jQuery 中找到两个文本点之间的内容?

javascript - IndexedDB:升级 promise ?

javascript - Gmail : What is a jQuery selector for incoming mail senders only? 通常如何使用高度压缩和嵌套的 CSS?