Attributes in functions - Javascript

Asked

Viewed 119 times

0

I was observing that the $ jQuery is a function, but if I do $. i can access several other functions, which are function attributes $. How is it possible for a function to have attributes that are accessible out of context through .?

  • As so accessible out of context?

  • I think you should look at your other questions that have answers and none have been marked as solved.

2 answers

2


If you do that, it’ll work:

function Guilherme() {
    console.log('Chamou o Foo');
}

Guilherme.falar = function (msg) {
     console.log('Guilherme diz:', msg);
};

Guilherme();

Guilherme.falar('olá mundo');
Guilherme.falar('Tchau!');

This is because when you use the expression function Javascript creates an object, Javascript is virtually all accessible as an object (then I will improve this part of the explanation).

You can also create a simple object with prototype would be like classes in other languages (I won’t talk about ES6 now because it will evade the question’s intention), for example an example of a "jQuery itself", so:

(function () {
    function $(seletor) {
       //Checa se é um objeto
       if (this instanceof $) {
           this.elementos = document.querySelectorAll(seletor);
           this.length = this.elementos.length;
       } else {
          //Se chamar `new $` vai direto, se chamar $() então a propria função instancia o objeto e retorna ele
          return new $(seletor);
       }
    }

    $.prototype = {
        "length": 0,
        "html": function () {
             if (this.length) return this.elementos[0].innerHTML;
        },
        "text": function () {
             if (this.length) return this.elementos[0].textContent;
        }
    };

    window.$ = $;
})();

console.log("html retornado:", $("#test").html() );
console.log("texto retornado:",  $("#test").text() );
<div id="test">
Olá mundo <b>novo</b>!
</div>


If you want to "extend" existing object types, such as String or Number, you can use .prototype, so you’ll have access to this and you can take the amount:

String.prototype.foobar = function () {
     console.log('String.foobar pegou:', this);
};

Number.prototype.foobar = function () {
     console.log('Number.foobar pegou:', this);
};

var testestr = "exemplo de string";
var testenum = 2018;

testestr.foobar();
testenum.foobar();

  • In the second example you are overwriting the function Guilherme with the object.

  • @bfavaretto sorry, sleep, erased the prototype xD

  • Better go to sleep and review tomorrow rs. <strike>Because this second block remains problematic, prototype methods would only be accessible by instances generated by the use as a constructor. </strike> The question is complicated, gives room for many related but different topics, better to polish your answer calmly after.

  • 1

    @exact bfavaretto, hehehe, for sure I am confused, I will remove and in the future I see from where I got it :) thank you!

1

In Javascript the functions have similarities to objects. The word "attributes" is not correct here, but "properties", and therefore functions can have properties that in case they are functions are called "methods".

So you can create a function with the name you want, including with the name of $ like jQuery did. Then you can add properties or methods to that specific function (that instance specific) or to the prototype of a function, which makes these methods and properties available in all functions of that prototype.

Note the example where I create two functions, and different ways to add properties to them and how to add "globally" properties to all functions

// declaração da função
function $_$(seletor) {
  return [...document.querySelectorAll(seletor)];
}

// declaração de outra função
function qqCoisa() {
  return 'Qualquer coisa...';
}

// adicionar uma propriedade à instância
$_$.descricao = 'Uma função minha...';

console.log($_$.descricao); // Uma função minha...
console.log(qqCoisa.descricao); // "undefined" - nada, esta função não tem esta propriedade

Function.prototype.metodoGlobal = function() {
  return 'Eu sou global...';
}

console.log($_$.metodoGlobal()); // Eu sou global...
console.log(qqCoisa.metodoGlobal()); // Eu sou global...

What happens in jQuery is that you create a unique, more specific instance that takes a number of methods. And for you to have the internal context (use the this and give it values that only affect that instance) you have to use the function builder new.

Example:

const $_$ = (function() {

  // defenição da função principal que retorna a instância para se poder usar outros métodos encadeados
  function $_$_proto(seletor) {
    this.conteudo = [...document.querySelectorAll(seletor)];
    return this;
  }

  // um método adicionado ao protótipo para que todas as intâncias venham com ele
  $_$_proto.prototype.buscarTags = function() {
    return this.conteudo.map(el => el.tagName.toLowerCase());
  }

  // a função "fábrica" que retorna uma nova instância (com o seu "this" único) para se poder consumir
  return function(seletor) {
    return new $_$_proto(seletor);
  }
})();


console.log($_$('.teste').buscarTags()); // ["div", "p"]
<div class="teste">Uma div</div>
<p class="teste">Um p</p>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.