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">
        <meta charset="UTF-8">
        <title>index</title>
        <link rel="stylesheet" href="./css/d02.css">
    </head>
            <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">
        <meta charset="UTF-8">
        <title>index</title>
        <link rel="stylesheet" href="./css/d02.css">
    </head>
            <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">
        <meta charset="UTF-8">
        <title>test</title>
        <link rel="stylesheet" href="./css/d02.css">
    </head>
            <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);
使用源代码安装
 $ git clone https://github.com/wxqee/get-set-var.git get-set-var
$ cd get-set-var/
$ npm install ./ -g
选择使用 db/database
 设置 env GSV_DB_NAME可以帮助识别即将使用的数据库。 
 $ export GSV_DB_NAME=<db>
初始化一个数据库/db 
 $ get-set-var-init
获取并设置一个 var 
 $ get-set-var <variable>
$ get-set-var <variable> <value>
                                    JavaScript是一种流行的编程语言,用于Web开发和创建交互式Web应用程序。在JavaScript中,可以使用事件监听器来捕捉变量的变化,并在变量改变时执行相应的操作。本文将介绍如何使用JavaScript监听变量的变化,以及如何使用事件监听器来触发相应的操作。
<span v-once>这个将不会改变: {{ msg }}</span>
2. HTML
双大括号会将数据解释为普通文本,而非 HTML 代码。为了输出真正的 HTML,你需要...
  value: 4,
  writable: true, // 是否可以修改属性的值
  configurable: true, // 配置项是否可以修改,就是说writable和enumerable是否能够修改
  enumerable: true, // 是否可以枚举,就是说在遍历
                                    对象原型的toString方法,以及数组的length属性都是不可枚举的。
对象的每个属性都有一个描述对象(Descriptor),用来控制该属性的行为。Object.getOwnPropertyDescriptor方法可以获取该属性的描述对象。
let obj = { foo: 123 };
Object.getOwnPropertyDescriptor(obj, 'foo')
//  {
//    value: 123,
//    writable: true,
//    enumerable: 
                                    5.map和set都是stl中的关联容器,map以键值对的形式存储,key=value组成pair,是一组映射关系。set只有值,可以认为只有一个数据,并且set中元素不可以重复且自动排序。Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。4.Set的值是唯一的可以做数组去重,Map由于没有格式限制,可以做数据存储。2.Map可以通过get方法获取值,而set不能因为它只有值;1.Map是键值对,Set是值的。,无论是原始值或者是对象引用。
                                    目录代码示例效果查看
自定义getUsername()和setUsername()方法,get方法用于对外提供数据查询,set方法是对外提供数据修改通道。
<script type="text/javascript">
     *  模块get方法set方法定义
    var module = (function () {
        //对象定义
        var userObj = {
            username:"lu