AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79337106
Accepted
Parzh from Ukraine
Parzh from Ukraine
Asked: 2025-01-08 03:17:25 +0800 CST2025-01-08 03:17:25 +0800 CST 2025-01-08 03:17:25 +0800 CST

Existe uma maneira de declarar uma propriedade de objeto sem inicializá-la?

  • 772

AS: A ordem de propriedade do objeto em JS é um tópico muito complicado . Para minhas intenções e propósitos, apenas a ordem de inserção importa.

TL;DR: Existe uma maneira de declarar uma propriedade de objeto em JavaScript sem atribuir um valor a ela, para que, quando a propriedade for definida posteriormente, ela ainda apareça antes na ordem de inserção?

const user = { name: unset, age: 42 }


Tenho um conjunto de funções assíncronas, cada uma retornando um valor associado a uma chave única. Elas são então invocadas em paralelo para construir um objeto com pares chave-valor usados ​​como entradas (propriedades). Algo assim:

const props = {}
const propsSet = getters.map(async ([key, getValue]) => {
  props[key] = async getValue()
})

await Promise.all(propsSet)

return props

Experimente .

Como tudo isso é assíncrono, a ordem das propriedades em propsestá em todo lugar: às vezes recebo { foo: …, bar: … }, às vezes { bar: …, foo: … }. Eu poderia consertar isso associando cada getter a um número de sequência. Mas uma solução muito mais fácil é apenas iniciar as propriedades o mais rápido possível; devido a como o loop de eventos funciona, isso é basicamente uma garantia de que as propriedades de propsserão ordenadas da mesma forma que em getters:

const propsSet = getters.map(async ([key, getValue]) => {
    props[key] = null // or any other initialization token
    props[key] = await getValue()
})

Em JS puro, isso é algo perfeitamente normal de se fazer, mas em TypeScript isso geralmente é um erro do compilador (já que um "token de inicialização" arbitrário não pode ser atribuído a propriedades estritamente tipadas de props); então, tenho que silenciar o compilador, o que não gosto de fazer:

values[key] = null! // non-null assertion operator

Experimente .

Eu preferiria que a propriedade não fosse realmente definida no objeto, mas que um "slot" fosse disponibilizado para ela. Percebi que o que eu basicamente preciso é muito similar a declarar variáveis ​​separadamente de inicializá-las, – como no estilo JS old-school:

var value1, value2

value1 = 42
value2 = 17

Existe alguma maneira existente ou futura (proposta) de declarar propriedades de objetos em JavaScript sem inicializá-los?

Note que não estou perguntando sobre maneiras de ordenar propriedades. Há muitas estratégias para fazer isso, incluindo o uso dos números de sequência mencionados anteriormente (por exemplo, índices de array).

javascript
  • 1 1 respostas
  • 67 Views

1 respostas

  • Voted
  1. Best Answer
    Bergi
    2025-01-08T04:32:50+08:002025-01-08T04:32:50+08:00

    Existe uma maneira de declarar uma propriedade de objeto sem atribuir um valor a ela?

    Não. Não há declarações (de tipo?) em tempo de execução. Você só pode criar uma propriedade de objeto, por atribuição (em uma declaração) ou inicialização (em um literal de objeto). Ou a propriedade existe, com um valor 1 , ou ela não existe de forma alguma. O valor padrão de variáveis ​​ou propriedades não definidas de outra forma seria undefined, não há valor "não definido" (ou ausência de um valor).

    A abordagem idiomática do TS para (não) inicializar uma propriedade undefinedindependentemente do seu tipo declarado seria usar uma asserção não nula:

    const propsSet = getters.map(async ([key, getValue]) => {
        props[key] = undefined!;
    //                        ^
        props[key] = await getValue();
    });
    

    Mas isso é basicamente mentir sobre o tipo de props, o objeto não é realmente utilizável até que sua inicialização assíncrona termine e seu tipo deve refletir isso. Então, em vez de afirmar, Object.create(null) as Record<GroupName, Group>você deve usar um Partialtipo e afirmar o tipo de resultado esperado somente quando todas as propriedades forem realmente inicializadas:

    const groups = Object.create(null) as Partial<Record<GroupName, Group>>;
    //                                    ^^^^^^^
    await Promise.all(Object.entries(groupGetters).map(async ([groupName, getGroup]) => {
        groups[groupName as GroupName] = undefined; // OK now
        groups[groupName as GroupName] = await getGroup();
    }));
    
    return groups as Record<GroupName, Group>;
    //            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    Uma abordagem ainda melhor, no entanto, seria adiar a criação do objeto até que todos os valores de propriedade estejam disponíveis. Dessa forma, não há objetos "incompletos" que precisem ser digitados em nenhum momento. No seu caso, isso seria

    return Object.setPrototypeOf(Object.fromEntries(await Promise.all(Object.entries(groupGetters).map(async ([groupName, getGroup]) => 
    //                           ^^^^^^^^^^^^^^^^^^
        [groupName, await getGroup()]
    ))), null) as Record<GroupName, Group>;
    //         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    1: Assumindo uma propriedade de dados. Pode-se definir uma propriedade de acesso sem getter, ou um getter que sempre lança. Você pode fazer isso e, subsequentemente, convertê-lo em uma propriedade de dados, mas eu desaconselho isso. É muito complicado, ineficiente e também não melhora os tipos.

    • 1

relate perguntas

  • classificação de mesclagem não está funcionando - código Javascript: não é possível encontrar o erro mesmo após a depuração

  • método select.remove() funciona estranho [fechado]

  • Sempre um 401 res em useOpenWeather () - react-open-weather lib [duplicado]

  • O elemento de entrada não possui atributo somente leitura, mas os campos ainda não podem ser editados [fechado]

  • Como editar o raio do primeiro nó de um RadialTree D3.js?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Reformatar números, inserindo separadores em posições fixas

    • 6 respostas
  • Marko Smith

    Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não?

    • 2 respostas
  • Marko Smith

    Problema com extensão desinstalada automaticamente do VScode (tema Material)

    • 2 respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Martin Hope
    Fantastic Mr Fox Somente o tipo copiável não é aceito na implementação std::vector do MSVC 2025-04-23 06:40:49 +0800 CST
  • Martin Hope
    Howard Hinnant Encontre o próximo dia da semana usando o cronógrafo 2025-04-21 08:30:25 +0800 CST
  • Martin Hope
    Fedor O inicializador de membro do construtor pode incluir a inicialização de outro membro? 2025-04-15 01:01:44 +0800 CST
  • Martin Hope
    Petr Filipský Por que os conceitos do C++20 causam erros de restrição cíclica, enquanto o SFINAE antigo não? 2025-03-23 21:39:40 +0800 CST
  • Martin Hope
    Catskul O C++20 mudou para permitir a conversão de `type(&)[N]` de matriz de limites conhecidos para `type(&)[]` de matriz de limites desconhecidos? 2025-03-04 06:57:53 +0800 CST
  • Martin Hope
    Stefan Pochmann Como/por que {2,3,10} e {x,3,10} com x=2 são ordenados de forma diferente? 2025-01-13 23:24:07 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve