zoukankan      html  css  js  c++  java
  • [学习es6]setter/getter探究(转)

     

    1. 背景

    在es6中,我们可以用class关键字来定义类,语法如下

    class Person {
        // 构造函数
        constructor (name) {
            // 属性初始化
            this.name = name;
        }
    
        // 成员方法
        sayName () {
            console.log(this.name);
        }
        
        // 静态方法
        static sayHi () {
            console.log("Hi~");
        }
    }

    其实本质还是基于javascript原型链机制开发的语法糖,其中,本人对setter/getter进行一番研究,发现了不少坑。

    2. 深入setter/getter

    2.1 setter/getter的调用执行时机

    class Person {
        constructor (name, age) {
            this.name = name;
            this.age = age;
        }
        set name (name) {
            console.log("setter");
            this.name = name;
        }
        get name () {
            console.log("getter");
            return this.name;
        }
    }
    
    var p = new Person("zhang", 25);

    很快,我们就会发现代码报错了

    setter-getter.png

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

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

    class Person {
        constructor (name, age) {
            this.name = name;
            this.age = age;
        }
        set name (name) {
            console.log("setter");
            this._name = name;
        }
        get name () {
            console.log("getter");
            return this._name;
        }
    
        // 加一个成员方法
        sayName () {
            console.log(this.name);
        }
    }
    
    var p = new Person("zhang", 25); 
    p.sayName();

    执行结果为

    图片描述

    到这里就可以明白了,原来只要this.name中的属性名和set name/get name后面的name一致,对this.name就会调用setter/getter,也就是说setter/getter是hook函数,而真实的存储变量是_name,我们可以在代码中直接获取它。

    class Person {
        constructor (name, age) {
            this.name = name;
            this.age = age;
        }
        set name (name) {
            console.log("setter");
            this._name = name;
        }
        get name () {
            console.log("getter");
            return this._name;
        }
    
        // 加一个成员方法
        sayName () {
            console.log(this.name);
        }
    }
    
    var p = new Person("zhang", 25); 
    console.log(p._name); // "zhang"

    执行结果为

    图片描述

    注意到结果并没有执行getter,因为我们直接访问了p._name,而不是p.name

    2.2 只有getter定义只读属性

    当一个属性只有getter没有setter的时候,我们是无法进行赋值操作的(第一次初始化也不行),这一点也是相当地。例如

    class Person {
        constructor (name) {
            this.name = name;
        }
        // 只有getter
        get name () {
            console.log("getter");
            return this.name;
        }
    }
    
    var p = new Person("zhang");

    执行结果为

    图片描述

    当没有getter和setter时,就可以正常读写属性

    原文:https://segmentfault.com/a/1190000007356931

  • 相关阅读:
    架构设计
    第七章
    第六章
    第五章
    第四章
    第三章
    第二章
    第一章
    链表中环
    实现链表中的部分翻转
  • 原文地址:https://www.cnblogs.com/yaolei0422/p/12295524.html
Copyright © 2011-2022 走看看