zoukankan      html  css  js  c++  java
  • vue--响应式原理(2)

    在谈 Vue 响应式原理之前,我们需要先了解一下 ES5 的 Object 的一个属性 defineProperty。
    下面我们来看一段官方的介绍
    The Object.defineProperty() method defines a new property directly on an object, or modifies an existing property on an object, and returns the object.
    直接在一个对象上定义一个新的属性,或修改一个已经存在的属性。这个方法会返回该对象。
    语法:
    Object.defineProperty(obj, prop, descriptor)
    参数说明:
    @params obj // 目标对象 type: Obejct @params prop // 需要定义的属性 type: String @params descriptor // 定义的属性所拥有的特性 type: Obejct
    通过简单的介绍可以看看到,也就是定义了个对象的某个属性,但是其中的奥秘主要在第三个参数 descriptor。 我们看一下第三个参数可以设置的属性:
    • value
    • writable
    • get ,set
    • configurable
    • enumerable
    分别介绍一下每个属性:
     
    1. value
    属性的值, 默认为undefined。例如:
    var someOne = {}
    Object.defineProperty(someOne, 'name', {
        value : 'cover'
    })
    someOne.name // cover
    从表面上看, 貌似和下面的语法是等价的:
    someOne.name = 'cover'
    那我们继续往下看接下来的属性。
     
    2. writable
    该属性是否可写, 如果设置成 false,则任何对该属性改写的操作都无效(但不会报错),默认为 false。
    var someOne = { };
    Object.defineProperty(someOne, "name", {
        value:"coverguo" , // 由于设定了writable属性为false 导致这个量不可以修改
        writable: false 
    });  
    console.log(someOne.name); // 输出 coverguo
    someOne.name = "monkeyWang";
    console.log(someOne.name); // 输出coverguo
     
    3. configurable
    如果为 false,则任何尝试删除目标属性或修改属性以下特性(writable, configurable, enumerable)的行为将被无效化,默认为 false。
    var someOne = { };
    Object.defineProperty(someOne, "name", {
        configurable: false, // 由于设定了configurable属性为false导致所有属性不可修改
        value: "hello"
    });  
    // 下面的操作想让 configurable 变为 true 但是不会被允许
    Object.defineProperty(someOne, "name", {
        configurable: true,
        value: "hello"
    });  // Cannot redefine property: name
    
    
    var someOne = { };
    Object.defineProperty(someOne, "name", {
       configurable: true, // 由于设定了configurable属性为false导致所有属性不可修改
        value: "hello"
    });  
    // 下面的操作想让 configurable 变为 false 是可以的
    Object.defineProperty(someOne, "name", {
       configurable: false,
        value: "hello"
    });  
     
    4. enumerable
    是否能在for...in循环中遍历出来或在Object.keys中列举出来。默认为 false。
    var someOne = {}
    Object.defineProperty(someOne,"name",{
      value:3445,
      enumerable:true
    })
    console.log(Object.keys(someOne));// 打印["name"]

    改为false

    var someOne = {}
    Object.defineProperty(someOne,"name",{
      value:3445,
      enumerable:false //注意咯这里改了
    })
    console.log(Object.keys(someOne));// 打印[]
    for...in 类似,不赘述了。
    接下来看看更加关键的几个属性:set 和 get
     
    5. set 和 get
    在 descriptor 中不能同时设置访问器(get 和 set)和 wriable 或 value,否则会错,就是说想用 get 和 set,就不能用 writable 或 value 中的任何一个。
    set 和 get,他俩干啥用的的。
    var someOne= {}
    Object.defineProperty(someOne,"name",{
        set: function (newValue) {
          console.log('你设置了name,新的值是' + newValue);
        },
        get: function (value) {
          console.log('你访问了name');
        }
    })
    someOne.name = 'monkeyWang'// 你设置了name,新值是monkeyWang
    console.log(someOne.name)    // 你访问了name
    简单来说,这个 “b” 赋值或者取值的时候会分别触发 set 和 get 对应的函数。
     
    演习:
    了解了上面这么多,那我们便可以开始 Vue 的基本响应式之旅了:我们从最简单的开始。其中,动态数据绑定就是 Vue 最为基础,最为有用的一个功能。这个系列将分成5部分,一步一步来理解和实现这一功能。ok,我们从最简单的开始。给定任意一个对象,如何监听其属性的读取与变化?也就是说,如何知道程序访问了对象的哪个属性,又改变了哪个属性?
    let app1 = new Observer({
      name: 'youngwind',
      age: 25
    });
    
    let app2 = new Observer({
      university: 'bupt',
      major: 'computer'
    });
    
    // 要实现的结果如下:
    app1.data.name // 你访问了 name
    app.data.age = 100;  // 你设置了 age,新的值为100
    app2.data.university // 你访问了 university
    app2.data.major = 'science'  // 你设置了 major,新的值为 science 
    感兴趣的小伙伴可以动手去实现这样一个简单的数据绑定。
     
    如果传入参数对象是一个“比较深”的对象(也就是其属性值也可能是对象),那该怎么办呢?考虑传递回调函数。
    在实际应用中,当特定数据发生改变的时候,我们是希望做一些特定的事情的,而不是每一次都只能打印出一些信息。所以,我们如何支持传入回调函数的功能?
     

  • 相关阅读:
    Python2 和 Python3的区别 更新中
    CentOS下图形界面安装_Orcaale 11g
    Nmap_使用介绍
    shell_innobackup增量备份步骤
    shell_跳板机推送公钥
    shell_clean_log
    shell_xtrabackup_backup_mysql
    gitlab免密登录
    gitlab安装与部署
    git合并分支
  • 原文地址:https://www.cnblogs.com/absoluteli/p/14082463.html
Copyright © 2011-2022 走看看