代码之家  ›  专栏  ›  技术社区  ›  Alwaysblue

向不同JS文件中的对象添加属性和方法

  •  2
  • Alwaysblue  · 技术社区  · 6 年前

    我正在创造一个 config.js 文件中有一个称为ContextTokenObject的对象

    //This holds context information or the information which will be transferred at various places of the app 
    
    let contextToken = {}
    
    module.exports = {
        contextToken
    }
    

    现在,我想从另一个文件(在创建Passport Strategy时)向该上下文对象添加属性和方法。

    不要粘贴整个代码,而是考虑 passport.js file 在这个passport.js文件中,

    我正在导入此文件中的上下文令牌对象。

    const contextObject = require("./config.js") 
    

    现在,比方说,我想向上面的对象添加以下属性

    let TokenToStore = { "googleRefreshToken": refreshToken, "`googleAccessToken": accessToken, "expires_in": params.expires_in}`   
    

    问题: 我该怎么做?

    更新: 我试过的。如上所述,我创建了一个对象,并将其导入到我的Passport策略中。

    const contextObject = require("./../config/context.js")
    

    然后在护照的回拨中我做了这样的事

    passport.use(new GoogleStrategy({
        clientID: process.env.GOOGLE_CLIENT_ID,
        clientSecret: process.env.GOOGLE_CLIENT_SECRET,
        callbackURL:  process.env.GOOGLE_CALLBACK_URL,
        userProfileURL: 'https://www.googleapis.com/oauth2/v3/userinfo',
        accessType: 'offline'
      }, (accessToken, refreshToken, params, profile, cb) => { 
            //Sorting the data we recieve and removing unwanted stuff 
            let profileSort = authHelper.extractGmailProfile(profile)
            //Update refresh token whenever recieved
            let TokenToStore = { "googleRefreshToken": refreshToken, "googleAccessToken": accessToken, "expires_in": params.expires_in}    
            //Context object 
            contextObject.contextToken["googleToken"] = TokenToStore
    

    这将引发以下错误

    无法设置未定义的属性“GoogleToken”

    任何帮助都将不胜感激。

    2 回复  |  直到 6 年前
        1
  •  1
  •   quirimmo    6 年前

    你有几种方法可以做到。

    第一个在 node.js 将导出/定义该对象为全局。这样,您甚至不需要再将其导入到不同的文件中。 我会立即告诉你,这个解决方案,即使它是可行的,而且这是非常直接的,它不是我喜欢的。 全局变量在任何情况下都是邪恶的 .

    当然,它可以取决于具体情况,但通常并不是最佳实践。这很容易出错,而且很容易出错。例如,一个新模块可以很容易地覆盖全局变量。

    顺便说一下,您可以这样做:

    global.contextObject = { ... };
    

    然后你可以直接在你的文件里使用它。因此,如果要在另一个文件中添加道具,可以直接执行以下操作:

    contextObject.TokenToStore = {
      "googleRefreshToken": refreshToken, 
      "googleAccessToken": accessToken, 
      "expires_in": params.expires_in
    };
    

    另一种方法是使用 prototype 但是在定义 obj 为了使用函数构造函数,否则通过对象文本使用原型添加props将导致为所有对象分配新的props,如下所示:

    const obj = { firstProp: 'I am a first prop' };
    console.log(obj);
    Object.getPrototypeOf(obj).secondProp = 'I am a second prop';
    console.log(obj);
    const obj2 = { test: 'I am a test' };
    console.log(obj2);

    所以正确的方法是:

    const obj = new function () { 
      this.firstProp = 'I am a first prop';
      return this; 
    };
    console.log(obj);
    // then export your obj
    // In the other file import back your obj and add things to the prototype
    Object.getPrototypeOf(obj).secondProp = 'I am a second prop';
    console.log(obj);
    const obj2 = { test: 'I am a test' };
    console.log(obj2);

    最后一种方法是简单地向对象添加普通的props,甚至更好,在这些情况下,如果您想在很多地方向CUSOTM对象添加props,请使用 Object.defineProperty 定义它们,这为新的道具提供了更多的选择。

    例如,您可能希望在新对象中分配的新属性不能在其他文件中更改,因为不能用文字语法添加属性。

    示例如下:

    const obj = { firstProp: 'I am a first prop' };
    console.log(obj);
    // then export it
    // import it somewhere else
    obj.secondProp = 'I am a second prop';
    console.log(obj);
    // or assign it with defineProperty
    Object.defineProperty(obj, 'secondProp', {
      value: 'I am a not changable second prop',
      writable: false
    });
    console.log(obj);
    // the following will be ignored
    obj.secondProp = 'new value';
    console.log(obj);

    最好的方法是什么? 这取决于您的用例。

    我将避免使用全局变量,并避免使用文本,因此我的选择是使用原型并特别使用 defineProperty 对于这些情况下的新道具。 但这完全取决于你。 所有这些都实现了你想要的。

        2
  •  0
  •   Nikko Khresna    6 年前

    contextObject.googleRefreshToken = refreshToken 等等,

    newContextObject = Object.assign(contextObject, refreshToken);

    或ES6方式

    newContextObject = { ...contextObject, ...refreshToken }