Introduction to EcmaScript5
First of all, we must figure out that ECMAScript is a god-ma. We know that JavaScript or LiveScript was originally created by Netscape, and later Microsoft also followed up to create Jscript. ScriptEase also has its own CENvi. In this way, there are three versions of browser Script that do their own. Everyone understands this chaotic, so the issue of standardization is put on the agenda. In 1997, the proposal based on JavaScript1.1 was submitted to the European Computer Manufacturers Association (European Computer M anufacturers A sector). Finally, everyone developed ECMA-262, a new scripting language standard called ECMAScript. The following year, ISO/IEC (International Organization for Standardization and International Electrotechnical Commission) also adopted ECMAScript as the standard. After that, the world will be peaceful. Major browser manufacturers use ECMAScript as the basis for their respective implementation of JavaScript. Of course, it is just the foundation and has not been completely followed. Otherwise, we would not have so many browser compatibility issues.
What is ECMAScript5? As the name suggests, it is the fifth version of this strange thing, just like the iPhone 5. ECMAScript3, which we often use now, is considered a real programming language rather than a toy, and has become very popular.
text:
I have always had a wrong understanding of get/set before, and I think get set is an object attribute method. I also had many questions after reading other people’s blogs. Today, the system did a lot of tests and finally figured it out. (If you pass the reading and writing demo tests yourself, if there is any incorrect, you are welcome to criticize and correct me)
The get/set accessor is not an object's property, but a property's property. Everyone must distinguish clearly. Features are only used internally, so they cannot be accessed directly in javascript. To indicate that the characteristics are internal values are enclosed in brackets between the two teams, such as [[Value]].
1. Let me briefly introduce these characteristics of attributes (here is a simple endorsement)
(1) Data attribute - the position containing a data value. This position can read and write values.
Data attributes have four characteristics that describe their behavior:
[[Configurable]]: Is it configurable?
[[Enumerable]]: Is it enumerable?
[[Writable]]: Is it readable
[[Value]]: Attribute value
(2) Accessor attribute attribute - does not contain data values, contains a getter and setter function (these two functions are not required)
Accessor properties also have four characteristics that describe their behavior:
[[Configurable]]: Is it configurable?
[[Enumerable]]: Is it enumerable?
[[Get]]: The function called when reading attributes, default is undefined
[[Set]]: The function called when writing attributes, default is undefined
2. Here we focus on introducing [[Get]]/[[Set]] is what we call get/set accessor
Let’s first talk about the behavioral characteristics of the get/set accessor mentioned in the book: the get/set accessor can be read and written without definition. You can also define only one. If only get is defined, the described attributes can only be readable and not writable. If only set is defined, the described attributes can only be written and not readable.
(1) Our original get set method is as follows:
function Foo(val){var value=val;this.getValue=function(){return value;};this.setValue=function (val){value=val;};}var obj=new Foo("hello");alert(obj.getValue());//"hello"obj.setValue("hi");alert(obj.getValue());//"hi"The above code is just a get set method implemented using the closure scope. Note that the method is the attribute method of the instance object, not the attribute property. If not defined, the value value will not be accessible
function Foo(val){var value=val;/* this.getValue=function(){return value;}; this.setValue=function (val){value=val;};*/}var obj=new Foo("hello");alert( obj.value);//undefinedThe following examples are also attribute methods of objects, not attribute properties.
var obj={name:"john",get:function (){return this.age;}//Only get is defined, set is not defined, but it can still read, write, and name attributes, even if it is age//The method defined here will not affect the get, set attributes of the attributes. Just a normal object attribute};alert(obj.name);//john readable obj.name="jack";//writable alert(obj.name);//jack(2) Get/set accessor as a property of the accessor attribute.
Again, it is not an object's attribute, they decide whether the attribute can be read and written. If not set, it is OK, just like reading and writing normally (properties can be read or read
Write, read and write access to the property itself)
There are two ways to change the get /set attribute:
a. Use Object.defineProperty()
var object={_name:"Daisy" };Object.defineProperty(object,"name",{//The method name here means that a name property is defined (so it can be accessed through object.name), only the getter accessor is defined, no [[value]] value get:function (){//Only the get attribute is defined, so it can only be read but not written return this._name;}});alert(object.name);//"Daisy"object.name="jack";//Only the getter accessor is defined, so the write is invalid alert(object.name);//"Daisy" object.name="jack";//Only the getter accessor is defined, so the write is invalid alert(object.name);//"Daisy"Note that the property name in Object.defineProperty(object,pro,{}) must correspond to the properties accessed by object.pro.
b. Use the get set keyword:
var object={_name:"Daisy",get name(){//The method name here means that a name attribute is defined (so it can be accessed through object.name), only the getter accessor is defined, no [[value]] value is defined. Return this._name;}//get,set method is only a property of the attribute, not an object method, which determines whether the attribute can be read and written}; alert(object.name);// Daisy The method to remove the underscore here is Daisy; plus it is undefinedobject.name="jack";// Only the getter accessor is defined, so it can only be read but not write alert(object.name);//DaisyThe above two methods are equivalent. Note that both the above two methods will have two attributes in the object object: _name (with initial value) name (without initial value), which can be seen through the browser console.
So when is this name attribute really defined? We know that Object.defineProperty(object,pro,{}) can define a new property pro for the object. Since get pro(){}/set pro(){} and Object.defineProperty(object,pro,{}) are equivalent, a new property pro will also be defined. This is why there are two properties in object.
(3) The implementation code of Get and Set accessor in JavaScript in this article: Related to the implementation of Get and Set accessors of standard standards: Reasonable thoughts
I wrote an example myself
function Foo(val){this.value=val;//The value attribute is defined and no _value}Foo.prototype={set value(val){//Note that the method name and attribute name are the same, the value attribute is defined in the prototype this._value=val;}, get value(){//The method name and attribute name are the same, and the value attribute and its get attribute are defined in the prototype return this._value;}}; //The accessor returns and sets them are both _name, and there is no definition here. Why can it be read or written? ? ? ? var obj=new Foo("hello"); alert(obj.value);//"hello" obj.value="yehoo"; alert(obj.value);//"yehoo"In order to solve the above question, a lot of tests have been done, let’s take a look at it one by one:
First look at this example. Only the get feature is defined in prototype. When reading the value attribute in obj.value, look for it in the instance without it, and then find it in the prototype. The get method is called, which can only be read but not written.
function Foo(val){this._value=val;//The attribute here is underlined, initializes the _value attribute of the instance object, the _value attribute is readable and writable}Foo.prototype={// set value(val){// Note that the method name is the same as the attribute name, and the value attribute is defined in the prototype // this._value=val;// },get value(){// The method name is the same as the attribute name, defines the value attribute and its get attribute in the prototype return this._value;}}; var obj=new Foo("hello");alert(obj.value);//hello accesses the value in the prototype The attribute obj.value="yehoo";//Only defines the get attribute of the name attribute, so it can only be read but not written. The write is invalid alert(obj.value);//helloIf this._value is removed from the underscore in the constructor, the value attribute defined in the prototype defines the get attribute. You can still control the read and write of the value attribute. In other words, when obj.value accesses attributes, the get method will be called, first searching in the object itself, if not, then searching in prototype. If nothing is not, it will be considered undefined. The default is both readable and writable.
function Foo(val){this.value=val;//Only the get feature of value is defined in the prototype, so the write here is invalid}Foo.prototype={// set value(val){//Note that the method name and attribute name are the same, the set feature of the value attribute is defined in the prototype// this._value=val;//},//value:"hah",// Even if the value value is written manually, since the get method returns this._value, value cannot be read correctly: "hah"//As long as the get pro (){} and set pro (){} attributes are declared, they can read and write, but if the function definition is wrong, the correct property value cannot be accessed as required. value(){//The method name is the same as the attribute name. The value attribute and its get attribute are defined in the prototype. Return this._value;}}; var obj=new Foo("hello");//"hello" was not successfully written alert(obj.value);//undefined obj.value="yehoo";//only defined the get attribute, so it can only be read but not written, and the write is invalid alert(obj.value);//undefined alert(obj.value);//undefinedTo prove that the above example is readable and not writable: manually write _value:"hah", you can read the value but cannot write it.
function Foo(val){this.value=val;//Only the get feature of value is defined in the prototype, so the write here is invalid}Foo.prototype={// set value(val){//Note that the method name and attribute name are the same, the set feature of the value attribute is defined in the prototype// this._value=val;//},_value:"hah",// Even if the value value is written manually, since the get method returns this._value, value cannot be read correctly: "hah"//As long as the get pro (){} and set pro (){} attributes are declared, they can read and write, but if the function definition is wrong, the correct property value cannot be accessed as required. value(){//The method name is the same as the attribute name. The value attribute and its get attribute are defined in the prototype. Return this._value;}}; var obj=new Foo("hello");//"hello" was not successfully written alert(obj.value);//"hah" obj.value="yehoo";// Only the get attribute is defined, so it can only be read but not written, and the write is invalid alert(obj.value);//"hah"If the value:"hah" is written manually, can I strive to read the value of the value? Since this._value returned by the get method is not defined, obj.value reads the value value and calls get value(){} method to fail, but the value still cannot be written.
function Foo(val){this.value=val;//Only the get feature of value is defined in the prototype, so the write here is invalid}Foo.prototype={// set value(val){//Note that the method name and attribute name are the same, the set feature of the value attribute is defined in the prototype// this._value=val;//},value:"hah",// Even if the value value is written manually, since the get method returns this._value, value cannot be read correctly: "hah"//As long as the get pro (){} and set pro (){} attributes are declared, they can read and write, but if the function definition is wrong, the correct property value cannot be accessed as required. value(){//The method name and attribute name are the same. The value attribute and its get feature are defined in the prototype. Return this._value;}}; var obj=new Foo("hello");//"hello" was not written successfully alert(obj.value);//undefined read invalid because as long as obj.value, get returns this._value, and there is no value, so undefinedobj.value="yehoo";//only the get feature is defined, so it can only be read but not written, and the write invalid alert(obj.value);//undefinedLooking at this example, get set is defined, but returns this._value that is not defined. You can find that the value can be read and writeable. Remove the get set method in the prototype and it can still be readable or written
function Foo(val){this.value=val;}Foo.prototype={set value(val){this._value=val;},get value(){return this._value;}}; var obj=new Foo("hello");alert(obj.value);//hello obj.value="yehoo";alert(obj.value);//yehoo function Foo(val){this.value=val;}//It is the same as usual, that is, it returns to the default state where the get /set accessor characteristics are not defined var obj=new Foo("hello");alert(obj.value);//hello obj.value="yehoo";alert(obj.value);//yehooSummarize
Only the get pro(){} attribute is readable and not writable;
Only declare the set pro(){} attribute to be writable and unreadable.
If none of the declarations are declared, the attributes are readable and writable;
If all declarations are made, read and write according to the method defined by get set;
If all are declared, but the defined read and write method cannot be read and written correctly, get/set will fail. Become the default readable and writeable
The value attribute defined in the prototype defines the get attribute. You can still control the read and write of the value attribute. In other words, when obj.value accesses attributes, the get method will be called, first searching in the object itself, and then searching in prototype. If there is nothing, it will be considered undefined. The default is both readable and writable.
Replenish:
Whether using get pro(){}/set pro(){} or Object.defineProperty(object,pro,{ get:function (){ return this._name; } });pro cannot be the same as return this., otherwise the following error will be reported: (I don't know why, it seems to be a stack overflow caused by my own call)
After the master's correction, I understand why the error is reported here: if this.value is returned in the get value(){} method, the get method of value will be called again, thus falling into a dead loop, causing the method stack to overflow.