aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/web/javascript/reference/global_objects/object/defineproperty/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'files/pt-br/web/javascript/reference/global_objects/object/defineproperty/index.html')
-rw-r--r--files/pt-br/web/javascript/reference/global_objects/object/defineproperty/index.html478
1 files changed, 478 insertions, 0 deletions
diff --git a/files/pt-br/web/javascript/reference/global_objects/object/defineproperty/index.html b/files/pt-br/web/javascript/reference/global_objects/object/defineproperty/index.html
new file mode 100644
index 0000000000..25ad45b438
--- /dev/null
+++ b/files/pt-br/web/javascript/reference/global_objects/object/defineproperty/index.html
@@ -0,0 +1,478 @@
+---
+title: Object.defineProperty()
+slug: Web/JavaScript/Reference/Global_Objects/Object/defineProperty
+tags:
+ - ECMAScript5
+ - JavaScript
+ - Método(2)
+ - Objeto
+translation_of: Web/JavaScript/Reference/Global_Objects/Object/defineProperty
+---
+<div>{{JSRef}}</div>
+
+<div></div>
+
+<p>O método <code><strong>Object.defineProperty()</strong></code> define uma nova propriedade diretamente em um objeto, ou modifica uma propriedade já existente em um objeto, e retorna o objeto.</p>
+
+<div class="note">
+<p><strong>Nota</strong>: Você invoca este método diretamente no construtor do {{jsxref("Object")}} ao invés de invocar em uma instância do tipo <code>Object</code>.</p>
+</div>
+
+<h2 id="Sintaxe">Sintaxe</h2>
+
+<pre class="syntaxbox notranslate"><code>Object.defineProperty(<var>obj</var>, <var>prop</var>, <var>descriptor</var>)</code></pre>
+
+<h3 id="Parâmetros">Parâmetros</h3>
+
+<dl>
+ <dt><code>obj</code></dt>
+ <dd>O objeto no qual será definida a propriedade.</dd>
+ <dt><code>prop</code></dt>
+ <dd>O nome da propriedade que será definida ou modificada.</dd>
+ <dt><code>descriptor</code></dt>
+ <dd>O descritor para a propriedade que será definida ou modificada.</dd>
+</dl>
+
+<h3 id="Valor_de_retorno">Valor de retorno</h3>
+
+<p>O objeto que foi passado à função.</p>
+
+<h2 id="Descrição">Descrição</h2>
+
+<p>Esse método permite uma precisa inclusão ou modificação de uma propriedade em um objeto. Enquanto a inclusão de propriedades através de atribuição cria propriedades que são visíveis durante a enumeração (por repetições {{jsxref("Statements/for...in", "for...in")}} ou pelo método {{jsxref("Object.keys")}}), e cujos valores podem ser alterados e {{jsxref("Operators/delete", "deletados", "", 1)}}, esse método permite a modificação deste comportamento padrão. Por padrão, valores incluídos utilizando <code>Object.defineProperty()</code> são imutáveis.</p>
+
+<p>Os descritores de propriedades presentes nos objetos se apresentam em duas variedades: descritores de dados e descritores de assessores. Um <em>descritor de dado</em> é uma propriedade que contém um valor, podendo este ser gravável ou não. Um <em>descritor de assessor </em>é uma propriedade definida como um par de funções getter-setter. Um descritor deve ser de uma destas variedades; não pode ser de ambas.</p>
+
+<p>Ambos os descritores de dados e de assessor são objetos. Eles compartilham as seguintes chaves obrigatórias:</p>
+
+<dl>
+ <dt><code>configurable</code></dt>
+ <dd><code>true</code> se e somente se o tipo deste descritor de propriedade pode ser alterado e se a propriedade pode ser deletada do objeto correspondente.<br>
+ <strong>Valor padrão é <code>false</code>.</strong></dd>
+ <dt><code>enumerable</code></dt>
+ <dd><code>true</code> se e somente se esta propriedade aparece durante enumeração das propriedades no objeto correspondente.<br>
+ <strong>Valor padrão é <code>false</code>.</strong></dd>
+</dl>
+
+<p>Um descritor de dados também possui as seguintes chaves opcionais:</p>
+
+<dl>
+ <dt><code>value</code></dt>
+ <dd>O valor associado com a propriedade. Pode ser qualquer valor válido em Javascript  (número, objeto, função, etc).<br>
+ <strong>Valor padrão é {{jsxref("undefined")}}.</strong></dd>
+ <dt><code>writable</code></dt>
+ <dd><code>true</code> se e somente se o valor associado com a propriedade pode ser modificada com um {{jsxref("Operators/Assignment_Operators", "operador de atribuição", "", 1)}}.<br>
+ <strong>Valor padrão é <code>false</code>.</strong></dd>
+</dl>
+
+<p>Um descritor de assessor também possui as seguintes chaves opcionais:</p>
+
+<dl>
+ <dt><code>get</code></dt>
+ <dd>Uma função que servirá como um getter da propriedade, ou {{jsxref("undefined")}} se não houver getter. Quando a propriedade é acessada, esta função é chamada sem argumentos e com <code>this</code> define para o objeto no qual a propriedade é acessada (este pode não ser o objeto sobre o qual a propriedade está definida devido a herança). O valor retornado será usado como valor da propriedade.<br>
+ <strong>Valor padrão é {{jsxref("undefined")}}.</strong></dd>
+ <dt><code>set</code></dt>
+ <dd>A função que servirá como um setter para a propriedade, ou {{jsxref("undefined")}} se não houver setter. Quando a propriedade é atribuída, esta função é chamada com um argumento (o valor sendo atribuído para a propriedade) e com <code>this</code> configura o objeto através do qual a propriedade é atribuída.<br>
+ <strong>Valor padrão é {{jsxref("undefined")}}.</strong></dd>
+</dl>
+
+<p>Se um descritor tem  nenhum das chaves <code>value</code>, <code>writable</code>, <code>get</code> e <code>set</code>, ele é tratado como um descritor de dados. Se um descritor tem ambas chaves <code>value</code> ou <code>writable</code> e <code>get</code> ou <code>set</code> keys, uma exceção é lançada.</p>
+
+<p>Tenha em mente que estes atributos não são necessariamente as propriedades do próprio descritor. Propriedades herdadas serão consideradas também. Para garantir que estes padrões sejam preservados, você pode congelar o {{jsxref("Object.prototype")}} previamente, declarar todas as opções explicitamente, ou apontar para {{jsxref("null")}} com {{jsxref("Object.create", "Object.create(null)")}}.</p>
+
+<pre class="brush: js notranslate">// usando __proto__
+var obj = {};
+var descriptor = Object.create(null); // não herdar propriedades
+// não enumerável, não configurável, não gravável por padrão
+descriptor.value = 'static';
+Object.defineProperty(obj, 'key', descriptor);
+
+// declarando explicitamente
+Object.defineProperty(obj, 'key', {
+ enumerable: false, // não enumerável
+ configurable: false, // não configurável
+ writable: false, // não gravável
+ value: 'static'
+});
+
+// reciclando um mesmo objeto
+function withValue(value) {
+ var d = withValue.d || (
+ withValue.d = {
+ enumerable: false,
+ writable: false,
+ configurable: false,
+ value: null
+ }
+ );
+ d.value = value;
+ return d;
+}
+
+// ... e ...
+Object.defineProperty(obj, 'key', withValue('static'));
+
+// se o método freeze estiver disponível, prevenir as propriedades
+// (value, get, set, enumerable, writable, configurable) de serem
+// incluídas ou removidas do protótipo do objeto
+(Object.freeze || Object)(Object.prototype);</pre>
+
+<h2 id="Exemplos">Exemplos</h2>
+
+<p>Se você deseja utilizar o método <code>Object.defineProperty</code> com uma sintaxe estilo <em>flags-binárias</em>, veja os <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty/Additional_examples">exemplos adicionais</a>.</p>
+
+<h3 id="Criando_uma_propriedade">Criando uma propriedade</h3>
+
+<p>Quando a propriedade especificada não existe no objeto, <code>Object.defineProperty()</code>  cria uma nova propriedade conforme descrito anteriormente. Campos podem ser omitidos no descritor, e os valores padrão para esses campos serão introduzidos.</p>
+
+<p>Todos os campos do tipo Boolean possuem como valor padrão <code>false</code>. Os campos <code>value</code>, <code>get</code>, e <code>set</code> possuem como padrão {{jsxref("undefined")}}.  Uma propriedade que é definida sem os valores para <code>get</code>/<code>set</code>/<code>value</code>/<code>writable</code> é dita "genérica" e classificada como um descritor de dados.</p>
+
+<pre class="brush: js notranslate">var o = {}; // Criar um novo objeto
+
+// Exemplo de propriedade de objeto inserida através
+// de defineProperty com descritor do tipo dado
+Object.defineProperty(o, 'a', {
+ value: 37,
+ writable: true,
+ enumerable: true,
+ configurable: true
+});
+// A propriedade 'a' existe no objeto com valor 37
+
+// Exemplo de propriedade de objeto inserida através
+// de defineProperty com descritor do tipo assessor
+var bValue = 38;
+
+Object.defineProperty(o, 'b', {
+ get: function() { return bValue; },
+ set: function(newValue) { bValue = newValue; },
+ enumerable: true,
+ configurable: true
+});
+
+o.b; // 38
+// A propriedade 'b' existe no objeto com valor 38
+// O valor de o.b será sempre idêntico a bValue, a
+// menos que o.b seja redefinido
+
+// Você não pode combinar ambos os tipos:
+Object.defineProperty(o, 'conflict', {
+ value: 0x9f91102,
+ get: function() { return 0xdeadbeef; }
+});
+// lança um TypeError: value existe apenas em descritores
+// de dado, get existe apenas em descritores de assessor</pre>
+
+<h3 id="Modificando_uma_propriedade">Modificando uma propriedade</h3>
+
+<p>Quando uma propriedade já existe, <code>Object.defineProperty()</code> tenta modificá-la de acordo com os valores do descritor e a configuração atual do objeto. Se o descritor antigo possuía seu atributo <code>configurable</code> como <code>false</code> a propriedade é chamada "não configurável" e nenhum atributo pode ser alterado <font face="consolas, Liberation Mono, courier, monospace">(exceto a alteração irreversível de <em>writable </em>para <em>false</em>)</font>. Não é possível alternar o tipo de uma propriedade entre dados e assessor quando esta for não-configurável.</p>
+
+<p>Um {{jsxref("TypeError")}} é lançado quando são realizadas tentativas de se alterar propriedades não-configuráveis (exceto o atributo <code>writable</code>) a menos que o valor atual e o novo sejam os mesmos.</p>
+
+<h4 id="O_atributo_writable">O atributo writable</h4>
+
+<p>Quando o atributo <code>writable</code> de uma propriedade é definido como <code>false</code>, a propriedade é dita "não-gravável". Seu valor não poderá ser alterado.</p>
+
+<pre class="brush: js notranslate">var o = {}; // Cria um novo objeto
+
+Object.defineProperty(o, 'a', {
+ value: 37,
+ writable: false
+});
+
+console.log(o.a); // escreve 37
+
+o.a = 25; // Nenhum erro é lançado (no modo strict seria
+ // lançado mesmo que o valor fosse o mesmo)
+
+console.log(o.a); // escreve 37. A atribuição não teve efeito.</pre>
+
+<p>Como visto no exemplo, tentativas de escrita em uma propriedade não-gravável não alteram seu valor, mas também não lançam erros.</p>
+
+<h4 id="O_atributo_enumerable">O atributo enumerable</h4>
+
+<p>O atributo <code>enumerable</code> de uma propriedade define se ela deve ser exibida em uma repetição {{jsxref("Statements/for...in", "for...in")}} e por {{jsxref("Object.keys()")}} ou não.</p>
+
+<pre class="brush: js notranslate">var o = {};
+
+Object.defineProperty(o, 'a', {
+ value: 1,
+ enumerable: true
+});
+
+Object.defineProperty(o, 'b', {
+ value: 2,
+ enumerable: false
+});
+
+Object.defineProperty(o, 'c', {
+ value: 3
+}); // o valor padrão para enumerable é false
+
+o.d = 4; // o valor padrão para enumerable é true quando
+ // a propriedade é criada em uma atribuição
+
+for (var i in o) {
+ console.log(i);
+}
+// escreve 'a' e 'd' (em ordem indefinida)
+
+Object.keys(o); // ['a', 'd']
+
+o.propertyIsEnumerable('a'); // true
+o.propertyIsEnumerable('b'); // false
+o.propertyIsEnumerable('c'); // false</pre>
+
+<h4 id="O_atributo_configurable">O atributo configurable</h4>
+
+<p>O atributo <code>configurable</code> controla ao mesmo se uma propriedade pode ser deletada do objeto, e se seus atributos (exceto a mudança de <code>writable</code> para <code>false</code>) podem ser alterados.</p>
+
+<pre class="brush: js notranslate">var o = {};
+
+Object.defineProperty(o, 'a', {
+ get: function() { return 1; },
+ configurable: false
+});
+
+Object.defineProperty(o, 'a', {
+ configurable: true
+}); // lança um TypeError
+
+Object.defineProperty(o, 'a', {
+ enumerable: true
+}); // lança um TypeError
+
+Object.defineProperty(o, 'a', {
+ set: function() {}
+}); // lança um TypeError (o atributo set já estava definido)
+
+Object.defineProperty(o, 'a', {
+ get: function() { return 1; }
+}); // lança um TypeError
+ // (mesmo o novo get fazendo exatamente a mesma coisa)
+
+Object.defineProperty(o, 'a', {
+ value: 12
+}); // lança um TypeError
+
+console.log(o.a); // escreve 1
+delete o.a; // Nada acontece
+console.log(o.a); // escreve 1</pre>
+
+<p>Se o atributo <code>configurable</code> de <code>o.a</code> fosse <code>true</code>, nenhum dos erros seria lançado e a propriedade estaria deletada ao final.</p>
+
+<h3 id="Incluindo_propriedades_e_valores_padrão">Incluindo propriedades e valores padrão</h3>
+
+<p>É importante considerar a forma como os valores padrão para atributos são aplicados. Normalmente existe diferença entre usar a notação por ponto para atribuir um valor e usar <code>Object.defineProperty()</code>, como pode ser visto no exemplo abaixo:</p>
+
+<pre class="brush: js notranslate">var o = {};
+
+o.a = 1;
+
+// é equivalente a:
+Object.defineProperty(o, 'a', {
+ value: 1,
+ writable: true,
+ configurable: true,
+ enumerable: true
+});
+
+// Por outro lado,
+Object.defineProperty(o, 'a', { value: 1 });
+
+// é equivalente a:
+Object.defineProperty(o, 'a', {
+ value: 1,
+ writable: false,
+ configurable: false,
+ enumerable: false
+});</pre>
+
+<h3 id="Setters_e_getters_customizados">Setters e getters customizados</h3>
+
+<p>O exemplo abaixo mostra como implementar um objeto auto-arquivável. Quando a propriedade <code>temperature</code> é atribuída, o array <code>archive</code> recebe uma nova entrada de log.</p>
+
+<pre class="brush: js notranslate">function Archiver() {
+ var temperature = null;
+ var archive = [];
+
+ Object.defineProperty(this, 'temperature', {
+ get: function() {
+ console.log('get!');
+ return temperature;
+ },
+ set: function(value) {
+ temperature = value;
+ archive.push({ val: temperature });
+ }
+ });
+
+ this.getArchive = function() { return archive; };
+}
+
+var arc = new Archiver();
+arc.temperature; // 'get!'
+arc.temperature = 11;
+arc.temperature = 13;
+arc.getArchive(); // [{ val: 11 }, { val: 13 }]</pre>
+
+<p>Neste exemplo, um getter sempre returna o mesmo valor.</p>
+
+<pre class="brush: js notranslate">var pattern = {
+ get: function () {
+ return 'Eu sempre retorno esta string, ' +
+ 'não importa o que você atribuiu';
+ },
+ set: function () {
+ this.myname = 'esta string é meu nome';
+ }
+};
+
+function TestDefineSetAndGet() {
+ Object.defineProperty(this, 'myproperty', pattern);
+}
+
+var instance = new TestDefineSetAndGet();
+instance.myproperty = 'test';
+
+console.log(instance.myproperty);
+// Eu sempre retorno esta string, não importa o que você atribuiu
+
+console.log(instance.myname); // esta string é meu nome
+</pre>
+
+<h3 id="Propriedades_de_Herança">Propriedades de Herança </h3>
+
+<p>Se uma propriedade de acessor é herdada, métodos <code>get</code> e <code>set</code> serão chamados quando a propriedade é acessada e modificada sobre os objetos descendentes. Se estes métodos usam uma variável para armazenar o valor, este valor será compartilhada por todos os objetos.</p>
+
+<pre class="notranslate"><code>function myclass() {
+}
+
+var value;
+Object.defineProperty(myclass.prototype, "x", {
+ get() {
+ return value;
+ },
+ set(x) {
+ value = x;
+ }
+});
+
+var a = new myclass();
+var b = new myclass();
+a.x = 1;
+console.log(b.x); // 1</code></pre>
+
+<p>Isto pode ser corrigido armazenando o valor em outra propriedade. Em métodos <code>get</code> e <code>set</code>, <code>this</code> aponta para o objeto no qual é usado para acessar ou modificar a propriedade.</p>
+
+<pre class="notranslate"><code>function myclass() {
+}
+
+Object.defineProperty(myclass.prototype, "x", {
+ get() {
+ return this.stored_x;
+ },
+ set(x) {
+ this.stored_x = x;
+ }
+});
+
+var a = new myclass();
+var b = new myclass();
+a.x = 1;
+console.log(b.x); // undefined</code></pre>
+
+<p>Ao contrário das propriedades do acessor, propriedades do valor serão sempre configuradas sobre  o próprio objeto, não sobre um protótipo. Entretanto, se uma propriedade de valor não-gravável é herdada, ele ainda previne de modicação a propriedade do objeto.</p>
+
+<pre class="notranslate"><code>function myclass() {
+}
+
+myclass.prototype.x = 1;
+Object.defineProperty(myclass.prototype, "y", {
+ writable: false,
+ value: 1
+});
+
+var a = new myclass();
+a.x = 2;
+console.log(a.x); // 2
+console.log(myclass.prototype.x); // 1
+a.y = 2; // Ignorado, lança no modo strict
+console.log(a.y); // 1
+console.log(myclass.prototype.y); // 1</code>
+</pre>
+
+<h2 id="Especificações">Especificações</h2>
+
+<table>
+ <tbody>
+ <tr>
+ <th scope="col">Especificação</th>
+ <th scope="col">Status</th>
+ <th scope="col">Comentários</th>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES5.1', '#sec-15.2.3.6', 'Object.defineProperty')}}</td>
+ <td>{{Spec2('ES5.1')}}</td>
+ <td>Definição inicial. Implementada no JavaScript 1.8.5.</td>
+ </tr>
+ <tr>
+ <td>{{SpecName('ES6', '#sec-object.defineproperty', 'Object.defineProperty')}}</td>
+ <td>{{Spec2('ES6')}}</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>{{SpecName('ESDraft', '#sec-object.defineproperty', 'Object.defineProperty')}}</td>
+ <td>{{Spec2('ESDraft')}}</td>
+ <td></td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Compatibilidade_de_browser">Compatibilidade de browser</h2>
+
+<div class="hidden">
+<p>A tabela de compatibilidade nesta página é gerada à partir de dados estruturados. Se você quiser contribuir, consulte <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> e nos mande uma requisição de pull.</p>
+</div>
+
+<p>{{Compat("javascript.builtins.Object.defineProperty")}}</p>
+
+<h2 id="Notas_de_compatibilidade">Notas de compatibilidade</h2>
+
+<h3 id="Redefinindo_a_propriedade_length_de_um_objeto_Array">Redefinindo a propriedade <code>length</code> de um objeto <code>Array</code> </h3>
+
+<p>É possível redefinir a propriedade {{jsxref("Array.length", "length")}} de arrays, sujeita às restrições de redefinição usuais. (A propriedade {{jsxref("Array.length", "length")}} é inicialmente não configurável, não enumerável, mas gravável. Assim, em um array que não foi modificado, é possível alterar o valor da propriedade {{jsxref("Array.length", "length")}} ou torná-la não-gravável. Não é permitido alterar sua enumerabilidade ou configurabilidade, ou quando se encontrar não-gravável, alterar seu valor ou torná-la gravável novamente.) Entretanto, nem todos os browsers permitem esta redefinição.</p>
+
+<p>Das versões 4 até 22 do Firefox, um {{jsxref("TypeError")}} é lançado em qualquer tentativa (seja ela permitida ou não) de redefinir a propriedade {{jsxref("Array.length", "length")}} de um array.</p>
+
+<p>Versões do Chrome que implementam <code>Object.defineProperty()</code> em algumas circunstâncias ignoram um valor para <em>length</em> diferente do valor atual da propriedade {{jsxref("Array.length", "length")}} do array. Em algumas circustâncias, alterar o atributo <code>writable</code> falha de forma silenciosa (sem lançar uma exceção). Além disso, alguns métodos que modificam o array como {jsxref("Array.prototype.push")}} não respeitam uma propriedade <em>length</em> não-gravável.</p>
+
+<p>Versões do Safari que implementam <code>Object.defineProperty()</code> ignoram um valor para <code>length</code> diferente do valor atual da propriedade {{jsxref("Array.length", "length")}}, e tentantivas de alterar o atributo <code>writable</code> executam sem erros embora não modifiquem seu comportamento.</p>
+
+<p>Apenas o Internet Explorer 9 a posteriores, e o Firefox 23 e posteriores, parecem implementar total e corretamente a redefinição da propriedade {{jsxref("Array.length", "length")}} de arrays. Por enquanto, não confie que a redefinição da propriedade {{jsxref("Array.length", "length")}} vá funcionar, mesmo que de uma forma particular. E mesmo quando você <em>puder </em>confiar, <a href="http://whereswalden.com/2013/08/05/new-in-firefox-23-the-length-property-of-an-array-can-be-made-non-writable-but-you-shouldnt-do-it/">existem boas razões para não fazer isso</a>.</p>
+
+<h3 id="Notas_específicas_para_o_Internet_Explorer_8">Notas específicas para o Internet Explorer 8</h3>
+
+<p>O Internet Explorer 8 implementa o método <code>Object.defineProperty()</code> para uso <a href="https://msdn.microsoft.com/en-us/library/dd229916%28VS.85%29.aspx">apenas em objetos DOM</a>. Algumas observações:</p>
+
+<ul>
+ <li>Tentativas de usar <code>Object.defineProperty()</code> em objetos nativos lançam um erro.</li>
+ <li>Todos os atributos da propriedade devem ter seu valor definido. Os atributos <code>configurable</code>, <code>enumerable</code> e <code>writable</code> devem ser <code>true</code> para um descritor do tipo dado, e <code>true</code> para <code>configurable</code> e <code>false</code> para <code>enumerable</code> em descritores do tipo assessor. (?) Qualquer tentativa de usar outros valores (?) resultará no lançamento de um erro.</li>
+ <li>Reconfigurar uma propriedade exige que ela seja deletada anteriormente. Se a propriedade não for deletada, ela permanecerá inalterada após a tentativa de reconfiguração.</li>
+</ul>
+
+<h2 id="Veja_também">Veja também</h2>
+
+<ul>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Enumerability_and_ownership_of_properties">Enumerabilidade and posse de propriedades</a></li>
+ <li>{{jsxref("Object.defineProperties()")}}</li>
+ <li>{{jsxref("Object.propertyIsEnumerable()")}}</li>
+ <li>{{jsxref("Object.getOwnPropertyDescriptor()")}}</li>
+ <li>{{jsxref("Object.prototype.watch()")}}</li>
+ <li>{{jsxref("Object.prototype.unwatch()")}}</li>
+ <li>{{jsxref("Operators/get", "get")}}</li>
+ <li>{{jsxref("Operators/set", "set")}}</li>
+ <li>{{jsxref("Object.create()")}}</li>
+ <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty/Additional_examples">Exemplos adicionais de <code>Object.defineProperty</code></a></li>
+ <li>{{jsxref("Reflect.defineProperty()")}}</li>
+</ul>