Maison  >  Article  >  interface Web  >  Explication détaillée de l'opérateur de suppression et des instances d'attributs internes dans js

Explication détaillée de l'opérateur de suppression et des instances d'attributs internes dans js

小云云
小云云original
2018-03-31 17:20:132131parcourir

Cet article partage principalement avec vous l'explication détaillée des exemples d'opérateurs de suppression et d'attributs internes dans js. Avant d'expliquer Configurable, examinons d'abord une question d'entretien :

a = 1;console.log( window.a ); 
// 1console.log( delete window.a ); 
// trueconsole.log( window.a ); 
// undefinedvar b = 2;console.log( window.b ); 
// 2console.log( delete window.b ); 
// falseconsole.log( window.b ); // 2

Comme le montre ce qui précède. question La différence entre les deux : lorsqu'une variable n'est pas déclarée à l'aide de var, elle peut être supprimée à l'aide du mot-clé delete, et la valeur sera indéfinie lorsqu'elle sera à nouveau obtenue lorsqu'une variable déclarée à l'aide de var est supprimée, elle ne peut pas être supprimée à l'aide de delete ; , et la valeur reste la même une fois obtenue à nouveau. C'est 2.

1. Opérateur de suppression

Lorsque vous utilisez delete pour supprimer une variable ou un attribut, il renvoie vrai si la suppression est réussie, sinon il renvoie faux. Comme dans l'exemple ci-dessus, si delete ne peut pas supprimer la variable a, il renvoie false ; si delete peut supprimer avec succès la variable b, il renvoie true.

En plus des deux situations ci-dessus, il existe diverses autres variables couramment utilisées qui peuvent être supprimées et certaines qui ne peuvent pas être supprimées. Ne nous inquiétons pas de la raison pour laquelle un tel résultat se produit lors de la suppression de ces variables. Ici, nous regardons uniquement sa valeur de retour :

Supprimez l'un des éléments du tableau de suppression :

// 使用for~in是循环不到的,直接忽略到该元素
// 使用for()可以得到该元素,但是值是undefinedvar arr = [1, 2, 3, 4];console.log( arr );             
// [1, 2, 3, 4]console.log( delete arr[2] );   
// true,删除成功console.log( arr );             
// [1, 2, undefined, 4]

Supprimez le. Variables de type de fonction :

// chrome 不能删除;火狐可以删除function func(){
}
console.log( func );console.log( delete func );
console.log( func );

Supprimer function.length, qui est le nombre de paramètres formels à obtenir :

function func1(a, b){
}console.log( func1.length );       
 // 2console.log( delete func1.length ); 
 // true,删除成功console.log( func1.length );       
  // 0

Supprimer les variables communes :

console.log( delete NaN );     
 // false,删除失败console.log( delete undefined );
 // falseconsole.log( delete Infinity ); 
 // falseconsole.log( delete null );     
 // true,删除成功

Supprimer le prototype, au lieu de supprimer les attributs sur le prototype :

function Person(){
}
Person.prototype.name = "蚊子";console.log( delete Person.prototype );
 // false,无法删除console.log( delete Object.prototype ); 
 // false

Lors de la suppression de la longueur des tableaux et des chaînes :

var arr = [1, 2, 3, 4];console.log( arr.length );          
// 4console.log( delete arr.length );   
// false,删除失败console.log( arr.length );          
// 4var str = 'abcdefg';console.log( str.length );         
 // 7console.log( delete str.length );   
 // false,删除失败console.log( str.length );         
  // 7

Lors de la suppression des attributs dans obj :

var obj = {name:'wenzi', age:25};console.log( obj.name );       
 // wenziconsole.log( delete obj.name ); 
 // true,删除成功console.log( obj.name );        
 // undefinedconsole.log( obj );             
 // { age:25 }

Lors de la suppression d'attributs dans un objet d'instance, vous pouvez voir dans le résultat suivant que lorsque vous utilisez delete pour supprimer des attributs, seuls les attributs de l'objet d'instance lui-même sont supprimés et les attributs du prototype ne peuvent pas être supprimés même si vous le faites. supprimez-le à nouveau, il sera toujours supprimé. Il ne peut pas être supprimé ; si vous souhaitez supprimer les attributs ou les méthodes des attributs sur le prototype, vous pouvez uniquement supprimer Person.prototype.name :

function Person(){    this.name = 'wenzi';
}
Person.prototype.name = '蚊子';var student = new Person();console.log( student.name );        
// wenziconsole.log( delete student.name ); 
// true,删除成功console.log( student.name );        
// 蚊子console.log( delete student.name ); 
// trueconsole.log( student.name );       
 // 蚊子console.log( delete Person.prototype.name );
 // true,删除成功console.log( student.name );       
  // undefined

2. Les attributs internes de js

sont ci-dessus Dans l'exemple, certaines variables ou attributs peuvent être supprimés avec succès, tandis que d'autres ne peuvent pas être supprimés. Alors, qu'est-ce qui détermine si cette variable ou cet attribut peut être supprimé.

