EcmaScript5简介
首先得先搞清楚ECMAScript是神马,我们知道JavaScript或者说LiveScript最开始是Netscape搞出来的,后来微软也跟进搞出了Jscript,ScriptEase也有自己的CENvi,这样就有了三个版本的浏览器Script各行其是,大家懂这个混乱的,于是乎标准化的问题被提上议事日程。1997年以JavaScript1.1为蓝本的建议被提交到欧洲计算机制造商协会( E uropean C omputer M anufacturers A ssociation),最后大家载歌载舞搞出了ECMA-262——一种名为ECMAScript的新脚本语言标准。第二年,ISO/IEC(国际标准化组织和国际电工委员会)也采用ECMAScript作为标准,此后天下太平,各大浏览器厂商以ECMAScript作为各自实现JavaScript的基础,当然只是基础,没完全按照来,否则我们也不会有那么多浏览器兼容性问题。
ECMAScript5是什么呢?顾名思义跟iPhone5一样是这个奇怪东东的第五个版本,我们现在常用的时ECMAScript3,相比前两个版本这个版本算是一门正真的编程语言而不是玩具了,变得很流行。
正文:
之前对get/set的理解一直有误,觉得get set 是对象属性方法。看了别人的博客也有很多疑问,今天系统的做了很多测试终于弄明白了。(自己通过看书和写demo测试的,如有不对欢迎大家批评指正)
get/set访问器不是对象的属性,而是属性的特性。大家一定要分清楚。特性只有内部才用,因此在javaScript中不能直接访问他们。为了表示特性是内部值用两队中括号括起来表示如[[Value]]。
1.先简单介绍一下属性的这些特性(这里是简单的背书)
(1)数据属性——包含一个数据值的位置。这个位置可以读入和写入值。
数据属性有描述其行为的四个特性:
[[Configurable]]:是否可配置
[[Enumerable]]:是否可枚举
[[Writable]]:是否可读
[[Value]]: 属性值
(2)访问器属性属性——不包含数据值,包含一个getter和setter函数(这两个函数不是必须的)
访问器属性也有描述其行为的四个特性:
[[Configurable]]:是否可配置
[[Enumerable]]:是否可枚举
[[Get]]:在读取属性时调用的函数,默认是undefined
[[Set]]:在写入属性时调用的函数,默认是undefined
2.这里着重介绍[[Get]]/[[Set]]就是我们所说的get/set访问器
先说一个书上说的 get/set访问器行为特点:get/set访问器可以不用定义,不定义也可以读写属性值。也可以只定义一个。只定义get,则被描述的属性只可读,不可写。只定义set,则被描述的属性只可写,不可读。
(1)我们原来的get set方法是这样的:
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"
以上代码只是利用闭包作用域实现的get set 方法,注意是方法即实例对象的属性方法,不是属性特性。如果不定义,将无法访问value值
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
以下例子也是对象的属性方法,不是属性特性。
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
(2)作为访问器属性的特性的get/set访问器。
再说一遍不是对象的属性,他们 决定属性能否、怎么读写。如果不设置也行,就和平时的读写一样(属性可读可
写,读写访问的都是属性本身的值)
要改变属性的get /set 特性,有两种方式:
a.就是用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"
注意Object.defineProperty(object,pro,{})中的属性名一定要和object.pro访问的属性对应
b.就是用用 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
以上两种方法等效。注意的是以上两种方法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"
为了解决以上这个疑问,做了很多测试,我们一一来看:
先看这个例子,在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
如果构造函数里面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
为了证明上面例子是可读不可写的:手动写入_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"
如果手动写入的是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
再看这个例子,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
总结
只声明了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; } });
pro不能和 return this. 后面的属性一样,不然会报下面的错误:(具体我也不知道为什么,好像是自身调用引起的栈溢出)
经大神指正,明白为什么这里报错:在get value(){}方法里返回 this.value,就会又去调用value的get 方法,因此陷入死循环,造成方法栈溢出。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

Python更适合数据科学和机器学习,JavaScript更适合前端和全栈开发。 1.Python以简洁语法和丰富库生态着称,适用于数据分析和Web开发。 2.JavaScript是前端开发核心,Node.js支持服务器端编程,适用于全栈开发。

JavaScript不需要安装,因为它已内置于现代浏览器中。你只需文本编辑器和浏览器即可开始使用。1)在浏览器环境中,通过标签嵌入HTML文件中运行。2)在Node.js环境中,下载并安装Node.js后,通过命令行运行JavaScript文件。

如何在Quartz中提前发送任务通知在使用Quartz定时器进行任务调度时,任务的执行时间是由cron表达式设定的。现�...

在JavaScript中如何获取原型链上函数的参数在JavaScript编程中,理解和操作原型链上的函数参数是常见且重要的任�...

在微信小程序web-view中使用Vue.js动态style位移失效的原因分析在使用Vue.js...

在Tampermonkey中如何对多个链接进行并发GET请求并依次判断返回结果?在Tampermonkey脚本中,我们经常需要对多个链...


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3 Linux新版
SublimeText3 Linux最新版

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

SublimeText3汉化版
中文版,非常好用

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。