Heim > Web-Frontend > js-Tutorial > Hauptteil

Diskussion: Neue Funktionen von JavaScript ECAMScript5 erhalten/setzen accessor_javascript-Fähigkeiten

WBOY
Freigeben: 2016-05-16 15:02:13
Original
1098 Leute haben es durchsucht

Einführung in EcmaScript5

Zunächst müssen wir verstehen, dass ECMAScript ein magisches Pferd ist. Wir wissen, dass JavaScript oder LiveScript zuerst von Netscape erstellt wurde und auch Jscript erstellt hat Browser-Skripte machen alle ihr eigenes Ding, und jeder versteht diese Verwirrung, daher wurde das Thema Standardisierung auf die Tagesordnung gesetzt. Im Jahr 1997 wurde der European Computer Manufacturers Association ein auf JavaScript 1.1 basierender Vorschlag vorgelegt, und schließlich sangen und tanzten alle ECMA-262, einen neuen Skriptsprachenstandard namens ECMAScript. Im nächsten Jahr übernahm ISO/IEC (International Organization for Standardization and International Electrotechnical Commission) natürlich auch ECMAScript als Standard , es handelt sich lediglich um eine Grundlage und wird nicht vollständig befolgt. Andernfalls werden wir auch nicht so viele Probleme mit der Browserkompatibilität haben.

Was ist ECMAScript5? Wie der Name schon sagt, handelt es sich um die fünfte Version dieses seltsamen Dings wie iPhone5. Im Vergleich zu den ersten beiden Versionen ist diese Version eher eine echte Programmiersprache als ein Spielzeug, und sie ist sehr geworden beliebt.

Text:

Mein bisheriges Verständnis von get/set war falsch. Ich dachte, get set sei eine Objekteigenschaftsmethode. Ich hatte auch viele Fragen, nachdem ich die Blogs anderer Leute gelesen hatte. Heute habe ich viele Tests mit dem System durchgeführt und es endlich herausgefunden. (Ich habe den Test durch das Lesen von Büchern und das Schreiben von Demos bestanden. Wenn es Fehler gibt, können Sie mich gerne kritisieren und korrigieren)

Die get/set-Accessoren sind keine Eigenschaften des Objekts, sondern Merkmale der Eigenschaft. Jeder muss klar unterscheiden. Eigenschaften werden nur intern verwendet und können daher nicht direkt über JavaScript aufgerufen werden. Um das Attribut anzugeben, wird der interne Wert in zwei Sätze eckiger Klammern eingeschlossen, z. B. [[Wert]].

1. Lassen Sie uns diese Eigenschaften von Attributen kurz vorstellen (hier ist eine einfache Bestätigung)

(1) Datenattribut – enthält den Speicherort eines Datenwerts. An dieser Stelle können Werte gelesen und geschrieben werden.

Datenattribute haben vier Merkmale, die ihr Verhalten beschreiben:

[[Konfigurierbar]]: Ob es konfigurierbar ist

[[Aufzählbar]]: Ob es aufzählbar ist

[[Beschreibbar]]: Ob es lesbar ist

[[Wert]]: Attributwert 

(2) Accessor-Attribut-Attribut – enthält keinen Datenwert, enthält eine Getter- und Setter-Funktion (diese beiden Funktionen sind nicht erforderlich)

Accessor-Eigenschaften weisen außerdem vier Merkmale auf, die ihr Verhalten beschreiben:

[[Konfigurierbar]]: Ob es konfigurierbar ist

[[Aufzählbar]]: Ob es aufzählbar ist

[[Get]]: Funktion, die beim Lesen von Eigenschaften aufgerufen wird, der Standardwert ist undefiniert

[[Set]]: Funktion, die beim Schreiben von Attributen aufgerufen wird, der Standardwert ist undefiniert 

2. Hier konzentrieren wir uns auf [[Get]]/[[Set]], was wir den Get/Set-Accessor nennen

Lassen Sie uns zunächst über die Verhaltensmerkmale des im Buch erwähnten Get/Set-Accessors sprechen: Der Get/Set-Accessor muss nicht definiert werden und kann Attributwerte lesen und schreiben, ohne ihn zu definieren. Sie können auch nur eine definieren. Wenn nur get definiert ist, ist das beschriebene Attribut nur lesbar, nicht schreibbar. Wenn nur „set“ definiert ist, kann das beschriebene Attribut nur geschrieben und nicht gelesen werden.

