2

属性

前几天看了一下,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 循环出来

[[Configurable]] :(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()

这个方法的作用,和你写字面量属性是一样的。 目的就是简化你的书写.
请看栗子:

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

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 属性的含义哈~


villainhr
7.8k 声望2.2k 粉丝

引用和评论

0 条评论