Blog address
Github welcomes Start Follow
This article mainly talks about some basic knowledge, about multiple assignment order, object reference, etc., during the insertion of a little ES6 is just as well as the idea of solving the problem.
Let’s start with an interview question
part1
var a={n:1};
var b=a;
a.x=a={n:2};
console.log(a.x);
console.log(b.x);
Copy the code
What does the output end up being? Forget the answer, let’s analyze it
L2(line 2) We assign a to B, and since A is an object type, this means that B and A refer to the same memory address
L3 a.x = a = { n: 2}
Here we have a doubt, this statement execution sequence is a = {2} n: && a.x = {2} n: or a.x = {2} n: && a = {2} n: is this a = {2} n: && a.x = a
We can use object.defineProperty or ES6 Proxy to verify the order of multiple assignments
const obj = new Proxy({}, {
set(target, key, value, r) {
console.log(key, value)
if (key === 'a') Reflect.set(target, key, 'isA', r);
else Reflect.set(target, key, value, r); }}); obj.b = obj.a= {n: 1};
/ / output:
// "a" {n: 1}
// "b" {n: 1}
obj.a; // isA
obj.b; // {n: 1}
Copy the code
So we can see that the assignment order is from the right to the left. A = {n:1}, a = {n:1}, a.x = {n:1}, not a.x = a
In part1, obj. A and obj. B are used to replace a and b.
var obj = new Proxy({}, {
get: function (target, key, receiver) {
console.log(`getting ${key}! `);
return Reflect.get(target, key, receiver);
},
set: function (target, key, value, receiver) {
console.log(`setting ${key}! `);
return Reflect.set(target, key, value, receiver); }}); obj.a = {n: 1 };// getting a;
obj.b = obj.a; // getting a; setting b;
obj.a.x = obj.a = {n:2 }; // getting a; setting a;
Copy the code
Obj.a.x = obj.a = {n: 2} setting A is getting a.
This means that when assigning to obj.a.x, the program first obtains the memory address of the object pointed to by obj.A, which triggers getting A, and then assigns to obj.A, which triggers setting A, and then assigns to obj.a.x {n:2} after the last step.
Obj.a.x = obj.a.x; obj.a.x = obj.a.x; obj.a.x = obj.a.x; Obj. B also points to that address
Let’s use three more pictures to get a sense of what to do
performobj.a = {n: 1}; obj.b = obj.a
The corresponding reference to post obj looks like this
performobj.a.x = xxx
时
performobj.a.x = obj.a = {n:2}
后
At this point, the interview question I believe we have the answer, you can go to the console to verify. If obj.a.n = 3 is executed, what will be printed if obj.b is printed?
part2
Now let’s look at another problem, which is object circular references
var a = { n: 1}
a.b = a;
Copy the code
Here a is clearly a circular reference, so how can we tell if an object is a circular reference?
In fact, I started this problem in addition to recursive judgment outside no good solution, behind is the group of a call fee big guy said (this problem is also his) directly use JSON. Stringify, wechat small game source code is so to judge.
Uncaught TypeError: Converting circular structure to JSON: Converting circular structure to JSON
What if you don’t use json.stringify or want to implement your own loop to detect calls? (This is a favorite question of interviewers and department leaders.)
In general, the easiest way to do this is to go to the polyfill of this method, JSON3. I’m looking for a jSON3 polyfill which basically iterates through the object into the stack array and then determines if there’s a circular reference when it’s parsed. json3.js#L482
He basically wrote one, which is the simple recursive judgment I talked about earlier
var stack = [];
function fn(obj) {
var len;
for (len = stack.length; len--;) {
if (stack[len] === obj) throw TypeError()
}
stack.push(obj);
for (let k in obj) {
const value = obj[k]
if (typeof value === 'object') fn(value); }}Copy the code
The last time to speak about the language knowledge points, if there are mistakes welcome to point out ~
Thank you for your patronage. Please accept