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

  • 相关阅读:
    .net4.5使用async和await异步编程实例
    并行开发系列 Plinq等
    改善C#程序的建议9:使用Task代替ThreadPool和Thread
    C# Task 用法
    Task
    C#委托的介绍(delegate、Action、Func、predicate)(转)
    ACTION与FUNC
    C#二叉树简易实例
    一些简单的算法
    教你如何写thinkphp多表查询语句
  • 原文地址:https://www.cnblogs.com/yaolei0422/p/12295524.html
Copyright © 2011-2022 走看看