(1) Unsere ursprüngliche Get-Set-Methode sieht folgendermaßen aus:

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" 
Nach dem Login kopieren

Der obige Code ist nur die Get-Set-Methode, die mithilfe des Abschlussbereichs implementiert wird. Beachten Sie, dass es sich bei der Methode um die Attributmethode des Instanzobjekts und nicht um das Attributmerkmal handelt. Wenn er nicht definiert ist, ist der Wert value
nicht zugänglich.

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
Nach dem Login kopieren

Die folgenden Beispiele sind ebenfalls Eigenschaftsmethoden von Objekten, keine Eigenschaftsmerkmale.

var obj={
name:"john",
get:function (){
return this.age;
}//只定义了get ,没有定义set,但是仍然可以读,写,name属性,即使这里是age
//这里这样定义的方法不会影响属性的get,set 特性。只是普通的对象属性
};
alert(obj.name);//john 可读
obj.name="jack";//可写
alert(obj.name);//jack 
Nach dem Login kopieren

(2) Accessor als Merkmal des Accessor-Attributs abrufen/festlegen.

Auch hier handelt es sich nicht um die Eigenschaften des Objekts, sondern sie bestimmen, ob und wie die Eigenschaften gelesen und geschrieben werden können. Es ist in Ordnung, wenn Sie es nicht festlegen. Es erfolgt das gleiche wie beim normalen Lesen und Schreiben (das Attribut kann gelesen werden

).

Schreiben, Lesen und Schreibzugriff sind der Wert des Attributs selbst)

Um die Get/Set-Eigenschaften eines Attributs zu ändern, gibt es zwei Möglichkeiten:

a. Verwenden Sie einfach Object.defineProperty()

var object={
_name:"Daisy" 
};
Object.defineProperty(object,"name",{//这里的方法名name,就表示定义了一个name属性(因此才能通过object.name访问),只定义了getter访问器,没有定义[[value]]值
get:function (){//只定义了get 特性,因此只能读不能写
return this._name;
}
});
alert(object.name);//"Daisy"
object.name="jack";//只定义了getter访问器,因此写入失效
alert(object.name);//"Daisy" 
Nach dem Login kopieren

Beachten Sie, dass die Eigenschaftsnamen in Object.defineProperty(object, pro, {}) den Eigenschaften entsprechen müssen, auf die object.pro zugreift

b. Verwenden Sie einfach das Schlüsselwort „get set“:

var object={
_name:"Daisy",
get name(){//这里的方法名name ,就表示定义了一个name属性(因此才能通过object.name访问),只定义了getter访问器,没有定义[[value]]值
return this._name;
}//get,set方法只是属性的特性 ,不是对象方法,决定属性能否、怎么读写
};
alert(object.name);// Daisy这里去掉下划线 方法就是Daisy ;加上就是undefined
object.name="jack";//只定义了getter访问器,因此只能读不能写
alert(object.name);//Daisy 
Nach dem Login kopieren

以上两种方法等效。注意的是以上两种方法object对象当中都将有有两个属性:_name(有初始值) name(无初始值),通过浏览器控制台可以看到

那么这个name属性实在什么时候定义的呢?我们知道Object.defineProperty(object,pro,{})可以给对象定义一个新属性pro,既然get pro(){}/set pro(){}和Object.defineProperty(object,pro,{})等效,则也会定义一个新属性pro .这就是为什么object里面有两个属性的原因。

(3)在此篇文章中网络之美 JavaScript中Get和Set访问器的实现代码关于标准标准的Get和Set访问器的实现:引发的思考

我自己也写了一个一样的例子

