2017-09-01 2 views
1

Je souhaite obtenir le chemin d'accès à la valeur dans un objet imbriqué. Mais mon expérience ne fonctionne pas comme prévu. Le scope doit retourner le chemin (tableau de clés) à la valeur exposée de l'objet imbriqué mais je ne sais pas comment y parvenir.Récupère le chemin d'accès à la valeur d'accès dans un objet imbriqué

Cela devrait fonctionner comme un observateur qui renvoie le chemin d'accès.

Voici ma mise en œuvre.

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))

  • Le premier journal doit retourner set value in scope: ['b0']
  • le second doit retourner get value in scope: ['a0', 'a1', 'a2'] et value: 0
  • le dernier devrait revenir keys in scope: ['a0'] et les clés de obj.a0

Merci pour toute aide!

Répondre

1

Vous avez fait quelques erreurs:

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

Il est return target[prop] de retourner la version enveloppée. et

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

il est isObject(o[key]) de vérifier l'objet original

Et sans toucher quoi que ce soit d'autre que vous deuxième journal ressemblera plus:

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