admin管理员组文章数量:1292177
I'm learning about observing Array objects. I found the following surprising:
var fooArray = [];
Array.observe(fooArray, function(changes){
console.log('changes:', changes[0].type);
});
fooArray.push({});
results in the type of change being splice
and not add
What methods would result in a change event of type add
? It would seem to me that pushing a single value on it would be the most likely scenario.
I'm learning about observing Array objects. I found the following surprising:
var fooArray = [];
Array.observe(fooArray, function(changes){
console.log('changes:', changes[0].type);
});
fooArray.push({});
results in the type of change being splice
and not add
What methods would result in a change event of type add
? It would seem to me that pushing a single value on it would be the most likely scenario.
-
1
Changing properties, at least. Adding to the collection is technically splicing, whether you're adding or removing. If you tried
fooArray.f = "whatever";
, you'd see it be for "add" – Ian Commented Mar 26, 2015 at 0:35 - The MDN documentation states "Index assignment changes which do not change the length of the array may be reported as update changes" Would that not fall under an update and not an add? Or only if 'f' does not exist yet? – Sean Anderson Commented Mar 26, 2015 at 0:38
- Why do you bring that up? Setting properties isn't the same as index assignment – Ian Commented Mar 26, 2015 at 0:39
- I see now. It does make some sense, but I guess a bit unintuitive to those uninformed. Feel free to submit it as an answer. – Sean Anderson Commented Mar 26, 2015 at 0:40
- Well, I was lucky to guess and see that setting properties would trigger the "add" event. I hadn't known, and I'm not sure if it's the only way, so I was hoping for someone else to chime in – Ian Commented Mar 26, 2015 at 0:44
3 Answers
Reset to default 7The MDN reference is not clear about what circumstances fire each change type. Here is a detailed explanation:
splice
Covers every change that you would expect to happen in an array. All the following functions trigger it:
push()
pop()
shift()
unshift()
splice()
update
Triggers if the value of some element changes:
var arr = ['a', 'b', 'c'];
Array.observe(arr, function (changes) {
console.dir(changes);
});
arr[0] = 'A'; // triggers 'update'
It's worth mentioning that some array functions may also trigger it, like reverse()
.
add | delete
As unintuitive as it seems, these types are triggered when a property is added to/deleted from the array. For example:
var arr = ['a', 'b', 'c'];
Array.observe(arr, function (changes) {
console.dir(changes);
});
arr.foo = 'bar'; // triggers 'add'
delete arr.foo; // triggers 'delete'
P.S.: See Jack's answer on why it behaves like this.
The change observer is actually implemented in Object
, from which Array
inherits. You can get your expected behaviour when you use Object.observe()
instead:
var arr = [];
Object.observe(arr, function(changes) {
console.log(changes)
});
arr.push({});
Output:
[
{"type":"add","object":[{}],"name":"0"},
{"type":"update","object":[{}],"name":"length","oldValue":0}
]
As you can see, two things happen here:
- An object is added under property 0 (i.e. first element),
- The length property is updated to reflect the new number of elements.
The Array.observe()
groups those two changes together into a single splice change; basically, anything that affects the length of an array will fall under this. The add and delete change types will only be triggered for normal properties, leaving just the update change type to work in the same way.
By adjusting the accept type list of Object.observe()
via the optional third argument, you can confirm this:
var arr = [];
Object.observe(arr, function(changes) {
console.log(changes)
}, ['add', 'update', 'delete', 'splice']);
arr.push({});
Output:
[
{"type":"splice","object":[{}],"index":0,"removed":[],"addedCount":1}
]
In fact, Array.observe()
can be implemented like this:
Array.observe = function(arr, callback) {
return Object.observe(arr, callback, ["add", "update", "delete", "splice"]);
};
As such, the following change types aren't sent to your callback when you use Array.observe()
:
["reconfigure", "setPrototype", "preventExtensions"]
In addition to setting custom properties such as arr.b = 1
it is also possible, at least currently using V8 in Node, Opera or Chrome, to trigger "add" changes on Array using:
arr = []
arr[1] = 1 // "splice" change
arr[0] = 1 // "add" change
本文标签: javascriptUnder what condition would Arrayobserve39s quotaddquot event triggerStack Overflow
版权声明:本文标题:javascript - Under what condition would Array.observe's "add" event trigger? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741551846a2384926.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论