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.aThe 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