简体   繁体   English

在不同的js文件中为对象添加属性和方法

[英]adding properties and methods to object in different js file

I am creating a config.js file having say an object known as contextTokenObject我正在创建一个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
}

Now, I want to add property and methods to that context object from another file (when I am creating my passport stratergy)现在,我想从另一个文件向该上下文对象添加属性和方法(当我创建我的护照策略时)

Instead of pasting entire code, consider passport.js file In this passport.js file,而不是粘贴整个代码,考虑passport.js file在这个passport.js文件中,

I am importing context Token object in this file.我正在此文件中导入上下文令牌对象。

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

Now, say, I want to add following property to my above object现在,比如说,我想将以下属性添加到我上面的对象中

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

Question: How can I do it?问题:我该怎么做?

Update: what I have tried.更新:我尝试过的。 Like mentioned above, I have created an object and I am importing it in my passport strategy如上所述,我创建了一个对象,并将其导入到我的护照策略中

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

then in the passport callback I am doing something like this然后在护照回调中我正在做这样的事情

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

This is throwing following error这是抛出以下错误

Cannot set property 'googleToken' of undefined无法设置未定义的属性“googleToken”

Any help would be appreciated.任何帮助,将不胜感激。

You do have several ways for doing it.你确实有几种方法可以做到这一点。

The first one in node.js will be to export/define that object as global. node.js的第一个是将该对象导出/定义为全局对象。 In that way, you don't even need anymore to import it in the different files.这样,您甚至不再需要将其导入到不同的文件中。 I am going to tell you immediately that this solution, even if it works, and that's pretty a straight forward, it's not my preferred one.我会立即告诉你这个解决方案,即使它有效,而且非常简单,但它不是我的首选。 Global variables are evil in any case .全局变量在任何情况下都是邪恶的

Then of course, it can depend on the case, but usually it is not the best practice to use.那么当然,它可以取决于情况,但通常它不是使用的最佳实践。 That's really error prone and delicated.这真的很容易出错,而且很微妙。 A new module can easily override your global variable for example.例如,新模块可以轻松覆盖您的全局变量。

By the way, you can do that as following:顺便说一下,你可以这样做:

global.contextObject = { ... };

And then you can use it straight forward inside your files.然后你可以直接在你的文件中使用它。 So if you want to add props in another file, you can do directly something like:因此,如果您想在另一个文件中添加道具,您可以直接执行以下操作:

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

Another way to do it, is to use the prototype , but you have to slightly change your syntax when defining the obj in order to use a function constructor, otherwise using the prototype for adding props through an object literal will result in assigning the new props to all the objects, as you can see below:另一种方法是使用prototype ,但在定义obj时必须稍微更改语法以使用函数构造函数,否则使用原型通过对象文字添加道具将导致分配新道具到所有对象,如下所示:

 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);

So the correct way to do it, will be:所以正确的做法是:

 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);

The last way to do it is simply adding plain props to the object, or even better, in these cases when you want to add props to a cusotm object in a lot of places, use Object.defineProperty for defining them, which gives you a lot of more options for the new props.最后一种方法是简单地向对象添加普通道具,或者甚至更好,在这些情况下,当您想在很多地方向 cusotm 对象添加道具时,使用Object.defineProperty来定义它们,这会给您一个新道具的更多选择。

For example you may want that the new props that you assign in the new object can't be changed in some other file, whcih is impossible adding the props with literal syntax.例如,您可能希望您在新对象中分配的新道具不能在其他文件中更改,这是不可能使用文字语法添加道具的。

An example is below:一个例子如下:

 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);

What's the best way to take?最好的方法是什么? That really depends on your use case.这真的取决于您的用例。

I would avoid global variables, and I would avoid literals, so my choice would be to use prototypes and specially use defineProperty for new props in these cases.我会避免使用全局变量,也会避免使用文字,所以我的选择是使用原型,并在这些情况下专门为新道具使用defineProperty But that's really up to you.但这真的取决于你。 All of them achieve what you are looking for.所有这些都实现了您想要的。

contextObject.googleRefreshToken = refreshToken , and so on, contextObject.googleRefreshToken = refreshToken ,依此类推,
or或者
newContextObject = Object.assign(contextObject, refreshToken);

or es6 way或 es6 方式

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM