前几天看了一下,es5的属性值,才发现里面的东西还挺深,挺坑的。原来写属性,无非就是像这样.
var People={ name:"Jimmy", age:18 } //或者 var People = new Object(); People.name = "Jimmy"; People.age = 18;一个是字面量定义,一个是创建实例添加属性. 后来看了js高级程序设计才知道,js中的属性我才用了50%. 为什么这么说呢? 因为js中的属性分为数据属性和访问器属性(descriptor),而我们通常写的属性只是数据属性,而且还有一些细节比如 [[writable]],[[enumberable]],[[value]] 等一些相关的设置我们都还没有涉及。 来,我们细细谈一下。
数据属性,就是我们平常定义的一些属性。
var Property = { name:"property" }但是,一门高级的语言不会让你知道 你到底哪里不知道. 在es5中, 对属性进行了更细的定义, 一个数据属性有4个配置项:
[[writable]] :(Boolean) 是否可以修改属性的值 [[Enumerable]] :(Boolean)是否可以通过for...in 循环出来 [[Coonfigurable]] :(Boolean)是否可以通过delete关键字删除 [[value]] :(xxx) 属性的内容,类型未知如果想使用者4个配置项的话,需要使用到es5新定义的一个方法. Object.defineProperty(); 老板啊喂,来个栗子~
var person = {}; Object.defineProperty(person,"name",{ person.name; writable: false, //不能修改属性的值 value: "Nicholas", //属性的值 configurable: false, //不能通过delete删除该属性 Enumerable: false //不能通过for...in 遍历出该属性 });Object.defineProperty(para1,para2,para3)里面第一个参数就是你要修改属性的对象, 第二个就是你要修改的属性,第三个就是详细的配置项. 看完这些不是不觉得脑袋蒙蒙哒, 对的,因为我们平常用不到,而且以后也很少会用。但是对于理解js这门 OO(Object-Oriented) 为标杆的语言是非常有利的。 平常我们使用字面量定义,比如:
var people = { name:"Jimmy" }js默认认为你的3个配置项(不包括value); 都是默认为true的. 如果你使用Object.defineProperty()定义(那你真是吃饱了没事,来秀技的):
var person = {}; Object.defineProperty(person,"name",{ person.name; value: "Jimmy" });他的3个配置项设置都为false. 这点和字面量定义需要区分开来.
这个descriptor可以算是一个tricks吧(个人观点). 平常用的时候,这个属性相当于 外部和数据属性的一个中间层. 因为你不能对访问器属性赋值...怎么说呢,他就是没有值。他只有两个函数,一个是get,一个是set。 这也是他活命的本钱了。 定义访问器属性同样也是使用Object.defineProperty() 进行定义的;
var people = { nickName:"Jimmy" }; Object.defineProperty(people,"name",{ configurable:true, //是否可以通过delete删除 Enumerable: true, //可以通过for...in 遍历出来 get:function(){ return this.nickName; }, set:function(value){ this.nickName = value; } })访问器属性里面的配置项里面同样有4个 items;
[[Enumerable]] :(Boolean)是否可以通过for...in 循环出来 [[Coonfigurable]] :(Boolean)是否可以通过delete关键字删除 [[get]] : (Function) 取值函数 [[set]] : (Function) 存值函数壮士,这个属性有什么卵用~ 少侠磨叽, 待我来解释. 我们通常修改访问器属性来关联相关的属性变化。 是不是又觉得脑袋蒙蒙哒~
talk is cheap , show me u code;
var Jimmy = { _year:"2015", //现在的年风 age:17, //现在的年龄 burn:"1998" //出生年份 }; Object.defineProperty(Jimmy,"year",{ get:function(){ return this._year; }, set:function(value){ this._year = value; this.age = Number(value)-Number(this.burn); //同时修改年龄的值 } }); Jimmy.year = "2016"; //不会直接修改原来的年龄的值, 通过访问器属性改变 console.log(Jimmy.age);这样做的好处就是做到了,数据的封装性比较好. 做到不让你访问到原始的数据类型.并且处理的时候可以对其他属性做对象的改变。 平常在写个人信息的时候用处还是有点滴~ 但是如果你有>2的属性想要写的话, 看见这样的语法,俺TMD 就疯了~~~ 所以js这门高级语言为了挽留我们这些残障人士,给我另外一个方法.Object.defineProperties().
这个方法的作用,和你写字面量属性是一样的。 目的就是简化你的书写. 请看栗子:
Object.defineProperties(Jimmy, { _year: { value: "2015", writable: true }, age: { value: "18" }, year: { get: function() { return this._year; }, set: function(value) { this._year = value; this.age = Number(value) - Number(this.burn); //同时修改年龄的值 } } });Object.defineProperties(para1,para2); 第一个参数就是你要添加属性的对象. 第二个参数就是你要添加的属性. 好吧,属性的内容就介绍到这里,我还想补充一点es6关于descriptor的东西. 大家肯定有所耳闻,ECMAScript 6. 这个版本是今年才出来的(不对,我已经跨年了~~是去年). 我这里不展开来讲,如果想了解的话,可以参考我的偶像 阮一峰老师 的 es6入门 . 这里我想说一下,和访问器属性相关的class 特性;
class 就是类的意思,虽然混淆了js原型继承的精华,但他简单的语法也会让你忍不住爱 上她的。 同样在类中也有descriptor属性. 来个栗子:
//html内容 <div>this is a div</div> <p>this is a p</p> class CustomHTMLElement { constructor(element) { this.element = element; } get html() { return this.element.innerHTML; //这里对ele设置存取值函数 } set html(value) { this.element.innerHTML = value; }} let c= new CustomHTMLElement(document.querySelector('div')); c.html; //返回的是 this is a div c.html = document.querySelector('p'); c.html; //返回的是 this is a p就是这么简洁,如果下次看到class的时候,可以回头来看看 set和get 属性的含义哈~
转载于:https://www.cnblogs.com/jimmyThr/p/5093539.html
相关资源:数据结构—成绩单生成器