宝哥软件园

讨论:获取/设置带有新特性的访问器

编辑:宝哥软件园 来源:互联网 时间:2021-11-01

EcmaScript5简介

首先,我们要搞清楚什么是ECMAScript。我们知道JavaScript或LiveScript最初是由网景公司创建的,后来微软跟进创建了JScript。ScriptEase也有自己的CENvi,这样就有了三个版本的浏览器脚本,大家都理解这种困惑,于是标准化问题就提上了日程。1997年,基于JavaScript1.1的提案被提交给欧洲计算机制造商协会(E urope c Computer m Manufacturers a Association),最后,大家又唱又跳,想出了ECMA-262——,一种叫做ECMAScript的新脚本语言标准。第二年,ISO/IEC(国际标准化组织和国际电工委员会)也采用了ECMAScript作为标准。从那以后,世界和平了,所有主要的浏览器制造商都采用了ECMAScript作为实现JavaScript的基础。当然,这只是基础,并没有完全遵循,否则我们也不会有那么多浏览器兼容性的问题。

什么是ECMAScript5?顾名思义,就是像iPhone5这种奇怪东西的第五个版本。现在常用ECMAScript3。与前两个版本相比,这个版本是真正的编程语言,而不是玩具,它变得非常流行。

文本:

以前对get/set的理解一直是错误的,我认为get set是一种对象属性方法。看了别人的博客,问题很多。今天做了很多系统的测试,终于想通了。(如果通过读写演示测试,欢迎批评指正。)

Get/set访问器不是对象的属性,而是属性的属性。每个人都必须分辨清楚。属性仅在内部使用,因此无法在javaScript中直接访问。为了表示属性是内部值,它由两对括号表示,例如[[Value]]。

1.首先简单介绍一下属性的这些特点(这里是简单的背书)。

(1)数据属性——包含数据值的位置。该位置可以读取和写入值。

属性有四个描述其行为的特征:

[[可配置]]:是可配置的?

[[Enumerable]]:是可枚举的吗?

[[可写]]:可读吗?

[[值]]:属性值。

(2)访问器属性属性——不包含数据值,但包含getter和setter函数(这两个函数不是必需的)。

存取器属性还有四个描述其行为的特征:

[[可配置]]:是可配置的?

[[Enumerable]]:是可枚举的吗?

[[获取]]:默认情况下,读取属性时调用的函数未定义。

[[Set]]:默认情况下,写入属性时调用的函数未定义。

2.这里要强调的是[[Get]]/[[Set]]就是我们所说的get/set访问器。

让我们在书中讨论get/set访问器的行为特征:get/set访问器可以在没有定义的情况下读写属性值。您也只能定义一个。如果只定义了get,所描述的属性只能读取,不能写入。如果只定义了set,则所描述的属性只能写入,不能读取。

我们最初的get set方法是这样的:

函数Foo(val){ var value=val;this . GetVaLue=function(){返回值;};this . SetVaLue=function(val){ value=val;};} var obj=new Foo(' hello ');alert(obj . GetVaLue());//' hello ' obj . setvalue(' hi ');alert(obj . GetVaLue());//‘hi’上面的代码只是闭包作用域实现的get set方法。请注意,方法是实例对象的属性方法,而不是属性属性。如果未定义,则无法访问值。

函数Foo(val){ var value=val;/* this . GetVaLue=function(){返回值;};this . SetVaLue=function(val){ value=val;};*/} var obj=new Foo(' hello ');alert(obj . value);//undefined以下示例也是对象的属性方法,而不是属性属性。

