美文网首页
面试总结之基础篇(1)

面试总结之基础篇(1)

作者: 硅谷干货 | 来源:发表于2022-07-20 23:19 被阅读0次

深拷贝与浅拷贝

// let a = 10
        // let b = a
        // b = 20
        // console.log(a,b)

        // 引用数据类型
        // let arr = [1, 2, 3]
        // let newArr = arr
        // newArr.push(666)
        // console.log(arr, newArr)

        // let obj = {
        //     a: 123,
        //     b: '小明'
        // }

        // let newObj = obj
        // newObj.a = 456
        // console.log(newObj, obj)
        
        // 解构赋值?一维数组,一维对象是深拷贝,多维数组,多维对象浅拷贝
        //  => 深拷贝,浅拷贝 => 假
        // let arr = [1, 2, 3]
        // let newArr = [...arr]
        // newArr.push(666)
        // console.log(arr, newArr)

        
        // let arr2 = [[1, 2], [3, 4], [5, 6]]
        // let newArr2 = [...arr2]
        // newArr2[1].push(666)
        // console.log(newArr2, arr2)

        // let objA = {
        //     name: '小明',
        //     age: 18,
        //     arr: [1, 2]
        // }

        // // 深拷贝 function,正则...
        // let newObjA = JSON.parse(JSON.stringify(objA))
        // newObjA.arr.push(666)
        // newObjA.name = '小红'

        // console.log(objA, newObjA)

        
        let objA = {
            name: '小明',
            age: 18,
            arr: [1, 2],
            aa: function(){
                console.log('aa')
            }
        }
        // 标准的深拷贝
        function deepClone(source){ // source => 数组 [], 对象 {}
            const targetObj = source.constructor === Array ? [] : {}
            for(let keys in source){
                if(source.hasOwnProperty(keys)){
                    if(source[keys] && typeof source[keys] === "object"){
                        targetObj[keys] = source[keys].constructor === Array ? [] : {}
                        targetObj[keys] = deepClone(source[keys])
                    }else{
                        targetObj[keys] = source[keys]
                    }
                }
            }
            return targetObj
        }
        let newObjA = deepClone(objA)
        newObjA.name = '小红'
        newObjA.arr.push(888)
        newObjA.aa()
        console.log(objA, newObjA)

原型与原型链

// 原型 prototype => 函数特有
        // 原型链 _proto_  => [[prototype]]
        // let obj = {}
        // console.log(obj)
        // let arr = []
        // obj.prototype.a = 666
        // let fn = function fn(){

        // }
        // console.dir(fn)
        // fn.prototype.name = '小明'
        // fn.prototype.fn2 = function(){
        //     console.log("111")
        // }

        function Person(){

        }
        Person.prototype.name = '小明'
        Person.prototype.age = 18
        Person.prototype.getAge = function(){
            console.log(this.age)
        }
        // 实例
        let person1 = new Person()
        person1.age = 28
        person1.demo = 'demo'
        console.log(person1)
        // person1.getAge()
        // person1.abcd()

        // 从当前实例属性去查找,如果找了就返回,否则顺着原型链一层一层往上面找
        // 直到找到null为止,如果找到null都没有找到,报错

        // 找自身的私有属性
        let item;
        for(item in person1){
            if(person1.hasOwnProperty(item)){
                console.log(item)
            }
        }

防抖节流

// 防抖 =>固定的时间内, 事件只允许发生一次
        let telInput = document.querySelector('input')
        telInput.addEventListener('input', antiShake(demo, 2000))

        // 防抖封装
        function antiShake(fn, wait){
            let timeOut = null;
            return args => {
                if(timeOut) clearTimeout(timeOut)
                timeOut = setTimeout(fn, wait);
            }
        }
        function demo(){
            console.log('发起请求')
        }

        // 节流 => 一定时间内的多个事情合为一个
        // 应用场景 => 1. 提交表单  2. 高频监听事件
        let box = document.querySelector(".box")
        box.addEventListener("touchmove", throttle(demo, 2000))

        function throttle(event, time){
            let timer = null
            return function() {
                if(!timer) {
                    timer = setTimeout(() => {
                        event();
                        timer = null;
                    }, time);
                }
            }
        }