ECMA-262 5ème Édition définit les caractéristiques des propriétés des objets JS (utilisées dans les moteurs JS, non directement accessibles de l'extérieur). Il existe deux types de propriétés dans ECMAScript : les propriétés de données et les propriétés d'accesseur.

2.1 Attribut de données

Un attribut de données fait référence à un emplacement contenant une valeur de données, où la valeur peut être lue ou écrite. Cet attribut a 4 caractéristiques qui décrivent son comportement :

<.>.[[configurable]] : Indique s'il peut être supprimé et redéfini à l'aide de l'opérateur delete, ou s'il peut être modifié en tant qu'attribut accesseur. La valeur par défaut est true ;

[[Enumberable]] : indique si l'attribut peut être renvoyé via une boucle for-in. True par défaut;
[[Writable]] : Indique si la valeur de l'attribut peut être modifiée. True par défaut ;
[[Value]] : contient la valeur des données de cet attribut. Cette valeur est lue/écrite. La valeur par défaut n'est pas définie ; par exemple, l'attribut name est défini dans l'objet d'instance Personne ci-dessus, et sa valeur est 'wenzi'. Les modifications de cette valeur se font de toute façon à cet emplacement

Pour modifier les caractéristiques par défaut du. attributs d'objet (la valeur par défaut est true ), vous pouvez appeler la méthode Object.defineProperty(), qui reçoit trois paramètres : l'objet où se trouve la propriété, le nom de la propriété et un objet descripteur (doit être : configurable, numérotable, inscriptible et valeur, une ou plusieurs valeurs peuvent être définies).

est le suivant :

var person = {};Object.defineProperty(person, 'name', {
    configurable: false,    // 不可删除,且不能修改为访问器属性
    writable: false,        // 不可修改
    value: 'wenzi'          // name的值为wenzi});console.log( person.name);          // wenziconsole.log( delete person.name );  // false,无法删除person.name = 'lily';console.log( person.name );         // wenzi
On peut voir que ni la suppression ni la réinitialisation de la valeur de person.name ne prennent effet. En effet, l'appel de la fonction définirProperty modifie les caractéristiques de l'objet. propriétés ; il convient de le noter Une fois que configurable est défini sur false, vous ne pouvez plus utiliser DefineProperty pour le modifier en true (l'exécution signalera une erreur : Uncaught TypeError : Impossible de redéfinir la propriété : nom);

2.2 Propriétés de l'accesseur

it Il comprend principalement une paire de fonctions getter et setter. Lors de la lecture de l'attribut accesseur, le getter sera appelé pour renvoyer une valeur valide lorsque l'attribut accesseur sera écrit, le setter sera appelé pour écrire le ; nouvelle valeur ; cet attribut a les 4 caractéristiques suivantes :

[[Configurable]] : Si l'attribut peut être supprimé et redéfini via l'opérateur de suppression

. peut être trouvé via une boucle for-in
[[Get] ] : automatiquement appelé lors de la lecture des propriétés, par défaut : undefined ;

Les propriétés de l'accesseur ne peuvent pas être définies directement et doivent utiliser definitionProperty (), comme suit :

Cependant, il y a encore une chose qui nécessite une attention particulière lors de la définition des propriétés avec l'objet. DefinissezProperty(), vous ne pouvez pas déclarer les propriétés d'accesseur (set et get) et les propriétés de données (inscriptibles ou valeur). Cela signifie que si une propriété a un ensemble d'attributs inscriptible ou value, alors cette propriété ne peut pas déclarer get ou set, et vice versa.
var person = {
    _age: 18};Object.defineProperty(person, 'isAdult', {
    Configurable : false,
    get: function () {        if (this._age >= 18) {            return true;
        } else {            return false;
        }
    }
});console.log( person.isAdult );  // true

如若像下面的方式进行定义,访问器属性和数据属性同时存在:

var o = {};Object.defineProperty(o, 'name', {
    value: 'wenzi',
    set: function(name) {
        myName = name;
    },
    get: function() {        return myName;
    }
});

上面的代码看起来貌似是没有什么问题,但是真正执行时会报错,报错如下:

Uncaught TypeError: Invalid property. A property cannot both have accessors and be writable or have a value

对于数据属性,可以取得:configurable,enumberable,writable和value;

对于访问器属性,可以取得:configurable,enumberable,get和set。

由此我们可知:一个变量或属性是否可以被删除,是由其内部属性Configurable进行控制的,若Configurable为true,则该变量或属性可以被删除,否则不能被删除。

可是我们应该怎么获取这个Configurable值呢,总不能用delete试试能不能删除吧。有办法滴!!

2.3 获取内部属性

ES5为我们提供了Object.getOwnPropertyDescriptor(object, property)来获取内部属性。

如:

var person = {name:&#39;wenzi&#39;};var desp = Object.getOwnPropertyDescriptor(person, &#39;name&#39;); // person中的name属性console.log( desp );    // {value: "wenzi", writable: true, enumerable: true, configurable: true}

通过Object.getOwnPropertyDescriptor(object, property)我们能够获取到4个内部属性,configurable控制着变量或属性是否可被删除。这个例子中,person.name的configurable是true,则说明是可以被删除的:

console.log( person.name );         
// wenziconsole.log( delete person.name );  
// true,删除成功console.log( person.name );         
// undefined

我们再回到最开始的那个面试题:

a = 1;var desp = Object.getOwnPropertyDescriptor(window, &#39;a&#39;);console.log( desp.configurable );   // true,可以删除var b = 2;var desp = Object.getOwnPropertyDescriptor(window, &#39;b&#39;);console.log( desp.configurable );   // false,不能删除

跟我们使用delete操作删除变量时产生的结果是一样的。

相关推荐:

JavaScript delete操作符应用实例_javascript技巧

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn