HTML5学习笔记(十七):访问器和class关键字

访问器

在ECMAScript5中,提供了Object.defineProperty的方法,我们可以通过该方法来控制属性的更多权限。

属性类型

我们先看一段定义属性的代码:

1 var person = {
2     name:"Li Lei"
3 };
4 console.log(person.name);

我们为person定义了一个名为name的属性,这是最简单的设定,那么当我希望这个属性是一个只读属性,或者该属性不会在for in循环中被遍历该怎么办呢,这就要用到Object.defineProperty方法了。

我们先认识一下该方法可以控制的属性类型有哪些:

  • configurable:该属性是否可以通过delete关键字删除,默认为false。
  • enumerable:该属性是否在for in循环中出现,默认值为false。
  • writable:该属性是否可写,默认值为false。
  • value:属性的默认值,默认值为undefined。

或者

  • configurable:同上
  • enumerable:同上
  • set:写入属性时调用的函数,只设定该方法时为只写。
  • get:读取属性时调用的函数,只设定该方法时为只读。

需要注意的是,直接定义在对象上的属性,configurable、enumerable和writable都是true。

这里的Writable、Value和Set、Get是不应该同时出现的,所以分为了两组。

示例

我们先看第一种搭配:

 1 var person = {};
 2 
 3 // 默认是只读、不可删除且不能被 for in 遍历的属性
 4 Object.defineProperty(person, "color", {
 5     value: "yellow"
 6 });
 7 
 8 person.color = "black";
 9 console.log(person.color); // yellow
10 delete person.color;
11 console.log(person.color); // yellow
12 
13 // 定义为可读写的属性
14 Object.defineProperty(person, "sex", {
15     writable: true,
16     value: "male"
17 });
18 
19 person.sex = "female";
20 console.log(person.sex); // female
21 
22 // 定义为可删除属性
23 Object.defineProperty(person, "name", {
24     configurable: true,
25     value: "Li Lei"
26 });
27 
28 delete person.name;
29 console.log(person.name); // undefined
30 
31 // 定义为会被 for in 枚举属性
32 Object.defineProperty(person, "age", {
33     enumerable: true,
34     value: 28
35 });
36 
37 for(var k in person) {
38     console.log(k); // age
39 }

我们再看下一种:

 1 var person = {
 2     _birthday:0,
 3     _age:0
 4 };
 5 
 6 Object.defineProperty(person, "birthday", {
 7     set:function(value) {
 8         this._birthday = value;
 9         this._age = 2017 - this._birthday;
10     },
11     get:function() {
12         return this._birthday;
13     }
14 });
15 
16 Object.defineProperty(person, "age", {
17     get:function() {
18         return this._age;
19     }
20 });
21 
22 person.birthday = 1989;
23 console.log(person.age); // 28

寄存器允许我们对属性执行额外的操作。

class继承

还记得上一节笔记中我们是如何实现类和继承的么?我们需要编写一些额外的代码,并且需要正确实现原型链。

那么在ECMAScript6中,提供了class、super和extends关键字,帮助我们更加方便的实现类和继承,我们来看一个示例:

 1 class Person {
 2     constructor(name) {
 3         this.name = name;
 4     }
 5 
 6     sayName() {
 7         console.log(this.name);
 8     }
 9 }
10 
11 class Student extends Person {
12     constructor(name, age) {
13         super(name);
14         this.age = age;
15     }
16 
17     sayAll() {
18         super.sayName();
19         console.log(this.age);
20     }
21 }
22 
23 var student = new Student("Li Lei", 28);
24 student.sayAll();
25 // Li Lei
26 // 28

比较一下就可以发现,class的定义包含了构造函数constructor和定义在原型对象上的函数hello()(注意没有function关键字),这样就避免了Student.prototype.sayAll = function () {...}这样分散的代码。

最后,创建一个Student对象代码和前面章节完全一样。

ES6引入的class和原有的JavaScript原型继承有什么区别呢?实际上它们没有任何区别,class的作用就是让JavaScript引擎去实现原来需要我们自己编写的原型链代码。简而言之,用class的好处就是极大地简化了原型链代码。

你一定会问,class这么好用,能不能现在就用上?

现在用还早了点,因为不是所有的主流浏览器都支持ES6的class。如果一定要现在就用上,就需要一个工具把class代码转换为传统的prototype代码,可以试试Babel这个工具。

原文地址:https://www.cnblogs.com/hammerc/p/6425683.html