定义一个对象,改变这个对象的属性,或者说是读取这个对象属性以及属性值的时候,我们自己定义的对象,一般不会知道这个对象什么时候被赋值,什么时候被改变。
var object = {
name: 'mapbar_front'
console.log(object.name);
object.name = '中国';
所以基于上面的示例,我们需要使用一种方法,来实现对象的属性的监听。
Object.defineProperty(obj, prop, descriptor)
JS原生对象中,有这样的一个方法,就能够实现对象属性的监听。就是通过defineProperty(obj,prop,descriptor)的第三个参数来实现的。
使用示例如下:
var obj = new Object();
var value;
Object.defineProperty(obj,'name',{
get: function () {
console.log('get it');
return value;
set: function (newvalue) {
console.log('set it');
value = newvalue;
console.log(obj);
console.log(obj.name);
obj.name = 1234;
console.log(obj.name);
封装一个监听属性值变动的方法
使用defineProperty方法封装一个监听属性变动的函数。
var object = {
name:'liwudi',
age:34
function changeIt(object) {
function descripterFun(value) {
return {
enumerable: true,
get: function () {
console.log('get it');
return value;
set: function (newvalue) {
console.log('set it');
value = newvalue;
for(var i in object){
Object.defineProperty(object, i, descripterFun(object[i]))
changeIt(object);
console.log(object.name);
object.name = '我是中国人';
console.log(object);
使用递归,解决深层遍历问题
上面的方式,虽然给一个对象的属性添加上了getter和setter,但是对于深层对象而言,这是不够的。
function observe(obj){
if(!obj || typeof obj != 'object'){
return
for(var i in obj){
definePro(obj, i, obj[i]);
function definePro(obj, key, value){
observe(value);
object.defineProperty(obj, key, {
get: function(){
return value;
set: function(newval){
console.log('检测变化',newval);
value = newval;
问题提出定义一个对象,改变这个对象的属性,或者说是读取这个对象属性以及属性值的时候,我们自己定义的对象,一般不会知道这个对象什么时候被赋值,什么时候被改变。var object = { name: 'mapbar_front'};console.log(object.name);//这个时候我们不知道这个对象的name属性被读取。object.name = '中国';//...
vue实现双向数据绑定的关键是 Object.defineProperty ,让我们先来看下这个函数。
在MDN上查看有关Object.defineProperty 的解释。
我们先从最简单的开始:
let a = {'b': 1};
Object.defineProperty(a, 'b', {
enumerable: false,
configurable: false,
get: function(){
consol
在 ES5中新增了不少新的API, 例如 新增了 Object.xxx相关的方法,其中有一个定义属性相关的 Object.defineProperty 这个方法(还有Object.defineProperties)这个方法是 vue框架实现数据监听的核心方法,它的定义如下:
Object.defineProperty([Object] obj, [String] propname, [Object] desp )
@param obj 要配置属性的某个对象
@param propname 要配置的属性名,是一个字符串
@param desp 对属性的描述,是一个对象,
let watch = page.watch;
for(let i in watch){
let key = i.split('.'); // 将watch中的属性以'.'切分成数组
let nowData = data; // 将data赋值给nowData
let lastKey = k
面试官问:defineProperty如果监视的是一个对象,且对象的属性还是一个对象or数组,那么如何对对象中的对象进行数据监视?把我问傻了,下来之后简单了解了一下,但是在过程中遇到了点问题,顺便记录一下。
我们常使用Object.defineProperty()来监听单个属性的变更,但是一旦牵扯到多个属性的监听,就需要对这个对象进行遍历,下面是我尝试对对象遍历,来实现多个属性监听的尝试。
let person = {
name: '',
age: 0
// Object.k
官方介绍:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
Vue中文社区:https://vue-js.com/learn-vue/reactive/object.html#_2-%E4%BD%BFobject%E6%95%B0%E6%8D%AE%E5%8F%98%E5%BE%97-%E5%8F%AF%E8%A7%82%E6%B5%8B
demo代
Object.defineProperty() 和 Proxy 对象,都可以用来对数据的劫持操作。何为数据劫持呢?就是在我们访问或者修改某个对象的某个属性的时候,通过一段代码进行拦截行为,然后进行额外的操作,然后返回结果。那么vue中双向数据绑定就是一个典型的应用。
Vue2.x 是使用 Object.defindProperty(),来进行对对象的监听的。
Vue3.x 版本之后就改用Proxy进行实现的。
下面我们先来理解下Object.defineProperty作用。
一: 理解Object.defineProperty的语法和基本作用。
在理解之前,我们先来看看一个普通的对象,对象它
点赞 + 关注 + 收藏 = 学会了
首先,解答一下标题:Object.defineProperty 不能监听原生数组的变化。如需监听数组,要将数组转成对象。
在 Vue2 时是使用了 Object.defineProperty 监听数据变...