This article mainly introduces the Internal Attributes of js and the relevant information about the delete operator.
Configurable
Before that, let's take a look at an interview question:
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
From the above question, we can see the two differences: When var is not used to declare a variable, the delete keyword can be used to delete it, And the undefined value is obtained again; when using a variable declared by var, You cannot delete it by using delete, and the value is still 2.
1. delete Operator
If you delete a variable or attribute using delete, 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. We don't care.DeleteWhy do these variables produce such a result? Here we only look at the returned values:
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 can only be deleted once: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. Internal Attributes of js
In the above 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 attributes
Data Attribute refers to the location where a data value can be read or written. This attribute has four characteristics to confess its behavior:
- [[Retriable]: indicates whether the delete operator can be used to delete and redefine the object, or whether the object can be modified to the accessors attribute. The default value is true;
- [[Enumberable]: Indicates whether an attribute can be returned through a for-in loop. The default value is true;
- [[Writable]: indicates whether the attribute value can be modified. The default value is true;
- [[Value]: the data Value that contains this attribute. This value is used to read/write data. The default value is undefined. For example, if the name attribute is defined in the Person object of the instance above, the value is 'wenzi', and all modifications to this value are at this location.
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 Cannot use defineProperty to change it to true (the execution reports the following error: Uncaught TypeError: Cannot redefine property: name );
2.2 accessors attributes
It 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:
- [[Retriable]: whether to use the delete operator to delete and redefine attributes;
- [[Numberable]: whether this attribute can be searched through the for-in loop;
- [[Get]: automatically called when reading attributes. Default Value: undefined;
- [[Set]: automatically called when writing an attribute. Default Value: undefined;
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
For data attributes, you can obtain: retriable, enumberable, writable, and value;
For accessors, you can obtain the following attributes: retriable, enumberable, get, and set.
We can see that:Whether a variable or attribute can be deleted depends on its internal attributes.Configurable
IfConfigurable
If this parameter is set to true, the variable or attribute can be deleted. Otherwise, the variable or attribute cannot be deleted.
But how can we get this?Configurable
The value cannot be deleted using delete. You can try it !!
2.3 obtain Internal Attributes
ES5 provides usObject.getOwnPropertyDescriptor(object, property)
To obtain internal properties.
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}
PassObject.getOwnPropertyDescriptor(object, property)
We can get four internal attributes,RetriableDetermines whether a variable or attribute 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. Summary
Look at a simple delete operation, which actually contains a lot of principles!