Object.defineProperty数据描述

6

Object.defineProperty是Vue中一个核心功能,用来实现数据劫持,对数据进行处理,转换为get和set 作用:直接在一个对象上定义一个新属性,或者修改一个对象的现…

Object.defineProperty是Vue中一个核心功能,用来实现数据劫持,对数据进行处理,转换为get和set

作用:直接在一个对象上定义一个新属性,或者修改一个对象的现有属性

语法:Object.defineProperty(obj,prop,descriptor)

参数:

obj要在其上定义属性的对象

prop要定义或修改的属性的名称

descriptor将被定义或修改的属性描述符

数据描述:

configurable 是否可以删除目标属性, 默认为false

enumerable 此属性是否可以被枚举(遍历),默认为false

value 该属性对应的值,默认为undefined

writable 属性的值是否可以被重写,默认为false

访问器描述:

getter是一种获得属性值的方法

setter是一种设置属性值的方法

可以写configurable、enumerable、

不能写value、writable

采用数据描述的方式修改数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style type="text/css">
    </style>
</head>

<body>
</body>

</html>
<script type="text/javascript">
    //使用数据的时候,对数据进行劫持(代理)
    //使用Object.defineProperty劫持属性,把属性转换成访问器的方式
    /*
        getter  获取属性触发的
        setter  设置属性触发的
     */

    let data = {
        title: 'blog'
    };

    //定义属性,也可在原有的属性上描述(添加新的属性)
    Object.defineProperty(data, 'myBlog', {
        value: 'huanggr.cn',
    })
    //改变对象的属性值
    Object.defineProperty(data, 'title', {
        value: '改变你的属性值',
        configurable: false, //该属性是否可以被删除
        //enumerable:false,  //是否可以被枚举
        writable: false //设置false,不允许重新改
    })
    //writable为false表示在外面不能够改变值
    data.title = "最后一次改变的值";
    console.log(data);

    //所谓枚举,实质上相当于遍历
    for (let attr in data) {
        console.log(attr);
    }
    //删除对象的属性
    delete data.title
    console.log(data); //configurable:false,  //该属性是否可以被删除

    //这个为数据描述,下面的一个为访问器描述
</script>

采用访问器方式修改数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style type="text/css">
    </style>
</head>

<body>

</body>

</html>
<script type="text/javascript">
    //使用数据的时候,对数据进行劫持(代理)
    //使用Object.defineProperty劫持属性,把属性转换成访问器的方式
    /*
        getter  获取属性触发的
        setter  设置属性触发的
     */

    let data = {
        title: 'blog'
    };

    //定义属性,也可在原有的属性上描述(添加新的属性)
    Object.defineProperty(data, 'myBlog', {
        value: 'huanggr.cn'
    })
    //改变对象的属性值
    let val = "新的值";
    Object.defineProperty(data, 'title', {
        //set设置之后get会再次获取,后面的   "//"   表示的就是程序执行的顺序
        get() {
            console.log('我访问数据了'); //1  //5
            return val;
        },
        //不设置新值不会触发
        set(newValue) {
            console.log('我设置了新值'); //3
            console.log(newValue); //4
            val = newValue;
        }
    })
    console.log(data.title + "-------"); //2
    data.title = "111";
    console.log(data.title); //6
</script>

模仿Vue对数据进行处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <title>Document</title>

</head>

<body>
    <div id="app">
        <button type="" id="btn">改变数据</button>
        <h2 id="title">这是标题</h2>
    </div>
</body>

</html>
<script type="text/javascript">
    var data = {
        title: "新闻",
        myBlog: 'huanggr.cn'
    };

    //
    observer(data);

    function observer(obj) {
        //Object.keys  拿到该对象上面的所有的key值
        Object.keys(obj).forEach((item) => {
            console.log(item + "======item");
            defineReactive(obj, item, obj[item])
        })
    }

    function defineReactive(obj, key, value) {
        Object.defineProperty(obj, key, {
            get() {
                return value;
            },
            set(newValue) {
                value = newValue;
                //title变化,触发set,然后赋值
                title.innerHTML = newValue;

            }
        })
    }

    console.log(data);

    title.innerHTML = data.title;

    btn.onclick = function () {
        data.title = "数据变化了";
    }
</script>

一些方法

删除对象属性

1
2
delect data.title           //删除data对象的title属性
Object.keys(data)        //获取data对象所有的下标

作者: huanggr

为您推荐

7

发表评论

电子邮件地址不会被公开。 必填项已用*标注