Those 5 example cases should all have the same output, but the 2nd and 4th are currently different:
var regularList = [];
regularList = ["a"].concat(regularList);
regularList = ["b"].concat(regularList);
regularList = ["c"].concat(regularList);
regularList = ["d"].concat(regularList);
console.log(regularList);
var observableList = mobx.observable([]);
observableList = ["a"].concat(observableList);
observableList = ["b"].concat(observableList);
observableList = ["c"].concat(observableList);
observableList = ["d"].concat(observableList);
console.log(observableList);
var myObject = {
someList: []
};
myObject.someList = ["a"].concat(myObject.someList);
myObject.someList = ["b"].concat(myObject.someList);
myObject.someList = ["c"].concat(myObject.someList);
myObject.someList = ["d"].concat(myObject.someList);
console.log(myObject.someList);
var myObservableObject = mobx.observable({
someList: []
});
myObservableObject.someList = ["a"].concat(myObservableObject.someList);
myObservableObject.someList = ["b"].concat(myObservableObject.someList);
myObservableObject.someList = ["c"].concat(myObservableObject.someList);
myObservableObject.someList = ["d"].concat(myObservableObject.someList);
console.log(myObservableObject.someList);
var observableWithSlice = mobx.observable({
someList: []
});
observableWithSlice.someList = ["a"].concat(observableWithSlice.someList.slice());
observableWithSlice.someList = ["b"].concat(observableWithSlice.someList.slice());
observableWithSlice.someList = ["c"].concat(observableWithSlice.someList.slice());
observableWithSlice.someList = ["d"].concat(observableWithSlice.someList.slice());
console.log(observableWithSlice.someList);
Output:
["d","c","b","a"]
["d","c","b","a", []]
["d","c","b","a"]
["d",["c",["b",["a",[]]]]]
["d","c","b","a"]
@mweststrate pointed out on gitter:
@bb that looks like a bug indeed
https://github.com/mobxjs/mobx/blob/master/src/types/observablearray.ts#L264 is the sourceEDIT: forgot mobx.observable([]) in initial version
The _2nd_ example was not using mobx.observable. Sorry for this copy'n'paste error. It's now fixed above. Please note that this brought up another difference for the empty observable array.
After a few more thoughts and debug outputs, it looks to me that an array property of an observable object is not imitating array as good as observableArray does.
Some more differences between the 5 examples:
Array.isArray(x) (but all return true for x instanceof Array)t or ObservableArray {})["0","1","2","3"]vs []["0","1","2","3","length"] vs ["$mobx"]toString.call(x) returns [object Array] vs [object Object]See https://jsfiddle.net/bock/0bpxtasx/ for executable test cases.
Don't see any bugs here.
[observableArray] as far as Array.isArray(observableArray) === false[observableArray] to observable property, it is being automatically converted to ObservableArray so you get ObservableArray["a", observableArray], then ["b" ObservableArray["a", observableArray]] becomes ObservableArray["b", ObservableArray["a", observableArray]] and so on.What's wrong with that?
Thanks for analyzing @andykog!
Behavior in all cases seems to be correct. (Not per se desirable, but alas, proxies.... Safari hurry up!)