zoukankan      html  css  js  c++  java
  • 学习es6 setter/getter研究

    1.背景

       在ES6中,我们对类的定义如下

     1 class Person {
     2     // 构造函数
     3     constructor (name) {
     4         // 属性初始化
     5         this.name = name;
     6     }
     7 
     8     // 成员方法
     9     sayName () {
    10         console.log(this.name);
    11     }
    12     
    13     // 静态方法
    14     static sayHi () {
    15         console.log("Hi~");
    16     }
    17 }

      其实本质还是基于javascript原型链机制开发的语法糖

    2. 深入setter/getter

    2.1 setter/getter的调用执行时机

     1 class Person {
     2     constructor(name,age) {
     3         this.name = name;
     4         this.age = age;
     5     }
     6                 
     7     set name(name) {
     8         console.log("setter");
     9         this.name = name;
    10     }
    11                 
    12     get name() {
    13         console.log("getter");
    14         return this.name;
    15     }
    16 }    

     发现上面的代码报错

    /**
    *   这是因为,在构造函数中执行this.name=name的时候,就会去调用set name,
    *   在set name方法中,我们又执行this.name = name,进行无限递归,
    *   最后导致栈溢出(RangeError)。
    * */

    我们稍作修改,让这个代码可以正常执行,达到我们想要的效果。

     1 // 针对上面的情况,稍作修改
     2 class Person {
     3     constructor(name,age) {
     4         this.name = name;// 执行这里 --- 1
     5         this.age = age;
     6     }
     7                 
     8     set name(name) { // 进入到这里进行设置  -- 2
     9         console.log("setter");
    10         this._name = name;
    11     }
    12                 
    13     get name() { // 在这里将对应的值返回 --- 3
    14         console.log("getter");
    15         return this._name;
    16     }
    17                 
    18     sayName() { // 这里的调用,又从 1-2-3
    19         console.log(this.name);
    20     }
    21 }
    22 let p2 = new Person("lisi",22);
    23 console.log(p2);// 真实的属性是 age  _name   而不是name
    24 p2.sayName();
    25 console.log(p2._name);// 如果你访问的是 p2.name  最后会执行 1-3 这两个步骤,会打印出getter    

    控制台结果如下: 

    /**
    * 总结
    *    只要this.+属性名 和get 属性名/ set 属性名 中,属性名一致,
    *    this.name 会去调用getter 和 setter ,也就是说 getter和setter是hock函数
    *    而真实存储的属性是 _name 我们可以在实例化后,直接获取
    * */

    2.2 只有getter定义只读属性

     1 // 只有getter定义只读属性
     2 class foo {
     3     constructor(name) {
     4         this.name = name;
     5     }
     6                  
     7     get name() {
     8         console.log(`getter函数`);
     9         return this.name;
    10     }
    11 }
    12 //Cannot set property name of #<foo> which has only a getter
    13  let p3 = new foo("李四");

    /**
    * 总结:
    *   当一个属性只有getter没有setter的时候,我们是无法进行赋值操作的(第一次初始化也不行),这一点需要注意
    *   当没有getter和setter时,就可以正常读写属性
    * */

  • 相关阅读:
    .NET牛人应该知道些什么
    秋梦
    感谢你走进我的生命里
    漂流有感
    QQ在跳舞
    青春无痕
    名人只是传说,你我才是传奇
    祝福紫秋
    可以用在任何人身上:百战百胜人生10大成功秘诀
    c#发送邮件
  • 原文地址:https://www.cnblogs.com/xiaqilin/p/8503079.html
Copyright © 2011-2022 走看看