Internal Attributes and delete operators in js
Before explaining resumable, let's take a look at one interview question:
a = 1;console.log( window.a ); // 1console.log( delete window.a ); // falseconsole.log( window.a ); // 1var b = 2;console.log( window.b ); // 2console.log( delete window.b ); // trueconsole.log( window.b ); // undefined
From the above question, we can see the two differences: When var is not used to declare a variable, the delete keyword cannot be used to delete the variable, and the value of variable a can still be obtained; when using the variables declared by var, you can use delete to delete them, and then get the value undefined. 1. When the delete operator uses delete to delete a variable or attribute, true is returned if the deletion is successful. Otherwise, false is returned. In the preceding example, if delete cannot delete variable a, false is returned. If delete successfully deletes variable B, true is returned. In addition to the preceding two cases, there are other common variables that can be deleted or not deleted. No matter why these variables are deleted, the following result is returned: delete an element in the delete array:
// USE ~ In cannot be cyclically. Ignore this element directly. // use for () to obtain this element, but the value is undefinedvar arr = [1, 2, 3, 4]; console. log (arr); // [1, 2, 3, 4] console. log (delete arr [2]); // true, console deleted successfully. log (arr); // [1, 2, undefined, 4]
Delete a function variable:
// Chrome cannot be deleted; Firefox can delete function func () {} console. log (func); console. log (delete func); console. log (func );
Delete function. length, which is the number of retrieved parameters:
Function func1 (a, B) {} console. log (func1.length); // 2console. log (delete func1.length); // true, console deleted successfully. log (func1.length); // 0
Delete common variables:
Console. log (delete NaN); // false: the console fails to be deleted. log (delete undefined); // falseconsole. log (delete Infinity); // falseconsole. log (delete null); // true, deleted successfully
Delete prototype, instead of deleting properties on prototype:
Function Person () {} Person. prototype. name = "mosquito"; console. log (delete Person. prototype); // false. The console cannot be deleted. log (delete Object. prototype); // false
When deleting the length of the array and string:
Var arr = [1, 2, 3, 4]; console. log (arr. length); // 4console. log (delete arr. length); // false, the console fails to be deleted. log (arr. length); // 4var str = 'abcdefg'; console. log (str. length); // 7console. log (delete str. length); // false, the console fails to be deleted. log (str. length); // 7
When deleting an attribute in obj:
Var obj = {name: 'wenzi', age: 25}; console. log (obj. name); // wenziconsole. log (delete obj. name); // true, console deleted successfully. log (obj. name); // undefinedconsole. log (obj); // {age: 25}
When deleting the attributes of an instance object, we can see from the following output that deleting the attributes using delete only deletes the attributes of the instance object, but cannot delete the attributes on prototype, the attribute or method of the prototype attribute cannot be deleted even if it is deleted again. It can only be: delete Person. prototype. name:
Function Person () {this. name = 'wenzi';} Person. prototype. name = 'mosquito '; var student = new Person (); console. log (student. name); // wenziconsole. log (delete student. name); // true, console deleted successfully. log (student. name); // mosquito console. log (delete student. name); // trueconsole. log (student. name); // mosquito console. log (delete Person. prototype. name); // true, console deleted successfully. log (student. name); // undefined
2. in the preceding example, some variables or attributes can be deleted successfully, while some variables or attributes cannot be deleted. What determines whether the variables or attributes can be deleted. ECMA-262 5th defines features in JS object attributes (for JS engines that cannot be accessed externally ). ECMAScript has two attributes: data attributes and accessors attributes. 2.1 data attribute refers to the location where a data value can be read or written. This attribute has four characteristics to confess its behavior: the default feature of the Object attribute to be modified (true by default). You can call Object. defineProperty () method, which receives three parameters: the object where the property is located, the property name and a descriptor object (must be: retriable, enumberable, writable, and value, you can set one or more values ). As follows:
Var person = {}; Object. defineProperty (person, 'name', {retriable: false, // cannot be deleted, and cannot be modified to the accessors property writable: false, // value cannot be modified: 'wenzi' // The value of name is wenzi}); console. log (person. name); // wenziconsole. log (delete person. name); // false, cannot delete person. name = 'lily'; console. log (person. name); // wenzi
We can see that delete and reset person. the value of name does not take effect. This is because the defineProperty function is called to modify the features of object properties. It is worth noting that once the retriable is set to false, then you can no longer use defineProperty to change it to true (the execution will report the following error: Uncaught TypeError: Cannot redefine property: name); 2.2 The accessors attribute mainly includes a pair of getter and setter functions, when reading the accessors attribute, getter is called to return the valid value. When writing the accessors attribute, setter is called to write new values. This attribute has the following four features: the accessors property cannot be defined directly. You must use defineProperty () to define it, as shown below:
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
Note that the Object. defineProperty () method cannot declare both the set and get attributes (writable or value) and the data attributes (writable or value ). This means that if the writable or value attribute is set for an attribute, the get and set attributes cannot be declared, and vice versa. If the following method is defined, the accessors and data attributes both exist:
var o = {};Object.defineProperty(o, 'name', { value: 'wenzi', set: function(name) { myName = name; }, get: function() { return myName; }});
The above Code seems to have no problem, but an error will be reported during actual execution. The error is as follows: Uncaught TypeError: Invalid property. A property cannot both have accessors and be writable or have a value can be obtained for the data attributes: retriable, enumberable, writable, and value. For the accessors attributes, you can obtain: retriable, enumberable, get and set. Therefore, we can know whether a variable or attribute can be deleted is controlled by its internal property retriable. If retriable is true, the variable or attribute can be deleted, otherwise, it cannot be deleted. But how can we get the retriable value? We can't try to delete it with delete. You can try it !! 2.3 get Internal Attributes ES5 provides Object. getOwnPropertyDescriptor (object, property) for us to get internal attributes. For example, var person = {name: 'wenzi'}; var desp = Object. getOwnPropertyDescriptor (person, 'name'); // name Attribute console in person. log (desp); // {value: "wenzi", writable: true, enumerable: true, retriable: true. getOwnPropertyDescriptor (object, property) We can get four internal attributes, which control whether the variables or attributes can be deleted. In this example, if the retriable value of person. name is true, it indicates that it can be deleted:
Console. log (person. name); // wenziconsole. log (delete person. name); // true, console. log (person. name) Deleted successfully; // undefined
Let's go back to the first interview question:
A = 1; var desp = Object. getOwnPropertyDescriptor (window, 'A'); console. log (desp. retriable); // true, you can delete var B = 2; var desp = Object. getOwnPropertyDescriptor (window, 'B'); console. log (desp. retriable); // false, cannot be deleted
The result is the same as when we delete a variable using the delete operation. 3. To sum up, don't look at a simple delete operation, which actually contains a lot of principles!