vue2响应式原理之Object.defineProperty()方法的使用

 更新时间:2023年10月07日 09:52:19   作者:山海入梦  
这篇文章主要介绍了vue2响应式原理之Object.defineProperty()方法的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

前言

最近一直在研究vue2响应式原理,去官网看一遍文档,好像懂了但又好像不懂,然后去查看别人写的响应式原理和视频,好的理解了百分六七十头皮发麻,vue2的响应式原理实现的核心就是Object.defineProperty()方法,所以自己也跟着手敲一下响应式源码记录对Object.defineProperty的理解

一、Object.defineProperty()

1.概念

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象.

这句话到底什么意思呢?

我们简单实现这个方法

var obj = {}
Object.defineProperty(obj, 'name', {
  value:'科比'
})
console.log(obj.name)  //科比

可以看出Object.defineProperty()能为我们定义一个属性,又有人会想为什么我们不直接定义obj.name='科比',而使用这个方法不更加麻烦吗?

2.Object.definProperty()方法

可以设置额外隐藏的属性使用这些属性能够使对象更加自由的被定义

var obj = {}
Object.defineProperty(obj, 'name', {
  value:'科比',
  //是否可写
  writable: false 
})
Object.defineProperty(obj, 'number', {
  value:24,
  //是否可枚举
  enumerable: false 
})
//修改属性报错
obj.name = "库里"  //Cannot assign to read only property 'name' of object '#<Object>'
console.log(obj.name)  

通过obj对象定义writable: false 使你属性不能修改,如果修改obj.name就会报错;enumerable是否可以枚举,所以使用这些属性能够使对象更加自由的被定义

二、Object.definProperty()方法的get()和set()

代码如下(示例):

通过这个示例可知访问obj.name属性就会触发get()方法,修改obj.name属性触发set()方法

但是我们发现修改obj.name属性为"乔丹",打印为undefined这是为什么呢?

看一下get和set方法的介绍:

get

  • 属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。
  • 执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。
  • 该函数的返回值会被用作属性的值。
  • 默认为 undefined

set

  • 属性的 setter 函数,如果没有 setter,则为 undefined。
  • 当属性值被修改时,会调用此函数。
  • 该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。
  • 默认为 undefined

因为get的函数返回值会被当作属性的值,而我们示例中get和set没有return 任何值,就默认为undefined,修改后:

const obj = {}
Object.defineProperty(obj , 'name' , {
  get(){
    console.log('访问obj.name属性触发')
    return "乔丹"
  },
  set(newValue) {
    console.log('修改obj.name属性触发' , newValue)
  }
})
obj.name  //访问属性
console.log(obj.name)  //乔丹
obj.name = "科比"  //修改属性
console.log(obj.name)  //乔丹

 

能够访问到设置的obj属性了,但是修改了obj.name = "科比"

最后打印还是"乔丹" ,但是set方法触发的newValue是科比这又是为什么呢?

因为getter并不能返回你修改的值,只要你访问obj.name他就是返回return "乔丹"

就如同你设置的set新属性从未改变一样非常固执,那么我们应该怎么解决这个问题呢?

我们可以通过一个变量com进行周转,修改如下:

var obj = {}
var com;  //设置变量周转
Object.defineProperty(obj , 'name' , {
  get(){
    console.log('访问obj.name属性触发')
    return com
  },
  set(newValue) {
    console.log('修改obj.name属性触发' , newValue)
    com = newValue
  }
})
obj.name  //访问属性
console.log(obj.name)  //乔丹
obj.name = "科比"  //修改属性科比
console.log(obj.name)  //最后控制台打印 科比

详细了解Object.defineProperty()方法

总结

vue2的响应式原理核心就是基于Object.defineProperty()方法实现的哟,不过完整的响应式源码可不止这样简单,所以下一篇博客就是手敲完整vue2响应式源码实现,加深理解.

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue+elementUI实现简单日历功能

    vue+elementUI实现简单日历功能

    这篇文章主要为大家详细介绍了vue+elementUI实现简单日历功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09
  • Vue打包工具(构建工具)和脚手架过程

    Vue打包工具(构建工具)和脚手架过程

    文章介绍了Vue项目中Webpack和Vite的使用区别,Webpack需vue-cli全局安装,适合复杂场景;Vite更轻量快速,适合Vue3项目,并提到尤雨溪团队新推出的VoidZero技术布局
    2025-08-08
  • 实例详解Vue项目使用eslint + prettier规范代码风格

    实例详解Vue项目使用eslint + prettier规范代码风格

    这篇文章主要介绍了Vue项目使用eslint + prettier规范代码风格,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2018-08-08
  • Vue-ref与props的使用详解

    Vue-ref与props的使用详解

    文章总结了Vue3中props和ref的使用方法、特点及区别,包括基本用法、类型校验、默认值设置、事件通信等,并指出了常见误区和最佳实践
    2026-01-01
  • Vue使用vant实现日期选择器功能

    Vue使用vant实现日期选择器功能

    在当今前端开发的领域中,Vue 框架因其高效和灵活的特性备受开发者青睐,而 Vant 是一个轻量的移动端组件库,为 Vue 应用的开发提供了丰富且便捷的功能组件,本文将就如何在 Vue 框架中通过 Vant 来实现日期选择器的使用,需要的朋友可以参考下
    2024-08-08
  • Vue.js绑定HTML class数组语法错误的原因分析

    Vue.js绑定HTML class数组语法错误的原因分析

    Vue.js绑定HTML class数组语法错误有哪些原因导致的呢,该如何解决呢?下面小编给大家分享Vue.js绑定HTML class数组语法错误的原因分析,感兴趣的朋友一起看看吧
    2016-10-10
  • Vue自定义全局弹窗组件操作

    Vue自定义全局弹窗组件操作

    这篇文章主要介绍了Vue自定义全局弹窗组件操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • vue cli3配置image-webpack-loader方式

    vue cli3配置image-webpack-loader方式

    这篇文章主要介绍了vue cli3配置image-webpack-loader方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • vue+iview+less+echarts实战项目总结

    vue+iview+less+echarts实战项目总结

    本篇文章是作者通过学习vue+iview+less+echarts制作一个小系统后,做的心得以及遇到的坑的总结,值得大家学习参考。
    2018-02-02
  • 解决vue中使用proxy配置不同端口和ip接口问题

    解决vue中使用proxy配置不同端口和ip接口问题

    这篇文章主要介绍了解决vue中使用proxy配置不同端口和ip接口问题 ,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08

最新评论