zoukankan      html  css  js  c++  java
  • 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这个工具。

  • 相关阅读:
    字符串复习笔记
    构造
    网络流复习笔记
    LCT学习笔记
    省选前的数据结构训练
    在windows安装并启动测试kafka
    Scala 原生操作MySQL
    Scala基础语法
    ORACLE查出表所有的触发器及触发器详细信息
    转载二,JAVA面试题
  • 原文地址:https://www.cnblogs.com/hammerc/p/6425683.html
Copyright © 2011-2022 走看看