2017-09-01 66 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