前端面试题-js

1.对象深浅拷贝

1:为什么需要拷贝

        var a=1,
            b=a;
        a=3;
        //此时b是不会被a的改变的
        console.log(b);

因为对象赋值的时候赋值的是引用

        var a ={
            a :1
        };
        var b=a;
        a.a=2;
        // 此时会被更改,因为赋值的是引用
        console.log(b);

2 :如何实现对象的浅拷贝==引用跟一起变

        //浅拷贝;拷贝对象一层
        var a ={
            a:1,
            b:2,
        }
        function simpleClone(obj) {
            var cloneObj = {};
            //es3语法实现,语义化不强
            for(var i in obj){
                cloneObj[i] = obj[i]
            }
            }
            // console.log(Object.keys(obj));
            // console.log(Object.values(obj));
            // console.log(Object.entries(obj));

            // for (var key of Object.keys(obj)) {
            //     cloneObj[key] = obj[key];
            // }
            // es6语法
            for (var [key,value] of Object.entries(obj)) {
                cloneObj[key] = value;
            }
            return cloneObj;

            //es5语法 defineProperty;
            Object.getOwnPropertyNames(obj).forEach(function (key){
                // cloneObj[key] = obj[key];
                var des = Object.getOwnPropertyDescriptor(obj,key)
                Object.defineProperty(cloneObj,key,des);
            });
            return cloneObj;
        }
        console.log(simpleClone(a))

3、如何实现深拷贝=不跟着变(引用:切断)

1、原生js实现对象的深拷贝:

创建一个对象,将原对象的属性赋到创建的对象上去;

    <script>
        var obj ={
            a:1,
            b:{
                c:3,
                d:{
                    e:5
                }
            }
        }
        //对象里面包含对象,对象赋值存在引用(会跟着变),所以要使用递归,一层层排除对象
        function deepClone(obj,cloneObj) {
            //如果存在数组
            cloneObj[i] = Array.isArray(obj[i]) ? [] :{} ;
            for( i in obj) {
                if( typeof obj[i] === 'object' && obj[i] !== null ) {
                    cloneObj[i] ={};
                    deepClone(obj[i],cloneObj[i]);
                }
                // 递归的出口:防止死循环
                else{
                    cloneObj[i] = obj[i];
                }
            }
            return cloneObj;
        }

        var obj1 = deepClone(obj);
        // console.log(obj);
        obj.b.c = 10;
        console.log(obj1);
    </script>
2、通过JSON.stringify实现
        var obj ={
            a:1,
            b:{
                c:3,
                d:{
                    e:5,
                    f:[1,2,3,4,5]
                }
            }
        }
        //JSON.parse JSON.stringify;
        function deepClone(obj){ 
            //把对象转换成字符串
            console.log(JSON.stringify(obj));
            //把字符串转换成对象
            return (Json.parse(JSON.stringify(obj)))
        }


        var obj1 = deepClone(obj);
        // console.log(obj);
        obj.b.c = 10;
        obj.b.d.f.push(7); 
        console.log(obj1);
3、使用JQuery-extend实现深拷贝
        var obj ={
            a:1,
            b:{
                c:3,
                d:{
                    e:5,
                    f:[1,2,3,4,5]
                }
            }
        }
        //3、使用jQuery中的extend实现深拷贝
        console.log($.extend(true,{},obj))
        function deepClone(obj) {
            return $.extend(true,{},obj)
        }

        var obj1 = deepClone(obj);
        // console.log(obj);
        obj.b.c = 10;
        obj.b.d.f.push(7); 
        console.log(obj1);

2.数组去重和排序

去重:

        //a.indexof(元素b) 返回为-1:数组a里面没有元素b;
        //封装一个去重的函数 unique 独一无二的
        function unique(arr) {
            var newArr = [];
            for (var i=0;i<arr.length;i++) {
                if(newArr.indexOf(arr[i]) === -1){
                    newArr.push(arr[i]);
                }
            }
            return newArr;
         }
         var demo = unique(["成强","chengqiang","成强"]);
         console.log(demo);

排序:

    <script>
        var arr=[1,5,2,4,9,6,7];
        var Newarr=[];
        Newarr= arr.sort(function(a,b){
            return a-b;//返回的升序
        });
        console.log(Newarr);
    </script>

冒泡排序:

    <script>        var a= [7,5,1,4,3];        for(var i=0; i<a.length; i++) {             for(var j=0;j<a.length-i;j++){                if (a[j]>a[j+1]){                    var t=a[j];                    a[j]=a[j+1];                    a[j+1]=t;                }            }        }        console.log(a);    </script>

2.数组扁平化

        //数组的扁平化        let arr = [1,2,[3,[4,[5,6]]]]        //要求将数组扁平化处理[1,2,3,4,5,6]        //方式一 flat(参数:深度)        console.log(arr.flat(Infinity))        //方式二 reduce 方法        let arr1 = [1,2,3,4]        let res = arr1.reduce((total,item)  => {            return total + item        },0)        console.log(res)                // function flatFn(arr){        //     return arr.reduce((total,item) => {        //         return res.concat(Array.isArray(item)?flatFn(item):item)        //     },[])        // }        // console.log(flatFn(arr))        //方式三 数组转成字符串,再将字符串转成数组        function flatfn(arr){            return arr.join(',').split(',').map((item) => {                return parseInt(item)            })        }        console.log(flatfn(arr))

3、堆栈内存+闭包作用域

1、作用域

es6定义变量的方法:let const

子可以访问父级,父级不能访问子集

2、闭包:一个函数和它周围状态的引用捆绑在一起的组合
    <script>        //1、函数作为返回值(函数内部临近)        function test(){            const a =1;             return function(){                console.log('a',a);            }        }        const fn = test();        const a =2;        fu(); // a=1        //2、函数作为参数(外部临近参数)        function test(fn) {            const a =1;            fn();        }        const a =2;        function fn(){            console.log('a',a);        }        test(fn);//a=2            </script>
3、堆和栈(都是内存里面的2大块)

栈:简单数据类型:函数的参数值funciton(a)、简单变量值const a=3;存放的是值;

堆:复杂类型(对象),由程序员释放,若程序员不释放,由垃圾回收机制回收;首先在栈里面存放16进制地址,这个地址指向堆里面的数据;

![image-20210919144856982](/Users/yangmiemiedeliuzhuzhu/Library/Application Support/typora-user-images/image-20210919144856982.png)

4、this的值

this的值是函数执行的时候决定的,不是函数定义时决定

    <script>        function test(){            console.log("this",this);        }        test();        test.call({ name: '成强'});        test.apply({ name: '成强'});        class Person {            constructor(name,age){                console.log('constrctor里面的this', this);                this.name =name;                this.age =age;            }            test (){                console.log('对象方法里面的this ',this)            }            asyncTest() {                console.log(this)//this指向实例对象Person                setTimeout(function(){                    console.log('setTimeout回调中的this',this);                    //this指向的window                },0)            }        }        const chengqiang= new Person("成强",20);        chengqiang.test();    </script>
5、使用原生js实现call、apply、blind
posted @ 2021-09-19 13:06  成强  阅读(49)  评论(0编辑  收藏  举报