Getter/setter de tableau javascript?
Est-il un moyen d'obtenir un get/set comportement sur un tableau? J'imagine quelque chose comme ceci:
var arr = ['one', 'two', 'three'];
var _arr = new Array();
for (var i = 0; i < arr.length; i++) {
arr[i].__defineGetter__('value',
function (index) {
//Do something
return _arr[index];
});
arr[i].__defineSetter__('value',
function (index, val) {
//Do something
_arr[index] = val;
});
}
Vous devez vous connecter pour publier un commentaire.
D'accès au tableau n'est pas différent de la normale l'accès à la propriété.
array[0]
signifiearray['0']
, de sorte que vous pouvez définir une propriété de nom'0'
et à intercepter l'accès au premier élément de tableau grâce à cela.Cependant, cela fait qu'il est impossible pour tous mais de courte durée, plus-ou-moins-Tableaux de longueur fixe. Vous ne pouvez pas définir une propriété pour “tous les noms qui se trouvent être des entiers” tout en un aller.
À l'aide de Les procurations, vous pouvez obtenir le comportement souhaité:
JS:
HTML:
Le Proxy constructeur de créer un objet à l'emballage de notre Tableau et utiliser les fonctions appelées des pièges pour remplacer le comportement de base. Le
get
fonction sera appelée pour tout recherche de propriété, etdoSomething()
avant de retourner la valeur.Procurations sont un ES6 fonction et ne sont pas pris en charge dans IE11 ou moins. Voir navigateur liste de compatibilité.
print(arr.constructor);
et vous verrez que c'est encore un tableau. Btwtypeof (new Array())
retourne'object'
ainsi.J'ai regardé dans John Resig de l'article JavaScript Getters Et Les Setters, mais son prototype exemple ne fonctionne pas pour moi. Après avoir essayé quelques solutions de rechange, j'en ai trouvé un qui semblait fonctionner. Vous pouvez utiliser
Array.prototype.__defineGetter__
de la manière suivante:A fonctionné pour moi sur Chrome et Firefox.
J'espère que cela aide.
Array.prototype
. Plus pertinente, la réponse devrait êtrevar SubArrayClass = {}; SubArrayClass.prototype = Object.extend(Array.prototype, { get: ..., set: ... });
Object[property]
, qui est vraiment ce qui est nécessaire pour passer outre. Cela fournit un Tableau comme Objet, ce qui n'est vraiment pas ce que l'affiche est de demander.Il est possible de définir des Accesseurs et Mutateurs pour les tableaux JavaScript. Mais vous ne pouvez pas avoir des accesseurs et des valeurs en même temps. Voir la Mozilla la documentation:
Donc, si vous définir des accesseurs pour un tableau, vous devez avoir un second tableau de la valeur réelle. La suite exemple illustre.
Le code utilise trois tableaux:
Le tableau avec les accesseurs est retournée à l'appelant. Lorsqu'un
set
est appelé par l'affectation d'une valeur à l'élément de tableau, les tableaux contenant la plaine et codé valeurs sont mises à jour. Lorsqueget
est appelée, elle retourne simplement la plaine de la valeur. EttoString
retourne la totalité de la requête contenant les valeurs codées.Mais comme d'autres l'ont déjà dit: cela n'a de sens qu', lorsque la taille de la matrice est constante. Vous pouvez modifier les éléments de la matrice, mais vous ne pouvez pas ajouter d'autres éléments.
Pourquoi ne pas créer une nouvelle classe pour les objets internes?
Et puis,
Je pense que vous obtenez l'idée.
new Array[ ... ]
n'est pas syntaxiquement correct. Vous devez utiliser des parenthèses à la place:new Array( ... )
. Ou tout simplement laisser lesnew Array
et il suffit d'utiliser le " [ ... ] ` la notation littérale.Il est possible de créer des setters pour chaque élément d'un tableau, mais il n'y a qu'une seule restriction: vous ne seriez pas en mesure de régler directement les éléments du tableau pour les index qui sont à l'extérieur de la initialisé région (p. ex.
myArray[2] = ... //wouldn't work if myArray.length < 2
) à l'Aide de la Matrice.prototype des fonctions de travail. (par exemple, push, pop, splice, maj, unshift.) Je donne un exemple de la façon d'accomplir cette ici.Vous pouvez ajouter ce que les méthodes que vous aimez à un
Array
, en les ajoutant àArray.prototype
. Voici un exemple qui ajoute un getter et setterc'est la façon dont je fais les choses. Vous devrez ajuster la Création de Prototypes (j'ai enlevé un peu de ma Version). Mais cela vous donnera la valeur par défaut getter /setter comportement, je suis employé dans d'autres Langages Basés sur des classes.
La définition d'un Getter et pas de Setter signifie que l'écriture de l'élément sera ignorée...
Espère que cette aide.
Cela me donne le comportement attendu de:
De prendre le critizism de dmvaldman: l'Écriture doit maintenant être impossible.
J'ai réécrit le code pour 1)ne pas utiliser depracated éléments (__ defineGetter __) et 2) ne pas accepter toute écriture (qui est: incontrôlé de l'écriture) aux niveaux de l'élément. Un exemple setter est inclus. (J'ai dû ajouter de l'espacement __ defineGetter en raison de markdown)
De dmvaldmans demande:
Cette réponse est juste une extension de la solution basée sur le Proxy.
Voir la solution de proxy, qui ne est mentionné, mais on peut aussi utiliser
jeu que je suis en train de montrer ici.
Avis: 3ème argument dans le jeu peut porter la valeur...
Le code est auto-explicatif.