以下语法是怎么实现的,请大家开脑洞 (更新)

本贴最后更新于 2821 天前,其中的信息可能已经时移俗易

一个在 vue 里面的例子:

<div id="demo">{{ fullName }}div> <script type="text/javascript"> var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', testName: 'ddddd' }, computed: { fullName: function () { console.log(1); return this.firstName + ' ' + this.lastName } } }) </script>

angluar 的 watch 方法监控变量,所以很好理解如果变量变化了,触发某个函数,这种语法用事件模型应该好实现

但是 vue 这个例子就有点好玩了,如果在控制台修改 vm.firstName=111,很显然 fullName 马上也修改了

但是如果我修改 vm.testName,当然 fullName 不会修改,但是我函数里放置的 console.log 也没有执行

这个就有点厉害了,也就是在 javascript 中一个函数体内有什么变量存在,都可以完全获取? 难道是靠词法分析获取的? 这个是怎么实现的呢????? @Vanessa


然后我又试验了一个:

var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', tag:1 }, computed: { fullName: function () { console.log("run") if(this.tag>0) { console.log(1) return this.firstName }else { console.log(2) return this.lastName } } } })

我在外面修改 vm.lastname,控制台是不会打印 run 的,这说明程序知道代码不会走 else,else 里的代码修改不会对 fullname 起任何变化??? 这个也太屌了吧! 怎么实现的啊!!!

  • JavaScript

    JavaScript 一种动态类型、弱类型、基于原型的直译式脚本语言,内置支持类型。它的解释器被称为 JavaScript 引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在 HTML 网页上使用,用来给 HTML 网页增加动态功能。

    729 引用 • 1278 回帖
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    267 引用 • 666 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • feix

    暗中观察

  • Vanessa via macOS

    主要使用了 Object.defineProperty 的 get 和 set 原理

    在执行 computed.fullName 的时候通过 get 收集 fullName 的依赖
    在 data 被赋值时,set 会对该收集的依赖进行 notify

    @feix

    1 回复
  • mainlove
    作者

    我就是想问 怎么收集 fullName 的依赖,依赖都是写在函数的代码块里的,难道要词法分析?

    1 回复
  • Vanessa via macOS

    没有。
    在运行时,会解析到 this.firstName 和 this.lastName
    这个时候就会触发 get 方法收集
    Object.defineProperty(target, 'firstName', {... get: () => { // 收集依赖 }})
    Object.defineProperty(target, 'lastName', {... get: () => { // 收集依赖 }})

  • Vanessa via macOS

    具体你可以看下这段源码

    Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: function reactiveGetter () { var value = getter ? getter.call(obj) : val; if (Dep.target) { dep.depend(); if (childOb) { childOb.dep.depend(); } if (Array.isArray(value)) { dependArray(value); } } return value }, set: function reactiveSetter (newVal) { var value = getter ? getter.call(obj) : val; /* eslint-disable no-self-compare */ if (newVal === value || (newVal !== newVal && value !== value)) { return } /* eslint-enable no-self-compare */ if ("development" !== 'production' && customSetter) { customSetter(); } if (setter) { setter.call(obj, newVal); } else { val = newVal; } childOb = observe(newVal); dep.notify(); } });
  • mainlove
    作者

    @88250 你用简单的语言解释下你媳妇说的

    1 回复
  • Vanessa via macOS

    我说的解析不是词法解析。是运行的时候,执行到 this.lastName 这句的时候 😄
    就触发了 get 方法,会去执行 dep.depend()

  • mainlove
    作者

    有点理解了,每次跑一个方法的时候 把 target 和它运行的参数 做动态的绑定
    估计就是这样了

  • mainlove
    作者

    也就是第一次的跑的时候 fullname 和 tag 以及 first 建立的关系(运行时建立),然后这个时候修改了 lastName,因为没有任何关系能找到,所以不会执行任何代码
    如果修改了 tag=-1,这个时候 fullname 会重新进行关系的关联,fullname 就和 lastName 有关系了

请输入回帖内容 ...

推荐标签 标签

  • 大数据

    大数据(big data)是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

    93 引用 • 113 回帖
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    53 引用 • 40 回帖 • 1 关注
  • Ruby

    Ruby 是一种开源的面向对象程序设计的服务器端脚本语言,在 20 世纪 90 年代中期由日本的松本行弘(まつもとゆきひろ/Yukihiro Matsumoto)设计并开发。在 Ruby 社区,松本也被称为马茨(Matz)。

    7 引用 • 31 回帖 • 253 关注
  • 安全

    安全永远都不是一个小问题。

    203 引用 • 818 回帖 • 1 关注
  • 一些有用的避坑指南。

    69 引用 • 93 回帖
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖
  • Caddy

    Caddy 是一款默认自动启用 HTTPS 的 HTTP/2 Web 服务器。

    12 引用 • 54 回帖 • 168 关注
  • 禅道

    禅道是一款国产的开源项目管理软件,她的核心管理思想基于敏捷方法 scrum,内置了产品管理和项目管理,同时又根据国内研发现状补充了测试管理、计划管理、发布管理、文档管理、事务管理等功能,在一个软件中就可以将软件研发中的需求、任务、bug、用例、计划、发布等要素有序的跟踪管理起来,完整地覆盖了项目管理的核心流程。

    6 引用 • 15 回帖 • 40 关注
  • V2EX

    V2EX 是创意工作者们的社区。这里目前汇聚了超过 400,000 名主要来自互联网行业、游戏行业和媒体行业的创意工作者。V2EX 希望能够成为创意工作者们的生活和事业的一部分。

    16 引用 • 236 回帖 • 277 关注
  • Log4j

    Log4j 是 Apache 开源的一款使用广泛的 Java 日志组件。

    20 引用 • 18 回帖 • 33 关注
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖 • 1 关注
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1395 回帖 • 5 关注
  • 分享

    有什么新发现就分享给大家吧!

    247 引用 • 1794 回帖
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 382 关注
  • Postman

    Postman 是一款简单好用的 HTTP API 调试工具。

    4 引用 • 3 回帖 • 1 关注
  • 强迫症

    强迫症(OCD)属于焦虑障碍的一种类型,是一组以强迫思维和强迫行为为主要临床表现的神经精神疾病,其特点为有意识的强迫和反强迫并存,一些毫无意义、甚至违背自己意愿的想法或冲动反反复复侵入患者的日常生活。

    15 引用 • 161 回帖
  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    5 引用 • 16 回帖
  • Firefox

    Mozilla Firefox 中文俗称“火狐”(正式缩写为 Fx 或 fx,非正式缩写为 FF),是一个开源的网页浏览器,使用 Gecko 排版引擎,支持多种操作系统,如 Windows、OSX 及 Linux 等。

    7 引用 • 30 回帖 • 395 关注
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖 • 1 关注
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    28 引用 • 197 回帖 • 25 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 99 关注
  • 印象笔记
    3 引用 • 16 回帖 • 1 关注
  • GitBook

    GitBook 使您的团队可以轻松编写和维护高质量的文档。 分享知识,提高团队的工作效率,让用户满意。

    3 引用 • 8 回帖
  • 叶归
    5 引用 • 16 回帖 • 8 关注
  • JVM

    JVM(Java Virtual Machine)Java 虚拟机是一个微型操作系统,有自己的硬件构架体系,还有相应的指令系统。能够识别 Java 独特的 .class 文件(字节码),能够将这些文件中的信息读取出来,使得 Java 程序只需要生成 Java 虚拟机上的字节码后就能在不同操作系统平台上进行运行。

    180 引用 • 120 回帖 • 1 关注
  • 开源中国

    开源中国是目前中国最大的开源技术社区。传播开源的理念,推广开源项目,为 IT 开发者提供了一个发现、使用、并交流开源技术的平台。目前开源中国社区已收录超过两万款开源软件。

    7 引用 • 86 回帖