美文网首页
让前端面试不再难(三)

让前端面试不再难(三)

作者: 我是一个前端 | 来源:发表于2019-01-29 10:52 被阅读0次

    今天聊一下clone这个前端面试高频问题,由此引出typeof、instanceof、Object.prototype.toString这些javascript Api。

    下面我们先详细的聊一下,完了解决下面试官的问题。

    typeof

    typeof能获取一个变量或表达式的类型。

    • 原始类型
      • Boolean
      • Null
      • Undefined
      • String
      • Symbol
    • 和 Object,Function

    下面看一些栗子

            //基础类型也可以说非引用类型
            let str = 'hello word!'
            console.log(typeof str) //string
            let num = 12
            console.log(typeof num) //number
            let udf = undefined
            console.log(typeof udf) //undefined
            let bl = true
            console.log(typeof bl) //boolean
            let nl = null
            console.log(nl) //null
            let sl = Symbol()
            console.log(typeof sl) //symbol
    
            //复合类型也可以说是引用类型,
            let obj = {
                a: 1
            }
            console.log(typeof obj) //object
            let arr = [1, 2, 3]
            console.log(typeof arr) //object
    
            //函数也属于引用类型,不过typeof却能准确的返回类型
            function fn() {}
            console.log(typeof fn) //function
    

    从以上的执行结果可以看出,typeof不能够准确分返回所有类型

    instenceof

    我们从instenceof的实现来了解下instenceof是干什么的

            // 模拟instenceof实现
            // 1、instenceof接收两个参数
            // 2、返回true或false
    
            function myInstenceof(X, Y) {
                let L = X._proto_
                let R = Y.prototype
                if (L !== R) {
                    return false
                }
                return true
            }
    
            // test
            function Fn() {
    
            }
            let newFn = new Fn()
            console.log(newFn)
            console.log(new Fn())
    
    
            console.log(myInstenceof(newFn, new Fn())) //true
            console.log(myInstenceof([], new Array())) //true
            console.log(myInstenceof([], new Object())) //true
    
    

    以上demo我们就能看出,instenceof也不够靠谱,模拟实现就是判断X的原型知否在Y的原型链上。
    数组之所以instenceof Object为true是因为 [].prototype->new Array->new Object->null

    上边说了typeof和instenceof其实就是想说这两个对于深度clone的实现来说不够严谨要不就是多层判断。

    Object.prototype.toString.call()

    接下里我们说个靠谱的

            Object.prototype.toString.call(''); // [object String]
            Object.prototype.toString.call(1); // [object Number]
            Object.prototype.toString.call(true); // [object Boolean]
            Object.prototype.toString.call(undefined); // [object Undefined]
            Object.prototype.toString.call(null); // [object Null]
            Object.prototype.toString.call(new Function()); // [object Function]
            Object.prototype.toString.call(new Date()); // [object Date]
            Object.prototype.toString.call([]); // [object Array]
            Object.prototype.toString.call(new RegExp()); // [object RegExp]
            Object.prototype.toString.call(new Error()); // [object Error]
            Object.prototype.toString.call(document); // [object HTMLDocument]
            Object.prototype.toString.call(window); //[object Window]
    

    靠谱!

    接下来我们就用Object.prototype.toString.call()来解答一下面试题

          function clone(obj, o) {
                //Object.prototype.toString.call(obj)返回类似[Object Array] 利用slice来截取我们需要的字符串
                let type = Object.prototype.toString.call(obj).slice(8, -1)
                    // 如果是Object
                if (type === 'Object') {
                    o = {}
                    for (let k in obj) {
                        o[k] = clone(obj[k]);
                    }
                    // 如果是对象
                } else if (type === 'Array') {
                    o = []
                    for (let i = 0; i < obj.length; i++) {
                        o.push(clone(obj[i]));
                    }
                } else {
                    // 非引用类型
                    o = obj
                }
                return o
            }
    
            let obj1 = {
                a: [1, 2, 3, 4, 5, 6],
                b: {
                    c: 2
                },
                d: 1,
                f: function() {
                    return 1
                }
            }
            let obj2 = clone(obj1)
            obj2.f = function() {
                return 2
            }
            obj2.a = 1
            console.log(obj1)
            console.log(obj2)
    

    测试打印结果,obj2的改变不会影响到obj1。


    image.png

    欢迎吐槽!

    相关文章

      网友评论

          本文标题:让前端面试不再难(三)

          本文链接:https://www.haomeiwen.com/subject/jqevkqtx.html