关于defineProperty,会被面试官问到的点

55 阅读2分钟

首先是聊到了Vue的计算属性(computed),被问到计算属性比起methods的优势在哪里?优势自然就是计算属性存在缓存,在第一次调用get计算后,该计算属性所需的源数据未改变时,就不会继续调用get,而是从缓存直接取值,该计算属性是缓存至Vue实例上的属性。而methods的话,由于是调用方法,因此每次调用都会执行并返回,性能上不如computed。但是computed也有缺点,无法实现异步数据更新,需要异步更新时应该使用methods。然后问实现的方法,就说到了 Object.defineProperty()。

Object.defineProperty(obj,name,{})

defineProperty()作用是为指定对象添加属性,第一个参数指定目标对象,第二个参数指定新属性名称,第三个参数是一个配置对象{enumerable, configurable,(value,writable)/(getter,setter) }

value指定属性值(默认undefined),writable指定数据是否可改写(默认false),enumerable配置属性是否可遍历(默认false不可遍历),configurable配置属性是否可移除(默认false不可移除),当存在get()方法和set()方法时,writable属性和value都不可以声明,即使指定为false和undefined也不可以。

当存在get()和set()方法时,每当对象的该属性被访问时会自动调用get()方法去拿返回值,这也是Vue计算属性使用的方法,vue实现数据的双向绑定也用到这个。同理set()方法可以用来设定该属性的值。

有这样一种一种情况,当你通过defineProperty定义的属性在目标对象上已经存在了,会怎么处理这次操作?
此时配置中的configurable就会发生作用,如果配置为true,则可以对该属性进行更新修改,否则认为该属性是不可配置的,强行修改会报错。但是有一个例外,即使configurable为false时,有一个配置项可以进行单向更改:writable可以从true更改为false。

    const address = "china shaanxi"
    Object.defineProperty(obj,"home",{
        configurable: false,
        writable:true,
        value:address
    })
    Object.defineProperty(obj,"home",{
        writable:false
    })

image.png 从控制台可以看出来,第二次的属性配置项生效了,home属性从可修改变为不可修改,但如果配置的不是writable属性或者不是writable单向从true到false都会报错,如下图:

    Object.defineProperty(obj,"home",{
        configurable: false,
        writable:false,
        value:address
    })
    Object.defineProperty(obj,"home",{
        writable:true
    })  
    

image.png 此处报错为:home属性不可被重定义。

关于这个知识点就先到这里,有问题期待随时指出。