Funções e objetos Javascript

9

Eu estou aprendendo Javascript, eu tenho usado PHP por cerca de 10 anos, então eu tenho algum conhecimento de Javascript, principalmente usando apenas jQuery e hacking juntos, eu acho que é hora de eu colocar algum esforço em aprendê-lo melhor, então eu tenho lendo sobre isso.

Abaixo estão meus exemplos de definir e chamar algumas funções.

Método 1

function testFunction1() {
    console.log('TestFunction1() was ran');
}
testFunction1();

Método 2

var testFunction2 = function() {
    console.log('TestFunction2() was ran');
}
testFunction2();

Método 3

var TestFunction3 = {
    flag: function() {
        console.log('TestFunction3.flag() was ran');
    },
    unflag: function() {
        console.log('TestFunction3.unflag() was ran');
    }
};
TestFunction3.flag();
TestFunction3.unflag();

Método 4

var TestFunction4 = {
    Like: {
        comment: function() {
            console.log('TestFunction4.Like.comment() was ran');
        },
        user: function() {
            console.log('TestFunction4.Like.user() was ran');
        }
    },
    Unlike: {
        comment: function() {
            console.log('TestFunction4.Unlike.comment() was ran');
        },
        user: function() {
            console.log('TestFunction4.Unlike.user() was ran');
        }
    }
};
TestFunction4.Like.comment();
TestFunction4.Like.user();
TestFunction4.Unlike.comment();
TestFunction4.Unlike.user();

Ok, entendo que os métodos 1 e 2 são apenas uma chamada básica de função.

1)
Os métodos 3 e 4 são onde minhas perguntas começam, a partir de outro post e da leitura, não posso dizer se elas ainda são consideradas uma função básica com o namespace aplicado ou se elas seriam consideradas Objetos?

2)
Eu tenho visto onde às vezes um objeto seria chamado com a palavra new no entanto executando tudo isso no navegador funciona bem, então eu estou supondo que isso não é um objeto? Se não é um objeto, como eu faria isso em um objeto?

3)
Os exemplos 3 e 4 são praticamente os mesmos, com a exceção de que o exemplo 4 tem funções definidas como 1 nível mais profundo que o exemplo 3, existe um nome para o exemplo 3 e 4 ou são consideradas a mesma coisa?

4)
Por último, de todos os 4 exemplos, qualquer um desses 4 métodos é preferível ao outro?

Desculpe por todas as perguntas em 1, mas elas estão todas relacionadas e não acho que eu deva iniciar 4 perguntas separadas para isso.

    
por JasonDavis 29.11.2011 в 00:14
fonte

3 respostas

4

3 é um objeto. Tem propriedades de objeto, que possuem propriedades que são funções. 4 é a mesma ideia, apenas com menos aninhamento.

No que diz respeito ao uso da palavra-chave new , essa é apenas uma maneira de criar objetos. Quando uma função é chamada com new , isso é chamado de invocação do construtor . É uma das quatro maneiras pelas quais as funções podem ser invocadas. Os outros três, para completar, são invocação de método , invocação de função e aplicam invocação .

Se você quiser usar uma função como um construtor, por convenção, comece com uma letra maiúscula e, em seguida, chame-a com a palavra-chave new . Isso cria um objeto em branco com base no Object.prototype e o define como this . Ao usar esse modo de criação de objetos, você adicionaria propriedades ao objeto resultante adicionando-as diretamente a this , ou seja, this.foo = 12

Os métodos desse objeto seriam adicionados modificando o protótipo da sua função.

YourConstrutor.prototype.newMethod = function() {
   alert(this.foo);
};

Note que o uso de construtores vem com muitas dificuldades, especialmente se você quiser implementar a herança

Os objetos podem ser criados mais simplesmente retornando-os de uma função "regular":

function createCar() {
   return {
      prop1 : 12,
      someFunc: function() {
         alert(this.prop1);
      }
   }
}

