Some problems about the preparation of JS clone() function

Keywords: Javascript

Problem Description: use js to implement a clone() cloning function, which will clone one of the different types of input values Number, String, Undefined, Boolean, Function,Null,Object,Array,RegExp

1, Solution code

Post code directly,

function clone(obj){
            var copy;
            switch(typeof obj){
                case 'undefined':break;
                case 'number':
                case 'string':
                case 'boolean':
                case 'function':copy = obj;break;
                case 'object':
                    if(obj == null) copy = null;
                    else if(toString.call(obj) === '[object Array]')
                    {
                        copy = [];
                        for(var i in obj) copy.push(clone(obj[i]));
                    }
                    else if(toString.call(obj) === '[object RegExp]')
                    {
                        copy = obj;
                    }
                    else 
                    {
                        copy = {};
                        for(var j in obj)
                            copy[j]= clone(obj[j]);
                    }
            }
            return copy;
        }
        var a=undefined;
        var b=1;
        var c="Hello";
        var d=true;
        var add=function(a,b){
            return a+b;
        }
        var e=null;
        var f=[1,2,3];
        var g=/^\s+/;
        var h={
            a:1,
            b:2
        }
        console.log(typeof clone(a));
        console.log(typeof clone(b));
        console.log(typeof clone(c));
        console.log(typeof clone(d));
        console.log(clone(add)(1,2));
        console.log(Object.prototype.toString.call(clone(e)));
        console.log(Object.prototype.toString.call(clone(f)));
        console.log(Object.prototype.toString.call(clone(g)));
        console.log(Object.prototype.toString.call(clone(h))); 

Result:

Two, questions

When I first saw this problem, I thought that the result of typeof [1,2,3] was, what can I do? Regular expression, null, object's typeof are all. Look at the above code. It is solved by Object.prototype.toString.call(obj) or toString.call(obj).

Why not just obj.toString()? Let's first see what obj.toString() will output?

There is an error in null and undefined, which is certain, because toString() cannot complete the transformation of null and undefined. Only String() can be used

If String() is not converted to null or undefined, the automatic conversion to toString(). Is far away.. Let's get back to the point

So what is the result of using Object.prototype.toString.call(obj)?

It 's different. What' s the matter?

It turns out that although Array, Null and other types are instances of Object, they each override the toString() method. Let's try to verify:

var arr=[1,2,3];
console.log(Array.prototype.hasOwnProperty("toString"));//Determine if there is any in the prototype toString()Method
console.log(arr.toString());
delete Array.prototype.toString;//delete Array Rewritten in the prototype toString
console.log(Array.prototype.hasOwnProperty("toString"));
console.log(arr.toString());

Result:

It's obviously rewritten.

3, There's something else

In fact, some people will say that you can use the array instanceof array to determine whether it is an array. In fact, instanceof will fail in the scenario built across frame objects.

Posted by kevin99 on Tue, 31 Mar 2020 22:20:05 -0700