• 【学习笔记70】数据劫持


    一、 数据驱动视图

    • 多次渲染页面,多的时候,比较麻烦和繁琐
    1. const box = document.querySelector('.box')
    2. const obj = {
    3. name: 'QF666',
    4. age: 18
    5. }
    6. box.innerHTML = `名字: ${obj.name}; 年龄: ${obj.age}`;
    7. obj.age = 99;
    8. box.innerHTML = `名字: ${obj.name}; 年龄: ${obj.age}`;
    9. obj.name = 'QF999';
    10. box.innerHTML = `名字: ${obj.name}; 年龄: ${obj.age}`;
    11. console.log(obj);

    二、数据劫持

    • 将原始数据,劫持出一份一摸一样, 听起来有点像浅拷贝
    • 劫持出来的数据, 默认是不可以修改的
    1. 语法: Object.defineProperty(那个对象, '对象的key', {配置项})
    2. 配置项:
    3. 1. value     访问这个值 之后, 得到结果
    4. 2. writable     决定当前这个属性能否被修改, 默认是 false
    5. 3. enumerable   决定当前这个属性能否被枚举, 决定当前这个属性能否被遍历到
    6. 4. getter   是一个函数, 是一个获取器, 当访问这个属性时, 会执行这个函数
    7.   getter不能和value、writable一起使用
    8. 5. setter   是一个函数, 是一个设置器, 当设置这个属性是, 会执行这个函数

    1、初级版 

    1. const obj = {}
    2. obj.name = 'QF666'
    3. console.log(obj)
    4. // Object.defineProperty(obj, str, {配置项})
    5. Object.defineProperty(obj, 'age', {
    6. // value: 'QF999',
    7. // writable: true,
    8. enumerable: true,
    9. get() {
    10. // console.log('你当前访问了这个age属性, 触发了get函数')
    11. return 'qwerty'
    12. },
    13. set(val) {
    14. console.log('你当前想要修改这个age属性, 修改的值是: ', val)
    15. }
    16. })
    17. obj.age = 999
    18. console.log(obj.age)

    2、升级版

    1. "box">
    2. <script>
    3. // 实现数据劫持
    4. const box = document.querySelector('#box')
    5. const obj = {
    6. name: 'QF666',
    7. age: 18
    8. }
    9. console.log('原始对象obj:', obj)
    10. const res = {}
    11. Object.defineProperty(res, 'name', {
    12. get() {
    13. return obj.name
    14. },
    15. set(val) {
    16. // console.log('你想要修改这个属性的值, 新值为: ', val)
    17. obj.name = val
    18. box.innerHTML = `名字: ${res.name}; 年龄: ${res.age}`
    19. }
    20. })
    21. Object.defineProperty(res, 'age', {
    22. get() {
    23. return obj.age
    24. },
    25. set(val) {
    26. // console.log('你想要修改这个属性的值, 新值为: ', val)
    27. obj.age = val
    28. box.innerHTML = `名字: ${res.name}; 年龄: ${res.age}`
    29. }
    30. })
    31. box.innerHTML = `名字: ${res.name}; 年龄: ${res.age}`
    32. res.age = 100;
    33. script>

     三、封装数据劫持

    1. <input type="text" name="" id="inp">
    2. <div id="box">div>

    函数的封装 :

    1. const box = document.querySelector('#box')
    2. const obj = {
    3. name: 'QF666',
    4. age: 18
    5. }
    6. function observer(origin, callback) {
    7. const target = {}
    8. for (let k in origin) {
    9. Object.defineProperty(target, k, {
    10. get() {
    11. return origin[k]
    12. },
    13. set(val) {
    14. // console.log('你现在想要修改的key是' , k, '修改的值为', val)
    15. origin[k] = val
    16. callback(target)
    17. }
    18. })
    19. }
    20. callback(target)
    21. return target
    22. }

    调用的 

    1. function fn(res) {
    2. box.innerHTML = `名字: ${res.name}; 年龄: ${res.age}`
    3. }
    4. const app = observer(obj, fn)
    5. document.querySelector('#inp').oninput = function (e) {
    6. app.age = e.target.value
    7. }

    四、封装数据劫持+渲染

    • 模拟一个其他人写的代码, 框架的源码
    • 把需要渲染的代码, 都放到HTML 中, 然后由我这段代码帮助我们去渲染
    1. "app">
    2. <h1> {{msg}} h1>
    3. <h1> {{ name }} h1>
    4. <h1> {{ age }} h1>
    5. <h1> {{ abc }} h1>
  • 封装的

    调用的

     五、数据劫持升级

        <div id="root">div>

    1、基本写法

    1. const obj = {
    2. name: 'QF001',
    3. age: 18
    4. }
    5. const res = {}
    6. Object.defineProperty(res, 'name', {
    7. get() {
    8. return obj.name;
    9. },
    10. set(val) {
    11. obj.name = val;
    12. }
    13. })
    14. obj.newName = 'QF999';
    15. console.log(obj);
    16. document.querySelector('#root').innerHTML = `name: ${obj.name}`;

    2、升级版

    语法: Object.defineProperties(到那个对象, {

            属性1: 配置项,

            属性2: 配置项

      })

    1. const obj = {
    2. name: 'QF001',
    3. age: 18
    4. }
    5. const res = {}
    6. Object.defineProperties(res, {
    7. name: {
    8. get() {
    9. return obj.name
    10. },
    11. set(val) {
    12. obj.name = val
    13. }
    14. },
    15. age: {
    16. get() {
    17. return obj.age
    18. },
    19. set(val) {
    20. obj.age = val
    21. }
    22. }
    23. })
    24. obj.newName = 'QF999';
    25. console.log(obj);
    26. document.querySelector('#root').innerHTML = `name: ${obj.name}`;

    3、升级版(plus) 

    1. const obj = {
    2. name: 'QF001',
    3. age: 18
    4. }
    5. const res = {};
    6. // 升级版(plus)
    7. for (let k in obj) {
    8. // k === 'name' 2. k === age
    9. console.log(k);
    10. Object.defineProperties(res, {
    11. // 对象内部直接写 k 会帮当成字符串, 所以可以写成 [k], 将他识别为变量
    12. [k]: {
    13. get() {
    14. return obj[k];
    15. },
    16. set(val) {
    17. obj[k] = val;
    18. }
    19. },
    20. })
    21. }
    22. obj.newName = 'QF999';
    23. console.log(obj);
    24. document.querySelector('#root').innerHTML = `name: ${obj.name}`;

    3、升级版(super plus),   自己劫持自己

    1. const obj = {
    2. name: 'QF001',
    3. age: 18
    4. }
    5. for (let k in obj) {
    6. Object.defineProperties(obj, {
    7. ['_' + k]: {
    8. // 我在我这个对象内把所有属性复制一份, 放在自己这个对象内部
    9. value: obj[k],
    10. writable: true
    11. },
    12. [k]: {
    13. get () {
    14. return obj['_' + k]
    15. },
    16. set(val) {
    17. obj['_' + k] = val
    18. document.querySelector('#root').innerHTML = `name: ${obj.name}`
    19. }
    20. }
    21. })
    22. }
    23. obj.newName = 'QF999'
    24. console.log(obj)
    25. document.querySelector('#root').innerHTML = `name: ${obj.name}`

  • 相关阅读:
    [Linux]什么是Linux根社区
    第4周学习:MobileNetV1, V2, V3
    HTTP复习(二)
    Aspose.Words for .NET样式处理教程——如何插入和使用目录字段
    所有 Windows 用户请注意:该高危零日漏洞已被利用 7 周
    面向大规模队列,百万并发的多优先级消费系统设计
    -骑士巡游-
    关于Nacos启动报错 Unable to start embedded Tomcat
    Springboot属性注入
    kubenates的傻瓜式部署教程(K8S部署教程)
  • 原文地址:https://blog.csdn.net/m0_58190023/article/details/128055507