• 【学习笔记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}`

  • 相关阅读:
    【机器学习】集成学习:使用scikitLearn中的VotingClassifier综合多个不同模型进行软硬投票
    6.filters滤波
    apifox怎么测试API,你学会了吗?
    【算法面试必刷Java版十三】判断一个链表是否为回文结构
    python知识点
    收银系统怎么选,网页版还是安装版好?
    【leetcode】【2022/9/10】669. 修剪二叉搜索树
    Julia元组、字典、集合
    Nginx HA高可用实现记录
    mysql字段中有空格问题查询汇总-保姆级教程
  • 原文地址:https://blog.csdn.net/m0_58190023/article/details/128055507