this 指向

//1. console.log(this) Window
        // function abcd(){
        //     console.log(this) // 2. Window
        // }
        // window.abcd()
        
        // 3. 
        // let userName = '李四'
        // let o = {
        //     userName: '王武',
        //     fn1: function(){
        //         console.log(this.userName)
        //     }
        // }
        // o.fn1()
        
        // 谁调用,指向谁 (上一级)
        // var j = {
        //     a: 10,
        //     b: {
        //         a: 12,
        //         fn:function(){
        //             console.log(this.a)
        //         }
        //     }
        // }
        // j.b.fn()

        var id = 66;
        function fn5(){
            // 1. 箭头函数没有作用域 => 没有this
            setTimeout(() => {
                console.log(this.id)
            }, 500)
        }

        // fn5({id: 21})

        fn5.call({id: 21})

        // call, apply, bind
        // call, apply 传参的不同 改变 + 执行
        // bind() 只改变this的指向,不会执行

new关键字

function Person(){
            this.name = '朱小明';
            this.fn = function(){
                console.log(`名字是:${this.name}`)
            }
        }
        let person1 = new Person()
        console.log(person1.name)
        person1.fn()


        // 1. 创建一个空的对象
        let obj = new Object()
        // 2. 链接到原型
        obj.__proto__ = Person.prototype;
        // 3. 绑定this,执行一次构造函数
        let result = Person.call(obj)
        // 4. 确保返回的是一个对象
        if(typeof(result) === "object"){
            person1 = result
        }else {
            person1 = obj
        }

        // 普通函数 => 默认返回值 undefined
        // 构造函数 => 默认返回,新创建的对象
        // function a(){

        // }

深度剖析js闭包

// 1. 闭包是什么?—— 方法里返回一个方法
        // function a(){
        //     let a1 = 1;
        //     return function(){
        //         return a1
        //     }
        // }
        // 2. 闭包存在的意义?
        // 2.1 延长变量的生命周期  
        // 2.2 创建私有环境

        let a = '小明'
        function fn1(){
            let b = 1
            // console.log(a)
        }
        // console.log(b)
        fn1()
        // AO 
        
        // 作用域链
        // let name = "小明"
        // function fn2(){
        //     // let name = "小白"
        //     function fn3(){
        //         // let name = "小红"
        //         console.log(name)
        //     }
        //     fn3()
        // }
        // fn2()

        // 沟通内外部方法桥梁
        function outer() {
            let a1 = 111;
            let a2 = 222;
            return function inner(){
                return a1;
            }
        }

        function fn5() {
            let getInnerData = outer();
            console.dir(getInnerData)
        }
        fn5();

        // 闭包会常驻内存 => 慎用闭包

        // 闭包 => 私有作用域
        // Vue data()为什么是一个函数?
        // data(){
        //     return {

        //     }
        // }

        // 不用闭包,obj = {}

        let makeCounter = function () {
            let num = 0;
            function changeBy(val){
                num += val
            }
            // 给你什么,你才能拿
            return {
                add: function() {
                    changeBy(1)
                },
                reduce: function() {
                    changeBy(-1)
                },
                value: function() {
                    return num
                }
            }
        }

        let counter1 = makeCounter()
        let counter2 = makeCounter()

        
        counter1.add()
        counter1.add()    // 2
        // counter2  // 0
        counter2.add() // 
        console.log(counter2.value())  // 1
        console.log(counter1.value())  // 2

        // 都有独立的词法作用域
        // 面向对象编程 ———— 数据的隐藏和封装

相关文章

网友评论

      本文标题:面试总结之基础篇(1)

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