Javascript,将属性推送到父级的范围

时间:2014-08-15 00:36:00

标签: javascript node.js

我正在构建一些node.js模块,我有一些我想要推入这个对象的库

在这个参议员中,我有

app.js

var api = require('./scripts/api.js');
var oauth = require('./scripts/oauth.js');
var db = require('./scripts/db.js')
var libraries  = {
    api : api,
    db : db,
    oauth : oauth,
}

var modules = require('./scripts/module.js');
modules.init(app, libraries);

module.js

module.exports = { 

    init : function(app,libraries) {
        for (key in libraries) {
            if (libraries.hasOwnProperty(key)) {
                this[key] = libraries[key]
            }
        }

        this.oauth.init(app,libraries);
    }
}

api.js

module.exports = { 

init : function(app, libraries) {
    for (key in libraries) {
        if (libraries.hasOwnProperty(key)) {
            this[key] = libraries[key]
        }
    }
    app.get('/api/linkedin/posts', function (req, res) {

        //get the credentials
        var userid = req.session.user_id;
        var credentials = '';
        getCredentials('linkedin',userid)
            .then(function(result) {
                this.db.store(credentials = JSON.parse(result))
                    })
    });
}, 
}

并且它工作正常,但我想要发生的不是将其推送到模块对象本身。将它推送到对象范围,这样我就不必将this.library.function()添加到所有内容中。通过这种方式,我可以直接调用oauth.init()并直接访问库,有没有什么好办法呢?

我想要完成的将是具有相同的效果,就像我做了以下操作一样,我只是想让这些引导方法变得神奇

module.js

var api = {}
var oauth = {}

module.exports = { 

    init : function(app,libraries) {
        api = libraries.api
        oauth = libraries.oauth

        oauth.init(app,libraries);
    }
}

这是展示问题http://jsbin.com/cadejukijudu/1/edit

的小提琴

2 个答案:

答案 0 :(得分:1)

@Matthew Bucci:你的问题让我非常困惑 - 不是因为你的编码风格,而是因为对问题的描述和程序设计 - 所以我开始稍微重写你的问题和添加评论。希望问题及其答案将变得明显;如果不是我,那么别人。


您的问题:

App.js

var libraries = {
    "api": require('./scripts/api.js'),
    "db": require('./scripts/db.js'),
    "oauth": require('./scripts/oauth.js')
};

var modules = require('./scripts/module.js');
modules.init(app, libraries);
// Where does the app variable come from?
// The naming of your script "module.js" is confusing,
// because node has a built-in module called module...

Module.js

module.exports = {
    "init": function (app, libraries) {
        var key;
        for (key in libraries) {
            if (libraries.hasOwnProperty(key)) {
                this[key] = libraries[key];
                // So you effectively want to copy all properties of libraries
                // to the object in the variable modules in app.js?
            }
        }
        this.oauth.init(app, libraries);
        // I assume the oauth object, required in app.js, also has an init property.
        // So you effectively want to copy all properties of libraries to the modules
        // object and to the oauth object contained in the modules object!?
        // Just pointing out, you're using the same app variable passed in app.js,
        // which in this context is an argument of the module.js .init function.
    }
};

api.js


猜测回答:

init.js

global.api = require('./scripts/api.js');
global.oauth = require('./scripts/oauth.js');
global.db = require('./scripts/db.js');
// Any initialization of required objects is best done when the respective code is
// evaluated, i.e. the first time they're required; Initialization code should be 
// included in respective modules.

app.js

api; // Not available yet!
require('./scripts/init.js');
api; // Refers to the result of require('./scripts/api.js') initialized in init.js
oauth; // idem, etc.

总之:我认为你正在处理一个你不应该处理的问题。物品没有范围,也没有父母。嵌套对象形成的属性树是单向的,因为单个对象可以是多个其他对象的属性;因此,通常从嵌套对象中检索对嵌套对象的引用是非常不可行的;它需要你编写一个非常复杂的搜索功能,这在执行时会非常昂贵。如果要将一个对象的属性复制(推送)到另一个对象 - 无论是否嵌套在另一个对象中 - 只需创建一个公共复制函数;您必须明确告诉函数需要将哪些内容复制到什么内容。

函数具有范围,并且使用let语句块语句可以具有范围。对象的花括号不是块语句。

答案 1 :(得分:0)

我发现我可以通过在没有var关键字的init函数中声明它来强制执行此操作,假设范围是GLOBAL然后,这是可怕的做法

http://jsfiddle.net/4wjbyy9g/6/

  this.init = function(libraries)
  {
     for (var key in libraries) {
        var messy = key + " = libraries[key] "

        eval(messy)
     }
     oauth.log('yay!');
  };

可以通过手动声明模块中的变量来避免全局范围问题,但这并不像我喜欢的那样干净,因为我必须手动声明每个变量名称。然而,这是迄今为止我发现的最干净的解决方案

function module()
{
  var oauth = {} //I don't want to have to write this to keep it out of the global scope

  this.init = function(libraries) {
     for (var key in libraries) {
        var messy = "if (typeof " + key + " !== 'undefined') {"
        messy += key + " = libraries[key] }"

        eval(messy)
     }
     oauth.log('yay!');
  }

  this.test = function() {
     oauth.log(JSON.stringify(oauth))     
  }
}

http://jsfiddle.net/52ea5t0q/6/