Vue08-数据代理

一、Object.defineProperty()

Object.defineProperty() 是 JavaScript 中的一个方法,用于直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。

这个方法允许你精确地控制一个对象的属性,包括它的值、是否可写、是否可枚举以及是否可配置。

Object.defineProperty() 方法接受三个参数:

  1. obj:要定义属性的对象。
  2. propertyName:要定义或修改的属性的名称或 Symbol。
  3. descriptor:这个属性的描述符。

descriptor 对象可以具有以下属性:

  • value:属性的值。
  • writable:如果为 true,属性的值可以被重写。默认为 false
  • enumerable:如果为 true,则属性会被枚举(例如,通过 for...in 循环或 Object.keys())。默认为 false
  • configurable:如果为 true,则属性的类型可以被改变,并且属性可以从对应的对象上被删除。默认为 false
  • get:一个函数,当访问该属性时,该函数会被调用,并返回有效的值。
  • set:一个函数,当修改该属性时,该函数会被调用,使用传入的新值作为唯一的参数。

注意:

你不能同时在一个描述符中设置 value 或 writable 与 get 或 set,因为这会导致错误。

        let obj = {};  
  
        Object.defineProperty(obj, 'example', {  
            value: 'Hello',  
            writable: false,  
            enumerable: true,  
            configurable: true  
        });  
            
        console.log(obj.example); // 输出 "Hello"  
        console.log(obj);
            
        // 尝试修改属性会失败,因为它是不可写的  writable: false,  
        obj.example = 'World';  
        console.log(obj.example); // 仍然输出 "Hello" 

二、Object.keys()函数

Object.keys() 是 JavaScript 中的一个内置方法,它返回一个表示给定对象所有可枚举属性的字符串数组。

(其枚举顺序与使用 for...in 循环的顺序相同,两者的主要区别是 for-in 循环还会枚举原型链中的属性)。

const person = {  
    firstName: 'John',  
    lastName: 'Doe',  
    age: 50,  
    eyeColor: 'blue'  
};  
  
const keys = Object.keys(person);  
  
console.log(keys);  
// 输出: ['firstName', 'lastName', 'age', 'eyeColor']

注意事项

  1. 1、原型链Object.keys() 方法只返回对象本身的属性(不包括继承自原型的属性)。

  2. 2、可枚举性:如果属性不可枚举(即它们的 enumerable 属性被设置为 false),那么 Object.keys()不会返回这些属性。

  3. 3、数组和对象:虽然 Object.keys() 主要用于对象,但它也可以用于数组,因为数组在 JavaScript 中也是对象。但是,对于数组,它返回的是索引(作为字符串),而不是值。

  4. const arr = ['a', 'b', 'c'];  
    console.log(Object.keys(arr)); // 输出: ['0', '1', '2']

    4、null 和 undefined:如果尝试在 null 或 undefined 上使用 Object.keys(),将会抛出一个错误。

三、使用Object.defineProperty()的好处

3-1、控制属性是否可枚举

颜色不一样了,意味着:这个属性不可枚举。

3-2、控制属性是否可以被修改

3-3、控制属性是否可以被删除

3-4、小结

3-5、getter属性

3-6、setter属性

3-7、小结

四、数据代理

通过obj2,读取、修改obj的x属性。

五、Vue中的数据代理

5-1、ES6:属性名简写(Property Shorthand)的语法 

这种语法允许你直接使用变量名作为对象的属性名,并且如果该变量名与属性名相同,则可以省略冒号和值。

let data = {  
    name: 'milk',  
    address: 'thailand'  
}  
const vm = new Vue({  
    el: '#root',  
    data: data  
})

这是传统的 JavaScript 对象字面量写法,其中 data: data 明确地将变量 data 的值赋给了对象属性 data

但是,使用 ES6 的属性名简写语法,你可以直接写成:

const vm = new Vue({  
    el: '#root',  
    data  
})

这里,data 变量被用作对象的属性名,并且由于属性名和变量名相同,所以 JavaScript 解释器会自动将 data 变量的值赋给该属性。这种写法更为简洁,并且在变量名和属性名一致时很常见。

注意:属性名简写语法只能在变量名和属性名相同时使用,并且不能用于函数、计算属性。因为这些属性在对象字面量中需要显式地定义其值和类型(函数或计算属性)。

1、函数属性

如果你有一个方法(函数),你不能直接使用属性名简写语法。你需要显式地写出属性名和函数体

// 错误的简写方式(会导致语法错误)  
const vm = new Vue({  
    el: '#root',  
    methods: myMethod // 错误!应该是一个对象,且包含属性名和方法体  
});  
  
// 正确的写法  
const vm = new Vue({  
    el: '#root',  
    methods: {  
        myMethod() {  
            // 方法体  
        }  
    }  
});

2、计算属性

类似地,计算属性也需要显式地写出属性名和计算逻辑

// 错误的简写方式(会导致语法错误)  
const vm = new Vue({  
    el: '#root',  
    computed: myComputedProperty // 错误!应该是一个对象,且包含属性名和计算逻辑  
});  
  
// 正确的写法  
const vm = new Vue({  
    el: '#root',  
    computed: {  
        myComputedProperty() {  
            // 计算逻辑  
            return someValue;  
        }  
    }  
});

3、小结

属性名简写语法仅适用于那些属性名和变量名完全相同的场景,并且该变量是一个简单值(如数字、字符串、布尔值、对象或数组,但对象或数组内的属性或元素需要显式定义)。

对于函数计算属性或其他需要特殊处理的属性,你需要使用传统的 属性名: 值 语法来定义它们。 

5-2、证明setter

vm将data属性,放置在_data属性中。

vm身上,以及Vue的原型所有的属性和方法,在模版里面都能直接用!

这两条线的数据代理,实现的方法:Object.defineProperty。

5-3、小结

数据劫持的目的:

只要修改vue中data中的name,哪个页面中用到name的地方,都会修改。为了实现此功能,要让vue检测到data中的name发生了改变。——数据劫持 

  • 24
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值