O que faz “var FOO = FOO || {} ”(Atribuir uma variável ou um object vazio a essa variável) significa em JavaScript?

Olhando para um código fonte on-line me deparei com isso no topo de vários arquivos de origem.

var FOO = FOO || {}; FOO.Bar = …; 

Mas eu não tenho ideia do que || {} || {} faz.

Eu sei que {} é igual ao new Object() e acho que o || é para algo como “se já existe use seu valor else use o novo object.

Por que eu veria isso no topo de um arquivo de origem?

    Seu palpite quanto à intenção de || {} || {} está bem perto.

    Esse padrão específico, quando visto no topo dos arquivos, é usado para criar um namespace , ou seja, um object nomeado sob o qual funções e variables ​​podem ser criadas sem poluir indevidamente o object global.

    A razão pela qual ele é usado é se você tiver dois (ou mais) arquivos:

     var MY_NAMESPACE = MY_NAMESPACE || {}; MY_NAMESPACE.func1 = { } 

    e

     var MY_NAMESPACE = MY_NAMESPACE || {}; MY_NAMESPACE.func2 = { } 

    ambos os quais compartilham o mesmo namespace, então não importa em que ordem os dois arquivos são carregados, você ainda obtém func1 e func2 corretamente definidos dentro do object MY_NAMESPACE corretamente.

    O primeiro arquivo carregado criará o object inicial MY_NAMESPACE e qualquer arquivo carregado posteriormente aumentará o object.

    De forma útil, isso também permite o carregamento asynchronous de scripts que compartilham o mesmo namespace, o que pode melhorar os tempos de carregamento da página. Se as tags tiverem o atributo defer definido, você não poderá saber em qual ordem elas serão interpretadas, portanto, conforme descrito acima, isso também corrigirá esse problema.

     var AEROTWIST = AEROTWIST || {}; 

    Basicamente esta linha está dizendo setar a variável AEROTWIST para o valor da variável AEROTWIST , ou configurá-la para um object vazio.

    O cano duplo || é uma instrução OR, e a segunda parte da OR é executada apenas se a primeira parte retornar falso.

    Portanto, se AEROTWIST já tiver um valor, ele será mantido como esse valor, mas se não tiver sido definido antes, ele será definido como um object vazio.

    é basicamente o mesmo que dizer isto:

     if(!AEROTWIST) {var AEROTWIST={};} 

    Espero que ajude.

    Outro uso comum para || é definir um valor padrão para um parâmetro de function indefinido também:

     function display(a) { a = a || 'default'; // here we set the default value of a to be 'default' console.log(a); } // we call display without providing a parameter display(); // this will log 'default' display('test'); // this will log 'test' to the console 

    O equivalente em outras programações geralmente é:

     function display(a = 'default') { // ... } 

    Existem duas partes principais que var FOO = FOO || {}; var FOO = FOO || {}; capas.

    # 1 Prevenindo substituições

    Imagine que você tenha seu código dividido em vários arquivos e seus colegas de trabalho também estejam trabalhando em um object chamado FOO . Então isso poderia levar ao caso que alguém já definiu FOO e atribuiu funcionalidade a ele (como uma function de skateboard ). Então você replaceia, se você não estivesse verificando se já existe.

    Caso problemático:

     // Definition of co-worker "Bart" in "bart.js" var FOO = {}; FOO.skateboard = function() { alert('I like skateboarding!'); }; // Definition of co-worker "Homer" in "homer.js" var FOO = {}; FOO.donut = function() { alert('I like donuts!'); }; 

    Nesse caso, a function skateboard terá desaparecido se você carregar o arquivo JavaScript homer.js depois de bart.js no seu HTML porque Homer define um novo object FOO (e, portanto, substitui o existente do Bart) para que ele só saiba sobre a function donut .

    Então você precisa usar var FOO = FOO || {}; var FOO = FOO || {}; o que significa que “FOO será atribuído a FOO (se já existir) ou a um novo object em branco (se FOO ainda não existir).

    Solução:

     var FOO = FOO || {}; // Definition of co-worker Bart in bart.js FOO.skateboard = function() { alert('I like skateboarding!'); }; // Definition of co-worker Homer in homer.js var FOO = FOO || {}; FOO.donut = function() { alert('I like donuts!'); }; 

    Como Bart e Homer estão agora verificando a existência do FOO antes de definir seus methods, você pode carregar o bart.js e o homer.js em qualquer ordem, sem sobrescrever os methods um do outro (se eles tiverem nomes diferentes). Então você sempre terá um object FOO que tem os methods skateboard e donut (Yay!).

    # 2 Definir um novo object

    Se você leu o primeiro exemplo, então você já sabe qual é o propósito do || {} || {} .

    Porque, se não houver nenhum object FOO , o caso OR ficará ativo e criará um novo object, para que você possa atribuir funções a ele. Gostar:

     var FOO = {}; FOO.skateboard = function() { alert('I like skateboarding!'); }; 

    Se não houver valor em AEROTWIST ou for nulo ou indefinido, o valor atribuído ao novo AEROTWIST será {} (um object em branco)

    O || operador leva dois valores:

     a || b 

    Se um for verdade, ele retornará a . Caso contrário, retornará b .

    Os valores falsos são null , undefined , 0 , "" , NaN e false . Os valores verdadeiros são todo o resto.

    Então, se a não foi definido (é undefined ), ele retornará b .

    Observe que, em algumas versões do IE, esse código não funcionará como esperado. Como o var , a variável é redefinida e atribuída – se bem me lembro do problema – você acabará tendo sempre um novo object. Isso deve corrigir o problema:

     var AEROTWIST; AEROTWIST = AEROTWIST || {};