Estou trabalhando com JavaScript há alguns dias e cheguei a um ponto em que quero sobrecarregar os operadores dos meus objetos definidos.
Depois de um período no Google procurando por isso, parece que você não pode fazer isso oficialmente, mas existem algumas pessoas por aí que afirmam que é uma forma prolixa de realizar essa ação.
Basicamente, criei uma classe Vector2 e quero ser capaz de fazer o seguinte:
var x = new Vector2(10,10);
var y = new Vector2(10,10);
x += y; //This does not result in x being a vector with 20,20 as its x & y values.
Em vez disso, estou tendo que fazer isso:
var x = new Vector2(10,10);
var y = new Vector2(10,10);
x = x.add(y); //This results in x being a vector with 20,20 as its x & y values.
Existe uma abordagem que posso adotar para sobrecarregar os operadores na minha classe Vector2? Como isso parece simplesmente feio.
javascript
operators
operator-overloading
Lee Brindley
fonte
fonte
Respostas:
Como você descobriu, o JavaScript não oferece suporte à sobrecarga de operador. O mais próximo que você pode chegar é implementar
toString
(que será chamado quando a instância precisar ser coagida a ser uma string) evalueOf
(que será chamado para forçá-la a um número, por exemplo, ao usar+
para adição, ou em muitos casos quando usá-lo para concatenação porque+
tenta fazer adição antes da concatenação), que é bastante limitado. Nenhum dos dois permite criar umVector2
objeto como resultado.Para as pessoas que chegam a esta questão e desejam uma string ou número como resultado (em vez de a
Vector2
), porém, aqui estão alguns exemplos devalueOf
etoString
. Esses exemplos não demonstram a sobrecarga do operador, apenas aproveitando as vantagens da manipulação integrada do JavaScript na conversão em primitivos:valueOf
Este exemplo dobra o valor da
val
propriedade de um objeto em resposta a ser forçado a um primitivo, por exemplo, por meio de+
:Exibir trecho de código
Ou com ES2015's
class
:Exibir trecho de código
Ou apenas com objetos, sem construtores:
Exibir trecho de código
toString
Este exemplo converte o valor da
val
propriedade de um objeto em maiúsculas em resposta a ser forçado a um primitivo, por exemplo, por meio de+
:Exibir trecho de código
Ou com ES2015's
class
:Exibir trecho de código
Ou apenas com objetos, sem construtores:
Exibir trecho de código
fonte
Date
classe convertem implicitamente datas em números usandovalueOf
? Por exemplo, você pode fazerdate2 > date1
e será verdade sedate2
foi criado depoisdate1
.>
,<
,>=
, E<=
(mas não==
,===
,!=
, ou!==
) use o Resumo relacional Comparação operação, que usaToPrimitive
com "número" dica. Em umDate
objeto, isso resulta no número quegetTime
retorna (o valor em milissegundos desde a época).Como TJ disse, você não pode sobrecarregar operadores em JavaScript. No entanto, você pode aproveitar a vantagem da
valueOf
função para escrever um hack que parece melhor do que usar funções comoadd
todas as vezes, mas impõe as restrições ao vetor de que xey estão entre 0 e MAX_VALUE. Aqui está o código:Então você pode escrever equações como esta:
fonte
add
método do OP ... Algo que eles não queriam fazer.+
sinal. Esta é uma resposta muito boa que mostra como evitar chamar um nome de função não natural para objetos quase numéricos.+
operador é a capacidade de retornar umNumber
em substituição a um dos operandos. Portanto, qualquer funcionalidade adicional que funcione comoObject
instâncias deve sempre codificar o objeto como umNumber
e, eventualmente, decodificá-lo.FYI paper.js resolve esse problema criando PaperScript, um javascript autocontido com escopo e sobrecarga de operadores de vetores, que é então processado de volta para javascript.
Mas os arquivos paperscript precisam ser especificamente especificados e processados como tal.
fonte
Na verdade, existe uma variante de JavaScript que oferece suporte à sobrecarga de operador. ExtendScript, a linguagem de script usada por aplicativos Adobe, como Photoshop e Illustrator, tem sobrecarga de operador. Nele, você pode escrever:
Isso é descrito com mais detalhes no "Guia de ferramentas Adobe Extendscript JavaScript" ( link atual aqui ). A sintaxe foi aparentemente baseada em um rascunho (agora abandonado) do padrão ECMAScript.
fonte
É possível fazer matemática vetorial com dois números agrupados em um. Deixe-me mostrar um exemplo antes de explicar como funciona:
Estou usando o fato de que, se você deslocar os bits dois números X vezes e, em seguida, adicionar ou subtraí-los antes de deslocá-los de volta, obterá o mesmo resultado como se não tivesse mudado para começar. Da mesma forma, a multiplicação e divisão escalar funcionam simetricamente para valores deslocados.
Um número JavaScript tem 52 bits de precisão inteira (flutuantes de 64 bits), então empacotarei um número nos 26 bits mais altos disponíveis e um nos mais baixos. O código está um pouco mais confuso porque eu queria oferecer suporte a números assinados.
A única desvantagem que vejo com isso é que x e y devem estar na faixa de + -33 milhões, já que eles devem caber em 26 bits cada.
fonte
Embora não seja uma resposta exata para a pergunta, é possível implementar alguns dos métodos python __magic__ usando os símbolos ES6
Um
[Symbol.toPrimitive]()
método não permite que você implique uma chamadaVector.add()
, mas permitirá que você use uma sintaxe comoDecimal() + int
.fonte
Interessante também é a biblioteca experimental operator-overheading-js . Ele faz sobrecarga em um contexto definido (função de retorno de chamada) apenas.
fonte
Podemos usar Ganchos semelhantes ao React para avaliar a função da seta com diferentes valores do
valueOf
método em cada iteração.Exibir trecho de código
A Library @ js-basics / vector usa a mesma ideia para o Vector3.
fonte