var obj={name:'john ',get : function(){ return this . age;}//只定义了get,get,set没有定义,但是仍然可以读写和命名属性,即使这是age//这里定义的方法不会影响属性的get和set特性。只是普通的对象属性};alert(obj . name);//约翰可读obj.name=' jack//写入alert(obj . name);//jack (2)一个get/set访问器,它是访问器属性的一个属性。

同样,这不是对象的属性。它们决定属性是否以及如何被读取和写入。如果不设置,和平时读写一样(属性可以读写。

写、读和写访问权限是属性本身的值)

有两种方法可以更改属性的get /set属性:

A.是使用Object.defineProperty()。

var对象={ _ name : ' Daisy ' };object . definepreproperty(object,' name ',{//这里的方法名表示定义了一个name属性(所以可以通过object.name访问),只定义了getter访问器,但是没有定义[[value]] value get:function()。{//只定义了get属性,所以只能读不能写。}});alert(object . name);//“黛西”object.name=“杰克”;//只定义了getter访问器,因此写入了无效的alert(object . name);//“Daisy”注意object.define属性(object,pro,{})必须对应于object.pro访问的属性.

B.是使用get set关键字:

Var object={_ name:' daisy ',getname(){//这里的方法名意味着定义了一个name属性(因此可以通过object.name访问),只定义了getter访问器,但是[[value]]值返回这个。_name未定义;}//get,set方法只是一个属性,不是object方法,它决定了属性是否可以读写};alert(object . name);//Daisy这里去掉下划线的方法是Daisy;添加undefinedobject.name=' jack//只定义了getter访问器,所以只能读取而不能写入alert(object . name);//Daisy,以上两种方法是等价的。注意,在上面两种方法中,对象对象中会有两个属性:_name(带初始值)name(不带初始值),可以通过浏览器控制台看到。

那么这个名字属性到底是什么时候定义的呢?我们知道那个物体。定义属性(对象,专业版,{})可以为对象定义新的属性专业版。因为get pro(){}/set pro(){}相当于Object。定义属性(对象,专业版,{}),还将定义一个新的属性专业版。这就是为什么对象中有两个属性。

(3)在本文中,JavaScript中Get和Set访问器的实现代码是关于标准Get和Set访问器的实现:一些思考。

我自己也写过类似的例子。

函数Foo(val){ this . value=val;//定义了value属性,但是_ value } foo . prototype={ setvalue(val){//请注意,方法名和属性名是相同的,value属性。_value=val在原型中定义;},get value(){//方法名与属性名相同,value属性及其get属性返回这个。_值在原型中定义;}};//访问器返回和设置的是_name,但这里没有定义属性_name。为什么能读或写?var obj=new Foo(' hello ');alert(obj . value);//“hello”obj . value=“yehoo”;alert(obj . value);//‘yehoo’为了解决上述问题,我们做了大量的测试。让我们一个一个来看:

先看这个例子,在原型中只定义了get特性。当obj.value读取value属性时,它会在实例中找到,然后在原型中找到。调用原型的get方法,只能读不能写。

函数Foo(val){this。_ value=val//此处的属性带有下划线。初始化实例对象的_value属性。_value属性是可读可写的。prototype={//setvalue(val){//注意方法名与属性名相同,而value属性//this。_value=val在原型中定义;//},get value(){//方法名与属性名相同,value属性及其get属性返回这个。_值在原型中定义;}};var obj=new Foo(' hello ');alert(obj . value);//hello访问原型中的value属性obj.value=' yehoo//只定义了name属性的get属性,所以只能读不能写,写了无效的alert(obj . value);//你好如果这。构造函数中的_value带有下划线,prototype中定义的value属性定义了get特性。您仍然可以控制value属性的读写。也就是说,当obj.value访问一个属性时,它会调用get方法,首先在对象本身中查找,如果没有,则在prototype中查找。如果没有,则不定义,默认值为可读和可写。

函数Foo(val){ this . value=val;//prototype中只定义了value的get属性,所以这里写的无效} foo . prototype={//setvalue(val){//注意方法名和属性名是一样的,value属性的set属性是在prototype //this中定义的。_ value=val//},//value:' hah '。//即使值是手动写入的,因为get方法会返回这个。_value,无法正确读取value :“hah”。//只要声明了get pro (){}和set pro (){}这两个属性,就可以读写,但是如果函数定义错误,仍然无法按要求访问正确的属性值getvalue(){//方法名与属性名相同,value属性及其get属性返回这个。_值在原型中定义;}};var obj=new Foo(' hello ');//“hello”未成功写入alert(obj . value);//undefined obj . value=' yehoo ';//只定义了get特征,所以只能读不能写,写了无效alert(obj.value)。//undefined为了证明上面的例子可读不可写,手动写_value:'hah ',可以读值但不能写。

函数Foo(val){ this . value=val;//prototype中只定义了value的get属性,所以这里写的无效} foo . prototype={//setvalue(val){//注意方法名和属性名是一样的,value属性的set属性是在prototype //this中定义的。_ value=val//},_ value: '哈哈'。//即使值是手动写入的,因为get方法会返回这个。_value,无法正确读取value :“hah”。//只要声明get pro (){}和set pro (){}属性,就可以读写,但如果函数定义错误,仍然无法按要求访问正确的属性值getvalue(){//方法名与属性名相同,value属性及其get属性返回这个。_值在原型中定义;}};var obj=new Foo(' hello ');//“hello”未成功写入alert(obj . value);//' hah ' obj . value=' yehoo ';//只定义了get特征,所以只能读不能写,写了无效alert(obj.value)。//'hah '如果value:'hah '是手工写的,你能试着读一下这个值吗?就像这样。get方法返回的_value未定义,obj.value读取该值并调用get value(){}方法失败,但该值仍无法写入。

函数Foo(val){ this . value=val;//prototype中只定义了value的get属性,所以这里写的无效} foo . prototype={//setvalue(val){//注意方法名和属性名是一样的,value属性的set属性是在prototype //this中定义的。_ value=val//},value:' hah '。//即使值是手动写入的,因为get方法会返回这个。_value,无法正确读取value :“hah”。//只要声明了get pro (){}和set pro (){}属性,就可以读写,但如果函数定义错误,仍然无法按要求访问正确的属性值getvalue(){//方法名与属性名相同,value属性及其get属性返回这个。_值在原型中定义;}};var obj=new Foo(' hello ');//“hello”未成功写入alert(obj . value);//undefined reading无效,因为get的调用时间和obj.value一样长,get返回这个。_value没有这个值,所以undefinedobj.value=' yehoo//只定义了get特征,所以只能读不能写,写了无效alert(obj.value)。//undefined再看一遍这个例子,getsets都被定义了,但是这个。_值未定义。您可以发现该值既可读又可写。去掉原型中的get set方法,仍然是可读可写的。

函数Foo(val){ this . value=val;} Foo . prototype={ set value(val){ this。_ value=val},get value(){返回这个。_值;}};var obj=new Foo(' hello ');alert(obj . value);//hello obj . value=' yehoo ';alert(obj . value);//yehoo函数Foo(val){ this . value=val;}//和平时期的操作是一样的,就是返回到没有定义get /set访问器特性的默认状态。var obj=new Foo(' hello ');alert(obj . value);//hello obj . value=' yehoo ';alert(obj . value);//yehoo摘要

只有get pro(){}属性被声明为可读但不可写;

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

如果两者都没有声明,则属性是可读可写的;

如果声明了它们,则根据get set定义的方法进行读写;

如果声明了它们,但定义的读写方法不能正确读写,get/set将无效。默认情况下变得可读和可写。

原型中定义的value属性定义了get属性。您仍然可以控制值属性的读写。也就是说,当obj.value访问一个属性时,它会调用get方法,首先在对象本身中查找,如果不是,则在prototype中查找。如果不是,则不定义,默认值是可读和可写。

补充:

请获取pro(){}/set pro (){}或object.defineproperty (object,pro,{get:function () {return this。_ name} });Pro不能和return这个后面的属性一样。否则会报错如下:(不知道为什么,好像是自身调用导致的堆栈溢出)。

经过大神的纠正,我明白为什么这里会报错了:如果在get value(){}方法中返回this.value,会再次调用value的get方法,因此陷入无限循环,导致方法栈溢出。

更多资讯
游戏推荐
更多+