function Foo(val){
this.value=val;//定义了value属性 并没有定义_value
}
Foo.prototype={
set value(val){//注意方法名和属性名相同,在prototype里定义了value属性
this._value=val;
},
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; //访问器返回和设置的都是_name,这里并没有定义_name属性为什么也可以读可以写????     
var obj=new Foo("hello");     
alert(obj.value);//"hello"     
obj.value="yehoo";     
alert(obj.value);//"yehoo" 
Nach dem Login kopieren

为了解决以上这个疑问,做了很多测试,我们一一来看:

先看这个例子,在prototype里面只定义get 特性,在obj.value读value属性时,在实例里面寻找没有,然后在原型里面找到,调用的是原型的get方法,只能读不能写

function Foo(val){
this._value=val;//这里 的属性是带下划线的,初始化实例对象的_value属性,_value属性可读可写
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性
// this._value=val;
// },
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");
alert(obj.value);//hello 访问的是prototype里面的value 属性
obj.value="yehoo";//只定义了name 属性的get 特性,因此只能读不能写,写入失效
alert(obj.value);//hello 
Nach dem Login kopieren

如果构造函数里面this._value 去掉下划线,在prototype里面定义的value属性,定义了get 特性。依然可以控制value属性的读写 。也就是说obj.value访问属性时,会调用get方法,先在对象本身寻找,如果没有,再到prototype寻找,如果都没有才算没有定义,默认的既可读又可写

function Foo(val){
this.value=val;//在原型里面只定义了value的get特性,因此这里写入失效
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性的set特性
// this._value=val;
//},
//value:"hah",//即使手动写入value值,由于get方法返回的是this._value,因此也不能正确读取value:"hah"
//只要声明了get pro (){}和set pro (){}属性就都能读能写,但是如果函数定义错误,依然不能按要求访问到正确的属性值
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");//"hello"没有写入成功
alert(obj.value);//undefined 
obj.value="yehoo";//只定义了get 特性,因此只能读不能写,写入失效
alert(obj.value);//undefined 
Nach dem Login kopieren

为了证明上面例子是可读不可写的:手动写入_value:"hah",就可以读取value 但不能写入。

function Foo(val){
this.value=val;//在原型里面只定义了value的get特性,因此这里写入失效
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性的set特性
// this._value=val;
//},
_value:"hah",//即使手动写入value值,由于get方法返回的是this._value,因此也不能正确读取value:"hah"
//只要声明了get pro (){}和set pro (){}属性就都能读能写,但是如果函数定义错误,依然不能按要求访问到正确的属性值
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");//"hello"没有写入成功
alert(obj.value);//"hah" 
obj.value="yehoo";//只定义了get 特性,因此只能读不能写,写入失效
alert(obj.value);//"hah" 
Nach dem Login kopieren

如果手动写入的是value:"hah",那么可以争取读取value的值吗?由于get方法返回的this._value并没有定义,obj.value读取value值调用get value(){}方法失效,但是value仍然不能写入。

function Foo(val){
this.value=val;//在原型里面只定义了value的get特性,因此这里写入失效
}
Foo.prototype={
// set value(val){//注意方法名和属性名相同,在prototype里定义了value属性的set特性
// this._value=val;
//},
value:"hah",//即使手动写入value值,由于get方法返回的是this._value,因此也不能正确读取value:"hah"
//只要声明了get pro (){}和set pro (){}属性就都能读能写,但是如果函数定义错误,依然不能按要求访问到正确的属性值
get value(){//方法名和属性名相同,在prototype里面定义了value属性和它的get 特性
return this._value;
}
}; 
var obj=new Foo("hello");//"hello"没有写入成功
alert(obj.value);//undefined 读取失效 因为只要obj.value就会调用get ,而get返回的是this._value,没有这个值,因此undefined
obj.value="yehoo";//只定义了get 特性,因此只能读不能写,写入失效
alert(obj.value);//undefined 
Nach dem Login kopieren

再看这个例子,get set 都定义了,但是返回没有定义的this._value。可以发现value既可读又可写。去掉原型里面的get set方法,依然可读可写

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;
}
//和平时的操作是一样的了,就是回到了不定义get /set访问器特性的默认状态
var obj=new Foo("hello");
alert(obj.value);//hello 
obj.value="yehoo";
alert(obj.value);//yehoo 
Nach dem Login kopieren

总结

只声明了get pro(){}属性 可读不可写;

只声明 set pro(){}属性可写不可读。

如果都不声明,属性可读可写;

如果都声明就按照,get set 定义的方法,读写;

如果都声明了,但是定义的读写方法不能正确读写,get/set失效。变成默认的可读可写

在prototype里面定义的value属性,定义了get 特性。依然可以控制value属性的读写 。也就是说obj.value访问属性时,会调用get方法,先在对象本身寻找,如果没有,再到prototype寻找,如果都没有才算没有定义,默认的既可读又可写。

补充:

不管是用get pro(){}/set pro (){} 

还是用Object.defineProperty(object,pro,{


         get:function (){
           return this._name;
           } });
Nach dem Login kopieren

pro不能和 return this. 后面的属性一样,不然会报下面的错误:(具体我也不知道为什么,好像是自身调用引起的栈溢出)

经大神指正,明白为什么这里报错:在get value(){}方法里返回 this.value,就会又去调用value的get 方法,因此陷入死循环,造成方法栈溢出。

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!