Discussion: get/set accessors and actionscriptgetset for new JavaScript ECAMScript5 features
Introduction to EcmaScript5
First, we must first understand that ECMAScript is a magic horse. We know that JavaScript or LiveScript was first developed by Netscape. Later, Microsoft also developed Jscript, and ScriptEase also had its own CENvi, in this way, three versions of browser scripts are used in different ways. Everyone understands this confusion, so the standardization issue has been put on the agenda. In 1997, the proposal modeled on JavaScript1.1 was submitted to the European Computer Manufacturers Association (E uropean C omputer M anufacturers A ssociation ), finally, everyone produced the ECMA-262-a new scripting language standard called ECMAScript. In the second year, ISO/IEC (International Standardization Organization and International Electrotechnical Commission) also adopted ECMAScript as the standard. Since then, the world has been peaceful. Major browser vendors have used ECMAScript as their own JavaScript implementation bases, of course, this is only the foundation, but it is not completely followed. Otherwise, we will not have so many browser compatibility problems.
What is ECMAScript5? As the name suggests, like iPhone5, it is the fifth version of this strange stuff. We now use ECMAScript3, which is quite popular compared to the first two versions.
Body:
The previous understanding of get/set has always been incorrect. I think get set is an object attribute method. I have a lot of questions after reading other people's blogs. Today, the system has done a lot of tests and finally figured it out. (If you have read a book or write a demo for testing, you are welcome to criticize and correct it)
The get/set accessors are not the properties of objects, but the properties. You must make it clear. Features are only used internally, so they cannot be accessed directly in javaScript. To indicate the feature, internal values are enclosed in brackets, for example, [[Value].
1. Briefly introduce these attributes (here is a simple endorsement)
(1) Data Attribute-the location that contains a data value. This location can be used to read and write values.
Data attributes have four characteristics that describe the behavior:
[[Retriable]: whether or not it can be configured
[[Enumerable]: whether Enumerable can be enumerated
[[Writable]: whether it is readable
[[Value]: Attribute Value
(2) accessors property properties -- contains no data value, including a getter and setter functions (these two functions are not required)
The accessors attributes also have four features that describe the behavior:
[[Retriable]: whether or not it can be configured
[[Enumerable]: whether Enumerable can be enumerated
[[Get]: The function called when reading the attribute. The default value is undefined.
[[Set]: The function called when writing an attribute. The default value is undefined.
2. [[Get]/[[Set] is what we call get/set accessors.
First, let's talk about the get/set accessors behavior features in a book: get/set accessors can read and write attribute values without definition or definition. You can also define only one. If only get is defined, the description attribute is only readable and cannot be written. If only set is defined, the property to be described is writable and unreadable.
(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 only uses the get set method implemented by the closure scope. Note that the method is the attribute method of the Instance Object, not the attribute feature. If this parameter is not specified, the value cannot be accessed.
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);//undefined
The following example shows the object's property method, not the property feature.
Var obj = {name: "john", get: function () {return this. age;} // only get is defined. No set is defined, but the set attribute can still be read, written, and name, even if the method defined here is age //, The get and set attributes are not affected. Only common object attributes}; alert (obj. name); // john readable obj. name = "jack"; // you can write alert (obj. name); // jack
(2) get/set accessors as the feature of accessors.
Again, it is not an object attribute. They decide whether the attribute can be read or written. If you do not set it, it will be the same as reading and writing in peacetime (the attribute can be readable
Write, read/write access is the value of the attribute itself)
There are two ways to change the get/set attribute:
A. Object. defineProperty ()
Var object = {_ name: "Daisy"}; Object. defineProperty (object, "name", {// The method name here indicates that a name attribute is defined (therefore, the object can be used. name access), only getter accessors are defined, and no [[value] value get: function () {// only get features are defined, therefore, you can only read and cannot write return this. _ name ;}}); alert (object. name); // "Daisy" object. name = "jack"; // only the getter accessors are defined, so the write failure alert (object. name); // "Daisy"
Note that the attribute name in Object. defineProperty (object, pro, {}) must correspond to the attribute accessed by object. pro.
B. Use the get set Keyword:
Var object = {_ name: "Daisy", get name () {// The method name here indicates that a name attribute is defined (therefore, the object can be used. name access), only getter accessors are defined, and [[value] value return this is not defined. _ name;} // get, the set method is only a property feature, not an object method, and determines whether or not the attribute can be read/written}; alert (object. name); // Daisy the underline method is Daisy, and undefinedobject. name = "jack"; // only the getter accessors are defined. Therefore, you can only read and not write alert (object. name); // Daisy
The above two methods are equivalent. Note that the object objects in the preceding two methods both have two attributes: _ name (with an initial value) name (without an initial value). You can see this in the browser console.
When will this name attribute be defined? We know Object. defineProperty (object, pro, {}) can define a new property pro for the Object, since get pro () {}/set pro () {} and object. defineProperty (object, pro, {}) is equivalent, a new property pro is also defined. this is why the object has two attributes.
(3) In this article, the Get and Set accessors implementation code in the Web-beautiful JavaScript about the implementation of standard Get and Set accessors:
I wrote the same example myself.
Function Foo (val) {this. value = val; // defines the value Attribute and does not define _ value} Foo. prototype = {set value (val) {// note that the method name and attribute name are the same. The value attribute this is defined in prototype. _ value = val ;}, get value () {// The method name and attribute name are the same. The value Attribute and Its get feature return this are defined in prototype. _ value ;}}; // The accessors return and set both _ name. The _ name attribute is not defined here. Why can this attribute be read and written ???? Var obj = new Foo ("hello"); alert (obj. value); // "hello" obj. value = "yehoo"; alert (obj. value); // "yehoo"
In order to solve the above questions, we have done a lot of tests. Let's take a look at them one by one:
Let's take a look at this example. In prototype, only the get feature is defined. In obj. when value is used to read the value attribute, it is not found in the instance, and then found in the prototype. The prototype get method is called and can only be read but not written.
Function Foo (val) {this. _ value = val; // The attribute here is underlined. It initializes the _ value Attribute of the Instance Object and the _ value attribute is readable and writable} Foo. prototype = {// set value (val) {// note that the method name and attribute name are the same, and the value Attribute // this is defined in prototype. _ value = val; //}, get value () {// The method name and attribute name are the same. The value Attribute and Its get feature return this are defined in prototype. _ value ;}}; var obj = new Foo ("hello"); alert (obj. value); // hello accesses the value Attribute obj in prototype. value = "yehoo"; // only the get feature of the name attribute is defined. Therefore, only the read and write operations are allowed, and the write operation fails. alert (obj. value); // hello
If this. _ value in the constructor removes the underline, the value Attribute defined in prototype defines the get feature. You can still control the read and write operations on the value attribute. That is to say, when obj. value is used to access the attribute, the get method will be called, first in the object itself, if there is no, then to the prototype search, if there is no definition, it is both readable and writable by default.
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, and the set feature of the value attribute is defined in prototype. // this. _ value = val; //}, // value: "hah", // even if the value is manually written, the get method returns this. _ value, so the value: "hah" // as long as the get pro () {} and set pro () {} attributes are declared, they can be read and written, however, if the function definition is incorrect, the correct attribute value get value () {// The method name and attribute name cannot be accessed as required, the value Attribute and Its get feature return this are defined in prototype. _ value ;}}; var obj = new Foo ("hello"); // "hello" is not successfully written into alert (obj. value); // undefined obj. value = "yehoo"; // only the get feature is defined. Therefore, only the read and write operations are allowed, and the write operation fails. alert (obj. value); // undefined
To prove that the preceding example is readable and unwritable: 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, and the set feature of the value attribute is defined in prototype. // this. _ value = val; //}, _ value: "hah", // even if the value is manually written, the get method returns this. _ value, so the value: "hah" // as long as the get pro () {} and set pro () {} attributes are declared, they can be read and written, however, if the function definition is incorrect, the correct attribute value get value () {// The method name and attribute name cannot be accessed as required, the value Attribute and Its get feature return this are defined in prototype. _ value ;}}; var obj = new Foo ("hello"); // "hello" is not successfully written into alert (obj. value); // "hah" obj. value = "yehoo"; // only the get feature is defined. Therefore, only the read and write operations are allowed, and the write operation fails. alert (obj. value); // "hah"
If you manually write value: "hah", can you try to read the value? Because this. _ value returned by the get method is not defined, the get value () {} method called to read the value of obj. value is invalid, but the value 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, and the set feature of the value attribute is defined in prototype. // this. _ value = val; //}, value: "hah", // even if the value is manually written, the get method returns this. _ value, so the value: "hah" // as long as the get pro () {} and set pro () {} attributes are declared, they can be read and written, however, if the function definition is incorrect, the correct attribute value get value () {// The method name and attribute name cannot be accessed as required, the value Attribute and Its get feature return this are defined in prototype. _ value ;}}; var obj = new Foo ("hello"); // "hello" is not successfully written into alert (obj. value); // undefined read failure because only obj. value will call get, and get returns this. _ value, which does not exist, so undefinedobj. value = "yehoo"; // only the get feature is defined. Therefore, only the read and write operations are allowed, and the write operation fails. alert (obj. value); // undefined
In this example, get set is defined, but this. _ value is not defined. We can find that the value is both readable and writable. Remove the get set Method in the prototype, and it is still readable and writable.
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;} // The operation is the same in peacetime, return to the default status var obj = new Foo ("hello"); alert (obj. value); // hello obj. value = "yehoo"; alert (obj. value); // yehoo
Summary
Only get pro () {} attributes are declared as readable and not writable;
Only declare the set pro () {} attribute to be writable and unreadable.
If they are not declared, attributes can be read and written;
If all statements are declared, read and write according to the method defined by get set;
If all statements are declared, but the defined read/write method cannot read and write correctly, the get/set is invalid. It becomes the default readable and writable
The value Attribute defined in prototype defines the get feature. You can still control the read and write operations on the value attribute. That is, obj. when the value accesses the attribute, the get method is called. The get method is first searched for in the object itself. If no value is found, it is searched for in prototype. If no value is defined, the default value is readable and writable.
Supplement:
Whether it is get pro () {}/set pro () {} or Object. defineProperty (object, pro, {get: function () {return this. _ name ;}});
Pro cannot have the same attributes as return this. Otherwise, the following error will be reported: (I don't know why, as if Stack Overflow caused by my own call)
After being corrected, I understand why the following error is reported: this is returned in the get value () {} method. value, it will call the get method of value again, so it falls into an endless loop, resulting in method stack overflow.