我制作了一个JavaScript对象,无法对其进行迭代,甚至无法访问其参数。我想念什么?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我制作了一个JavaScript对象,无法对其进行迭代,甚至无法访问其参数。我想念什么?相关的知识,希望对你有一定的参考价值。

当我在Chrome中登录时,这是我的对象:


de: path: "/assets/trads/de.json", trads: …
en: path: "/assets/trads/en.json", trads: …
es: path: "/assets/trads/es.json", trads: …
fr: path: "/assets/trads/fr.json", trads: …
it: path: "/assets/trads/it.json", trads: …
nl: path: "/assets/trads/nl.json", trads: …
ru: path: "/assets/trads/ru.json", trads: …
__proto__: Object

这里是我登录时的类型:

Object

如果我尝试:

console.log(obj.en);
console.log(obj['en']);
console.log(obj.length);

我得到:

undefined

如果我这样做:

Object.keys(obj).forEach(e => console.log(e));
for (let i in obj)  console.log(obj[i] 
for (let i in obj)  console.log(i) 

我什么也没得到。

我是如何从createTradsObjFrom()制作对象的(在客户端运行,获取包含某些内容翻译的JSON文件):

const getJson = path => 
  return new Promise((resolve, reject) => 
    $.getJSON(path, json => 
      if (!json) return reject(new Error('Error while trying to get json for assets trads.'));
      return resolve(json);
    );
  );
;

const createTradsObjFrom = (languages, tradsPaths) => 
  return new Promise((resolve, reject) => 
    try 
      const obj = ;
      languages.forEach(async (lang, index) => 
        const path = tradsPaths[index];
        obj[lang] = 
          path,
          trads: await getJson(path)
        ;
      );
      console.log('obj : ', obj);
      return resolve(obj);
    
    catch (err) 
      return reject(new Error(err));
    
  );
;

const getTrads = currentLanguage => 
  return new Promise((resolve, reject) => 
    const tradsDir = "/assets/trads/";
    const languages = [
      "de",
      "en",
      "es",
      "fr",
      "it",
      "nl",
      "ru"
    ];
    const tradsPaths = languages.map(e => tradsDir + e + '.json');
    createTradsObjFrom(languages, tradsPaths)
    .then(trads => resolve(trads))
    .catch(err => reject(err));
  );
;

感谢您的帮助,我已经花了太多时间在此上。 :)

答案

首先,您正在使用一种创建诺言的反模式,该诺言的调用已经返回了诺言/可续签。例如,$.getJSON返回一个可以用于await的对象。

const getJson = path => 
  return $.getJSON(path);
;

//or just change
trads: await getJson(path)
//to use $.getJSON directly
trads: await $.getJSON(path)

第二forEach()不使用promise,因此使其成为回调async无关紧要,因为它不会等待该promise解决。您将需要使createTradsObjFrom本身异步并使用常规循环

const createTradsObjFrom = async (languages, tradsPaths) => 
  try 
    const obj = ;
    //set index,lang by destructuring
    for(let [index,lang] of languages.entries())
      const path = tradsPaths[index];
      obj[lang] = 
        path,
        //just call $.getJSON directly unless needing extra work done
        trads: await $.getJSON(path)
      ;
    
    console.log('obj : ', obj);
    return obj;
  
  catch (err) 
    //since async functions don't provide a reject method we 
    //need to throw an error to cause a rejection
    throw new Error("some error");
  
;

现在您可以只返回createTradsObjFrom()或直接拨打电话给它,]

const getTrads = currentLanguage => 
  //again don't need to make a new promise here as 
  //createTradsObjFrom will be returning one itself
  const tradsDir = "/assets/trads/";
  const languages = ["de","en","es","fr","it","nl","ru"];
  const tradsPaths = languages.map(e => tradsDir + e + '.json');
  return createTradsObjFrom(languages, tradsPaths);
;
getTrads().then(yourObj=>
  console.log(yourObj);
  //you can now use your filled object
).catch(err=>
  console.log("Some error happened: ",err);
);

关于您为何看到控制台日志中已填满该对象的信息,请参阅以下问答,有关控制台在控制台中第一次扩展该对象时如何评估该对象:Is Chrome's JavaScript console lazy about evaluating arrays?

以上是关于我制作了一个JavaScript对象,无法对其进行迭代,甚至无法访问其参数。我想念什么?的主要内容,如果未能解决你的问题,请参考以下文章

用javascript定义一个数组,里面包含五个元素,对其进行赋值,每个元素的值

如何根据动态键制作Javascript过滤器值

Wpf中“由于其他线程拥有此对象,因此调用线程无法对其进行访问”

Wpf中“由于其他线程拥有此对象,因此调用线程无法对其进行访问”的问题

无法在 Firefox 上从 Javascript 提交表单

如何制作用户定义的矩形数组并对其进行迭代