2017-09-01 54 views
1

我想获取嵌套对象中值的路径。但是我的实验并没有按照我的预期工作。 scope应该返回从嵌套对象暴露的值的路径(键数组),但我不知道如何实现这一点。获取嵌套对象中访问值的路径

它应该像返回访问路径的观察者一样工作。

下面是我的实现。

function wrap(o, fn, scope = []) { 
 
    const handler = { 
 
    set(target, prop, value, receiver) { 
 
     fn('set value in scope: ', scope.concat(prop)) 
 
     target[prop] = value 
 
     return true 
 
    }, 
 
    get(target, prop, receiver) { 
 
     fn('get value in scope: ', scope.concat(prop)) 
 
     return o[prop] 
 
    }, 
 
    ownKeys() { 
 
     fn('keys in scope: ', scope) 
 
     return Reflect.ownKeys(o) 
 
    } 
 
    } 
 

 
    return new Proxy(
 
    Object.keys(o).reduce((result, key) => { 
 
     if (isObject(result[key])) { 
 
     result[key] = wrap(o[key], fn, scope.concat(key)) 
 
     } else { 
 
     result[key] = o[key] 
 
     } 
 
     return result 
 
    }, {}), 
 
    handler 
 
) 
 
} 
 

 
function isObject(obj) { 
 
    return typeof obj === 'object' && !Array.isArray(obj) 
 
} 
 

 
const obj = wrap({ 
 
    a0: { 
 
    a1: { 
 
     a2: 0 
 
    }, 
 
    b1: { 
 
     b2: 0 
 
    } 
 
    }, 
 
    b0: 0 
 
}, console.log) 
 

 

 
// set value: 
 
obj.b0 = 1 
 

 
// get value: 
 
console.log('value: ' + obj.a0.a1.a2) 
 

 
// list keys: 
 
console.log('keys: ', Object.keys(obj.a0))

  • 第一个日志应该返回set value in scope: ['b0']
  • 第二应该返回get value in scope: ['a0', 'a1', 'a2']value: 0
  • 最后一个应该返回keys in scope: ['a0']obj.a0
键3210

感谢您的帮助!

回答

1

你犯了几个错误:

get(target, prop, receiver) { 
    fn('get value in scope: ', scope.concat(prop)) 
    return o[prop] 
}, 

这是return target[prop]返回包的版本。 和

if (isObject(result[key])) { 
    result[key] = wrap(o[key], fn, scope.concat(
} else { 
    result[key] = o[key] 
} 

isObject(o[key])检查原始对象

上,并没有触及任何你第二日志看起来更像:

get value in scope: ['a0'] 
get value in scope: ['a0', 'a1'] 
get value in scope: ['a0', 'a1', 'a2'] 
value: 0