另一个对象内的对象初始化

时间:2018-12-18 21:49:02

标签: javascript

今天,我在玩Backbone和Javascript,遇到了一个有趣的问题。请考虑以下内容:

var App = {};
App.model = Backbone.Model.Extend({/* Omitted for brevity */});
App.view = Backbone.View.Extend({/* Omitted for brevity */});
App.obj = new App.view();

在这一点上,我出于可读性和可维护性的原因进行重构:

var App = {
   model: Backbone.Model.Extend({}),
   view: Backbone.View.Extend({}),
   obj: new view()  // Here comes trouble
}

上面的代码段是我想要获得的,但是显然初始化不起作用:

  • view不在范围内
  • App尚未初始化,因此App.view不可用。
  • this指的是window,因此this.view不可用。

这时,在case-insensitive list sorting, without lowercasing the result?的帮助下,我制定了一个解决方案:

var App = {
   model: Backbone.Model.Extend({}),
   view: Backbone.View.Extend({}),
   get obj() { delete this.obj; this.obj = new this.view(); return this.view; }
}

使用吸气剂,我可以将对象实例的创建推迟到使用为止(因此,在完成App初始化之后),然后使用对象实例从内部替换吸气剂。

一切正常,但是由于我不太熟练使用现代JS,所以我想知道是否有其他或适当的方法来实现我想要的目标。我还想知道这种实现方式是否会导致我没有考虑的缺点或意外问题。

1 个答案:

答案 0 :(得分:0)

首先,我要感谢大家的见解。为了完善起见,我想发布一种似乎是获得我想要的东西的最好且不太讨厌的方法。虽然我的骇客作品行之有效,但绝不应该使用它,而将文字转换为构造函数也能获得相同的结果,而不会受到骇客的攻击:

import React, { Component } from 'react';
import Table from './Table.js';

class App extends Component {
     state = {
            characters:[
                            {
                'name': 'Charlie',
                'job': 'Janitor'
            },
            {
                'name': 'Mac',
                'job': 'Bouncer'
            },
            {
                'name': 'Dee',
                'job': 'Aspiring Actress'
            },
            {
                'name': 'Dennis',
                'job': 'Bartender'
            }
            ]
        };

     removeCharacter = index => {
      const { characters } = this.state;

        this.setState({
            characters: characters.filter((character, i) => {
                return i !== index;
            })
        });
     }

    render(){
      const { characters } = this.state;
      return (
            <div className="container">
                <Table characterData={characters} />
            </div>
        );
    }
}

export default App;

此版本保持干燥,并具有两个附加的好处:实例化和“私有”成员。它很容易这样重写:

function App() {
   this.model: Backbone.Model.Extend({});
   this.view: Backbone.View.Extend({});
   this.obj = new this.view();
}
var app = new App();

这将使function App() { var model: Backbone.Model.Extend({}); var view: Backbone.View.Extend({}); this.obj = new view(); } var app = new App(); model都无法访问,同时可以轻松访问view。当然,如果实例化是不希望有的效果,那么app.obj不会胜过一切。

还要注意,由于我的示例具有Backbone功能,因此在欢迎可扩展性时可能建议使用构造方法,并且可以通过var App = {}添加该类的原型。这是骨干网的方式:

_.extend()

参考:_.extend()object constructorsliterals vs. constructors