草庐IT

javascript - 从另一个实例更新实例的属性

coder 2024-07-19 原文

我正在寻找更新对象实例的最佳方法,例如在本例中 myParentObjects 的名称属性。我理解实现此目的的唯一方法是将父对象对子对象实例的引用作为参数传递给构造函数中的 new myChildObj(this,name)myChildObj 实例,如 myChildObj.updateParentProperty(name)

我无法想象子对象向下嵌套 4-5 层,并且必须更新其父对象的属性传递 (parent1,parent2,parent3,etc) 它是参数,那将是管理噩梦!必须有更好的方法来更新父属性!

function myParentObj(){
    this.name = 'jordan'
    this.names = ['jordan','danny','cassie'];
    this.init=()=>{
       this.names.forEach((name)=>{
          var childObj = new myChildObj(this,name);
          childObj.updateParentProperty();
       })
    }
}
function myChildObj(parentObj,name){
    this.parent = parentObj;
    this.name = name;
    this.updateParentProperty=()=>{
        this.parent.name = this.name;
    };
}
function init(){
     var parentObj = new myParentObj();
     parentObj.init();
}
document.addEventListener('DOMContentLoaded',init);

问题:更新父对象参数的最佳方法是什么?

最佳答案

让我困惑的是:

this.init=()=>{
   this.names.forEach((name)=>{
      var childObj = new myChildObj(this,name);
      childObj.updateParentProperty();
   })
}

因为一旦创建了所有三个子级,您的父级就会有一个名称 cassie(因为这是调用 updateParentProperty 的最后一个子级)。那和你的标签就是为什么我倾向于声称你正在寻找经典继承,就像这样:

经典传承

function myParentObj (name) {
    this.name = name;
    this.names = ['jordan','danny','cassie'];
    this.init=()=>{
       this.names.forEach((name)=>{
          var childObj = new myChildObj(name);
          console.log(childObj);
       });
    }
}

function myChildObj (name) {
	myParentObj.call(this, name);
  
  // Other stuff, only available for myChildObj
}

function init(){
     var parentObj = new myParentObj();
     parentObj.init();
}
document.addEventListener('DOMContentLoaded',init);

var parent = new myParentObj();
console.log(parent);

这意味着子级从其父级继承属性,但当然不会在他们自己的名称更改时为父级更新它们。

一些简单的观察者模式

好的,您的示例只有一个属性需要注意更改。 我认为像下面示例中的观察者模式有点太多了,但对于大型应用程序来说它非常有用。。观察者模式仅与 JavaScript 不同(参见 enter link description here )。基本上,您有一个应监视更改的对象 (observable) 和一个或多个要根据这些更改执行操作的对象 (observers)。实现可以非常简单(如我的演示)或非常复杂。基本思想是让 observable 维护一个观察者列表。该示例使用自己的简单实现。还有可用的库,我们正在使用 knockout ,它为您的页面提供 MVVM 结构,甚至可以根据更改更新 DOM。

function myParentObj(){
    this.name = 'jordan'
    this.names = ['jordan','danny','cassie'];
    this.init=()=>{
       this.names.forEach((name)=>{
          var childObj = new myChildObj(name);
          childObj.subscribe('name', newValue => this.name = newValue);
       })
    }
}
function myChildObj(name){
    this.subscribers = {};
    
    Object.defineProperty(this, 'name', {
      set: newValue => {
        this._name = newValue;
        this.notify('name');
      },
      get: () => this._name
    });
    
    this.subscribe = function (prop, callback) {
      if (!this.subscribers.hasOwnProperty(prop)) {
        this.subscribers[prop] = [];
      }
      
      this.subscribers[prop].push(callback);
    };
    
    this.notify = function (prop) {
      if (this.subscribers[prop]) {
        this.subscribers[prop].forEach(callback => callback(this[prop]));
      }
    };
}
function init(){
     var parentObj = new myParentObj();
     parentObj.init();
}
document.addEventListener('DOMContentLoaded',init);

var parent = new myParentObj();
var child = new myChildObj('bob');
child.subscribe('name', newName => parent.name = newName);
console.log(parent.name);
child.name = 'cassie';
console.log(parent.name);

使用Object.assign

你也可以使用 Object.assign ,它将所有可枚举属性从一个对象复制到另一个对象。不过,您应该注意,它会复制所有 属性,即使是那些您可能不想更改的属性。

function myParentObj(){
    this.name = 'jordan'
    this.names = ['jordan','danny','cassie'];
    this.init=()=>{
       this.names.forEach((name)=>{
          var childObj = new myChildObj(this,name);
          childObj.updateParentProperty();
       })
    }
}
function myChildObj(name){
    this.name = name;
}

var parent = new myParentObj();
var child = new myChildObj('cassie');
Object.assign(parent, child);
console.log(child);

关于javascript - 从另一个实例更新实例的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44731771/

有关javascript - 从另一个实例更新实例的属性的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  4. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  5. ruby-on-rails - 如果为空或不验证数值,则使属性默认为 0 - 2

    我希望我的UserPrice模型的属性在它们为空或不验证数值时默认为0。这些属性是tax_rate、shipping_cost和price。classCreateUserPrices8,:scale=>2t.decimal:tax_rate,:precision=>8,:scale=>2t.decimal:shipping_cost,:precision=>8,:scale=>2endendend起初,我将所有3列的:default=>0放在表格中,但我不想要这样,因为它已经填充了字段,我想使用占位符。这是我的UserPrice模型:classUserPrice回答before_val

  6. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  7. ruby-on-rails - 如何使用 instance_variable_set 正确设置实例变量? - 2

    我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击

  8. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  9. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  10. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

随机推荐