繁体   English   中英

调用 JavaScript 中的 object 后的默认字符串值

[英]Default string value after call the object in JavaScript

我有一个 js object,其中我从 api 返回我的端点地址。 这对我来说是一个非常好的解决方案,它看起来像这样:

export const API_BASE_URL = 'http://localhost:3000';
export const USERS = '/Users';

export default {
  users: {
    checkEmail: (email) => `${API_BASE_URL}${USERS}/${email}/checkEmail`,
    notifications: `${API_BASE_URL}${USERS}/notifications`,
    messages: `${API_BASE_URL}${USERS}/messages`,
  },
};

现在我可以在我的 redux-saga 中调用这个地址来执行 xhr 查询:

import { api } from 'utils';

const requestURL = api.users.notifications; 

但我有点卡住了,因为现在我遇到了一个问题 - 这里缺少基本路径: '/users'

现在当我调用api.users时,我得到一个 object。 我想在调用 object 后有一个默认值,例如:

import { api } from 'utils';

const requestURL = api.users; // http://localhost:3000/Users
const requestURL2 = api.users.notifications; // http://localhost:3000/Users/notifications

我知道我可以在 object 中添加一个名为“base”的新字符串并在那里添加“/Users”,但我不喜欢这个解决方案,我认为有更好的解决方案。

您可以执行以下操作之一:

扩展字符串 class

const API_BASE_URL = "http://localhost:3000"
const USERS = "/Users"

class UsersEndpoints extends String {
  constructor(base) {
    super(base)
  }
  // this is still a proposal at stage 3 to declare instance variables like this
  // if u want a truly es6 way you can move them to the constructor
  checkEmail = (email) => `${API_BASE_URL}${USERS}/${email}/checkEmail`
  notifications = `${API_BASE_URL}${USERS}/notifications`
  messages = `${API_BASE_URL}${USERS}/messages`
}

// you can use userEndpoints itself as a string everywhere a string is expected
const userEndpoints = new UsersEndpoints(API_BASE_URL)
export default {
   users: userEndpoints
}

前一个实际上相当于

...
const userEndpoints = new String(API_BASE_URL)
userEndpoints.notifications = `${API_BASE_URL}${USERS}/notifications`
...

显然这是不推荐的:你不应该扩展原生类,这种方法有很多缺点。 一个明显的例子是,您使用的属性与本机 class 可能带来的属性之间可能存在冲突

覆盖 toString 方法

...
export default {
  users: {
    checkEmail: (email) => `${API_BASE_URL}${USERS}/${email}/checkEmail`,
    notifications: `${API_BASE_URL}${USERS}/notifications`,
    messages: `${API_BASE_URL}${USERS}/messages`,
    toString: () => API_BASE_URL
  },
};
// this is actually not much different than the previous method, since a String is an objet with an overridden toString method.
// That said this method is also not recommended since toString is used in many places in native code, and overriding it just to substitute a string value will make information get lost in such places, error stacks for example

使用针对此类用例的语言功能实现您想要的

您要问的是使相同的变量同时具有不同的值,这在语言语法中是不可能的,这是有道理的,因为它很难推理代码。

话虽如此,我推荐以下性质的东西

// it is also better to use named exports
export const getUsersEndpoint = ({
  path = "",
  dynamicEndpointPayload = {},
} = {}) => {
  switch (path) {
    case "notifications":
      return `${API_BASE_URL}${USERS}/notifications`
    case "messages":
      return `${API_BASE_URL}${USERS}/messages`
    case "checkEmail":
      return `${API_BASE_URL}${USERS}/${dynamicEndpointPayload.email}/checkEmail`
    // you still can do checkEmail like this, but the previous is more consistent
    // case "checkEmail":
    //   return (email) => `${API_BASE_URL}${USERS}/${email}/checkEmail`
    default:
      return `${API_BASE_URL}`
  }
}

// you can use it like this
getUsersEndpoint() // returns the base
getUsersEndpoint({path: 'notifications'})

您可以扩展原型来实现此行为:

export const API_BASE_URL = 'http://localhost:3000';
export const USERS = '/Users';

const users = `${API_BASE_URL}${USERS}`

const baseUrls = {
  checkEmail: (email) => `${users}/${email}/checkEmail`,
  notifications: `${users}/notifications`,
  messages: `${users}/messages`,
}

Object.setPrototypeOf(users.__proto__, baseUrls);

export default {
  users
};

尝试让 object 将所有用户端点和返回端点值的 function

    const user = {
    default: '/users',
    notification: '/notification',
    profile: '/profile',
    getEndPoint(prop) {
    if(this[prop] === 'default' ){
        return this[prop];
     }   else {
        if(this[prop]) {
            return  this.default + this[prop];
        }
     }

     }
   }

因此,您可以拥有更多属于用户的端点,您可以简单地调用

const requestURL = api.user.getEndPoint('default'); // http://localhost:3000/Users
const requestURL2 = api.user.getEndPoint('notifications'); // http://localhost:3000/Users/notification

暂无
暂无

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

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