javascript 面向对象系列更新:
Javascript面向对象编程之工厂模式、构造函数和ES6的class类
JavaScript 面向对象之Object的getter和setter的使用
更多不定期更新中

JavaScript巧用Object的get和set方法实现js变量的动态监听

咳咳,现在开始打起精神了哈!

  • 话说怎么突然想起写这个了呢?事情是这样的,且听小编给你慢慢道来
  • 前段时间VUE写的有些累了,想换换脑子,就开始学一个js写后端的程序,没有demo,自己瞎玩,玩着玩着就到了从浏览器访问静态页面的环节,一切顺利
  • 但是,我这页面有个按钮:<button onclick="plus()">+</button>,可以实现对下面的数字做+1操作,这一个“+”就导致我的一个变量发生了改变!变成什么了呢?我想实时都知道,用惯了vue的我就想啊,js有没有vue.$watch那样的数据监听呢?

有事找度娘!走一波

  1. switch死循环监听:目的达到了,但性能完全没有了,pass掉
    function applyA(val){
        a = val;
        switch(val){
            case 1: test1(); break;
            case 2: test2(); break;
        }
    }
  1. jQ的fire函数,一开始都没打算学jQ的我,还是放弃吧(也是用的switch+回调)
  2. setInterval 定时去检查该变量的值是否被改变(比死循环好点,但也好不到哪去,pass掉)
  3. 无限多的水贴水回复,简直无力吐槽-_-!,谷歌被墙,还是靠自己吧

第一步:看W3C中JavaScript那一块有没有提到

  • 大多都是比较容易理解的,js各个Dom对象,BoM对象都是几句带过。。。

第二部:查JavaScript标准

  • ES5基本都很熟了,貌似没有吧,直奔ES6
  • 看到对象的get和set方法时,突然想起来Vuex中的getter和setter就是可控的改变和读取变量,果断认真看起来
  • 将需要监听的值放在一个对象中,通过get方法调用,通过set方法改变值,安全又可靠!!!
  • 有戏… …

初步实践

谷歌控制台测试get和set方法,一切顺利

    var c = {
        w: 111,
        get ws(){
            console.log('取值',this.w);
            return this.w;
        },
        set ws(val){
            console.log('存值', this.w , 'val' + val);
            this.w = val;
            console.log('存过后的w',this.w);
        }
    }
    console.log(c)
    // {w: 111}
    // w: 111
    // ws: 111
    // get ws: ƒ ws()
    // set ws: ƒ ws(val)
    // __proto__: Object
    console.log('原生值:',c.w);
    // 111
    console.log('get方法取值:',c.ws);
    // 取值 111
    // 111
    console.log('set方法存值:',c.ws = 222);
    // 存值 111 val222
    // 存过后的w 222
    // 222
    console.log('验证存取:',c.w,c.ws);
    // 取值 222
    // 222 222

用到我的demo中:

    # index.html
    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>index</title>
        <link rel="stylesheet" href="./css/d02.css">
    </head>

    <body>
        <div>
            <h2>只能用index做首页吗???!!!</h2>
            <a href="./d02_index.html">链接到d02</a><br>
            <button onclick="plus()">&nbsp; + &nbsp;</button>
            <p id="p">0</p>
        </div>
    </body>
    <script type='text/javascript' src='./js/d02.js'></script>
    <script type='text/javascript'>
        function plus() {
            watchVal.val = ++watchVal.value;
            let screen = document.getElementById('p');
            screen.innerHTML = watchVal.value;
            console.log(watchVal.value)
        }
    </script>

    </html>

    # d02.js
    var watchVal = {
        value: 0,
        get val() {
            console.log('取值', this.value);
            return this.value;
        },
        set val(vals) {
            this.value = vals;
            console.log('存过后的值', this.value);
        }
    }

测试效果:

点击页面的 “+”,p标签显示数值+1,控制台打印:存过后的值 1
大功告成,现在你就可以在watchVal对象中的set方法里写任意你想要的监听回调函数了,简单又安全

最后,通过js变量监听实现页面数据共享

  • 目标:index页面和test页面各有一个“+”按钮和显示当前变量值的p标签,通过点击按钮使p标签的值改变,切换页面后,p的值还是最后的值,可继续增加
  • 思路:首先把p标签的值保存在一个对象变量中,通过对象的set和get方法来存储值得改变和读取新的值,监听每次值发生改变时,都往localStorage中存一次,页面初始化时,初始p标签的值为localStorage中存的值即可
  • 代码如下:(示例很简单,但我学到了东西,那么,聪明的你你学会了吗)
    // index.html
    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>index</title>
        <link rel="stylesheet" href="./css/d02.css">
    </head>

    <body>
        <div>
            <h2>只能用index做首页吗???!!!</h2>
            <a href="./test.html">链接到test</a><br>
            <button onclick="plus()">&nbsp; + &nbsp;</button>
            <p id="p">0</p>
        </div>
    </body>
    <script type='text/javascript' src='./js/d02.js'></script>
    <script type='text/javascript'>
        window.onload = function () {
            let screen = document.getElementById('p');
            screen.innerHTML = watchVal.value;
        }
        function plus() {
            watchVal.val = ++watchVal.value;
            let screen = document.getElementById('p');
            screen.innerHTML = watchVal.value;
            console.log(watchVal.value)
            storage();
        }
    </script>
    </html>

// test.html

    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>test</title>
        <link rel="stylesheet" href="./css/d02.css">
    </head>

    <body>
        <div>
            <h2>这是test的内容</h2>
            <button onclick="plus()"> + </button>
            <p id="p">0</p>
        </div>
    </body>
    <script type='text/javascript' src='./js/d02.js'></script>
    <script type='text/javascript'>
        window.onload = function () {
            let screen = document.getElementById('p');
            screen.innerHTML = watchVal.value;
        }
        function plus() {
            watchVal.val = ++watchVal.value;
            let screen = document.getElementById('p');
            screen.innerHTML = watchVal.value;
            console.log(watchVal.value);
            storage();
        }
    </script>
    </html>

// d02.js

    var stor = window.localStorage;
    var item = stor.getItem('wv');

    // 监听value的动态变化
    var watchVal = {
        value: item > 0 ? item : 0,
        get val() {
            console.log('取值', this.value);
            return this.value;
        },
        set val(vals) {
            this.value = vals;
            console.log('存过后的值', this.value);
        }
    }

    // 存储到本地
    function storage() {
        let localStorage = window.localStorage;
        localStorage.setItem('wv',watchVal.value);
    }
Logo

前往低代码交流专区

更多推荐