Isso também facilita a ocultação de informações:

function createCar() {
   var protectedInfo = "haha I'm protected"; ///not visible outside this function
   return {
      prop1 : 12,
      showProtectedData: function() {
         alert(protectedInfo);
      },
      someFunc: function() {
         alert(this.prop1);
      }
   }
}

(você também pode implementar informações ocultas com construtores, mas as informações protegidas não ficarão visíveis aos métodos que você coloca no protótipo; as informações protegidas serão visíveis apenas aos métodos que você adicionar manualmente a this )

A única desvantagem aqui é que a criação será um pouco mais lenta, já que está criando esse someFunc método de novo a cada vez; com um construtor, ele existiria uma vez, como parte do protótipo.

4. Qual é preferível? Se você quiser apenas criar um único objeto, use 3 ou 4. Simples.

Se você quiser criar um objeto repetidamente, ele depende . Você estará criando dezenas de milhares desses objetos, de modo que a velocidade seja da maior importância? Se assim for, você provavelmente vai querer um construtor. Se não, então depende do que você está mais confortável. Eu acho uma função simples que retorna um objeto mais claro e mais flexível, mas isso é apenas minha preferência. Muitos desenvolvedores mais inteligentes do que eu preferem construtores.

    
por Adam Rackis 29.11.2011 / 00:19
fonte
1
  1. 3 e 4 ainda são funções, mas também são objetos. 1 e 2 também são objetos, além de serem funções. Todas as funções são objetos - o JavaScript tem funções de primeira classe.

  2. Instancia um objeto. As funções que estão sendo chamadas com new são construtores . Eles criam objetos.

  3. Eles são exatamente a mesma coisa. Como em # 1, o nível de aninhamento não tem efeito sobre o tipo de coisa ...

  4. Não, porque são todos equivalentes. Um Function é um Object e não importa onde esteja. Geralmente, no entanto, você evitaria o aninhamento pesado com o propósito de namespaces porque pode diminuir o seu código, sem muito benefício de clareza. JavaScript não foi realmente projetado com namespaces em mente.

por Ry- 29.11.2011 / 00:19
fonte
0

AFAIK

1) No JS todas as funções são objetos. No caso de 3, sim, seria considerado como um objeto porque está dentro de chaves

3) Eles são a mesma coisa, mas uma maneira de fazer jazz seria "retornar" uma das propriedades de nível mais alto e não a outra, que basicamente oculta a função não retornada e dá a você uma maneira de criar métodos públicos e privados.

4) Provavelmente, 4 está mais próximo do que eu acho que você quer e segue algumas abordagens sensatas, mas, como Andrew diz, eu estaria inclinado a mudar 4 em algo como isto:

var TestFunction4 = (function(){
    return {
        flag: function() {
            console.log('TestFunction4.flag() was ran');
        },
        unflag: function() {
            console.log('TestFunction4.unflag() was ran');
        }
    }
})();
TestFunction4.flag();
TestFunction4.unflag();

Observe os parênteses na parte final do método, forçando a função a ser executada imediatamente e disponibilizada antes do tempo de execução para o restante do aplicativo (em termos de, digamos, intellisense)

EDITAR:

Isto é como eu usaria funções 'privadas' em resposta ao comentário 'por que você faria isso':

var TestFunction4 = (function(){
    //private function
    var private = {
        aPrivateFunction: function(a) {
            return a + 1;
        }
    }
    //public return object
    var public = {
        flag: function() {
           console.log('Calling private function aPrivateFunction(10) expecting 11');
            console.log('result' + private.aPrivateFunction(10));
            console.log('TestFunction4.flag() was ran');
        },
        unflag: function() {
            console.log('TestFunction4.unflag() was ran');
        }
    }
    //return things to expost publicly
    return public;
})();
    
por dougajmcdonald 29.11.2011 / 00:25
fonte