Qual é a maneira padrão de chamar métodos estáticos? Posso pensar em usar constructor
ou usar o nome da classe em si, não gosto desta última, pois ela não parece necessária. O primeiro é o caminho recomendado ou existe algo mais?
Aqui está um exemplo (artificial):
class SomeObject {
constructor(n){
this.n = n;
}
static print(n){
console.log(n);
}
printN(){
this.constructor.print(this.n);
}
}
javascript
class
static
ecmascript-6
es6-class
simonzack
fonte
fonte
SomeObject.print
parece natural. Mas porthis.n
dentro não faz sentido, pois não há exemplo, se estamos falando de métodos estáticos.printN
não é estático.Respostas:
Ambas as formas são viáveis, mas fazem coisas diferentes quando se trata de herança com um método estático substituído. Escolha aquele cujo comportamento você espera:
A referência à propriedade estática por meio da classe será realmente estática e fornecerá constantemente o mesmo valor. Usar
this.constructor
vez usará o despacho dinâmico e se referirá à classe da instância atual, onde a propriedade estática pode ter o valor herdado, mas também pode ser substituída.Isso corresponde ao comportamento do Python, onde você pode optar por se referir às propriedades estáticas pelo nome da classe ou pela instância
self
.Se você espera que as propriedades estáticas não sejam substituídas (e sempre consulte a da classe atual), como em Java , use a referência explícita.
fonte
class
sintaxe), não há diferença na definição do método. É apenas uma questão de como você a pesquisa, através daconstructor
propriedade herdada ou diretamente pelo nome.Property 'staticProperty' does not exist on type 'Function'
Eu tropecei sobre esta discussão em busca de resposta para um caso semelhante. Basicamente, todas as respostas são encontradas, mas ainda é difícil extrair o essencial delas.
Tipos de acesso
Suponha uma classe Foo provavelmente derivada de outras classes com provavelmente mais classes derivadas dela.
Então acessando
this.method()
this.property
Foo.method()
Foo.property
this.constructor.method()
this.constructor.property
this.method()
this.property
Foo.method()
Foo.property
Foo.prototype.method.call( this )
Object.getOwnPropertyDescriptor( Foo.prototype,"property" ).get.call(this);
fundo
this
está se referindo à instância atual.super
está basicamente se referindo à mesma instância, mas abordando métodos e getters escritos no contexto de alguma classe atual que está se estendendo (usando o protótipo do protótipo de Foo).this.constructor
.this
está disponível para se referir diretamente à definição da classe atual.super
também não se refere a alguma instância, mas a métodos estáticos e getters escritos no contexto de alguma classe atual que está sendo estendida.Conclusão
Tente este código:
fonte
Own non-overridden instance method/getter / not possible by intention unless using some workaround
--- Isso é uma pena. Na minha opinião, esta é uma deficiência do ES6 +. Talvez deva ser atualizado para permitir simplesmente se referir amethod
- iemethod.call(this)
. Melhor queFoo.prototype.method
. Babel / etc. poderia implementar usando um NFE (expressão da função nomeada).method.call( this )
é uma solução provável, exceto a quemethod
não está vinculada à "classe" base desejada e, portanto, deixa de ser um método / getter de instância não substituída . Sempre é possível trabalhar com métodos independentes de classe dessa maneira. No entanto, não acho que o design atual seja tão ruim assim. No contexto de objetos de classe derivados de sua classe base Foo, pode haver boas razões para substituir um método de instância. Esse método substituído pode ter boas razões para invocar suasuper
implementação ou não. Qualquer um dos casos é elegível e deve ser obedecido. Caso contrário, terminaria com um design ruim de POO.arguments.callee
ou um NFE.this
). Parece tentar combinar os benefícios da aritmética dos ponteiros do C simples com o C # de nível superior. Apenas por curiosidade: o que você usariaarguments.callee
no código OOP limpo?this.inherited(currentFn, arguments);
- ondecurrentFn
é uma referência à função atualmente em execução. Não poder fazer referência diretamente à função atualmente em execução está tornando-a um pouco complicada no TypeScript, que retira sua sintaxe de classe do ES6.Se você planeja fazer algum tipo de herança, eu recomendaria
this.constructor
. Este exemplo simples deve ilustrar o motivo:test1.callPrint()
registraráConstructorSuper Hello ConstructorSuper!
no consoletest2.callPrint()
registraráConstructorSub Hello ConstructorSub!
no consoleA classe nomeada não tratará bem da herança, a menos que você redefina explicitamente todas as funções que fazem referência à classe nomeada. Aqui está um exemplo:
test3.callPrint()
registraráNamedSuper Hello NamedSuper!
no consoletest4.callPrint()
registraráNamedSuper Hello NamedSub!
no consoleVeja todas as opções acima em execução no Babel REPL .
Você pode ver disso que
test4
ainda acha que está na super classe; neste exemplo, pode não parecer muito importante, mas se você estiver tentando fazer referência a funções-membro que foram substituídas ou a novas variáveis-membro, estará com problemas.fonte