最新前端面试题------JavaScript面试篇

JavaScript面试题

1.闭包
闭包是什么?
	闭包一个函数和词法环境的引用捆绑在一起,这样的组合就是闭包(closure)。
	(一个函数Areturn出去函数B,被return出去的函数B,能够在外部访问函数A内部的变量)
    代码演示:
        function A(){
            let a = 1;
            return function B(){
                return a
            }
        }
		console.log(A()())
闭包形成的原理:作用域链,当前作用域可以访问上级作用域中的变量。
优点:1.内部函数B可以访问到外部函数A的局部变量
	 2.能够让函数作用域中的变量在函数执行结束之后不被销毁
缺点:1.变量会保存在内存中,不被垃圾回收,造成内存损耗问题。
		解决方法:把闭包的函数设置为null
     2.内存泄露。
2.js的数据类型有哪些,区别是什么?
基本数据类型:Number、String、Boolean、BigInt、Symbol、Null、Undefined
引用数据类型:Object(普通对象,数组,正则,日期,Math数学函数...)
区别:内存中的存储方式不同。
	1.基本数据类型:直接存储在栈中的简单数据段,占据空间小,属于被频繁使用的数据。
    2.引用数据类型:存储在堆内存中,在栈中存储了该堆的指针,占据空间大。
注:BigInt和Symbol是ES6所提出来的
3.防抖与节流区别?
共同点:都是为了减少函数的执行次数,提升性能。
1.防抖:把多次函数执行,合并成一次执行。
	给定一个间隔时间,当两次函数执行的间隔时间大于了给定的间隔时间,就执行一次函数。
    使用场景:商品搜索、数据实时查询...
    代码演示:
    	function debounce(fn, delay){ // fn是真正执行的函数, delay是时间间隔
            let timer = null;
            return function(){
                // var that = this;
                // var args = arguments;
                if (timer) clearTimeout(timer)
                timer = setTimeout(function(){
                    fn.apply(this, [...arguments])
                },delay)
            }
        }
2.节流:减少函数执行的频率。
	规定一个单位时间,在单位时间内触发一个事件回调,触发时超过间隔时间则执行,否则不执行。
    使用场景:比如我们的移动端,在一段时间内成百上千次的执行同一个方法。
    代码演示:
    	function throttle(fn, gapTime){
            let lastTime = null;
            return function(){
                // var that = this
                // var args = arguments;
                let nowTime = new Date();
                if(nowTime-lastTime>gapTime && !lastTime){
                    fn.apply(this, arguments);
                    lastTime = nowTime;
                }
            }
        }
4.JavaScript的浅拷贝和深拷贝
注意:深浅拷贝只针对引用类型(Object),基本类型这种就是普通的赋值操作不是拷贝
共同点:复制
判断深浅拷贝的方法:是否是同一个地址
1.浅拷贝:只是复制了对应的地址,而未复制真正的值
	方法1var arr1 = ['a','b','c','d'];
		var arr2 = arr1;
	方法2var obj1 = {a:1,b:2}
		var obj2 = Object.assign(obj1);
2.深拷贝:是复制真正的值 (不同引用)
	方法1:利用JSON进行深拷贝
    	var obj3 = { a:1,b:2 }
        var obj4 = JSON.parse(JSON.stringify(obj3));
	方法2:利用递归的方法进行深拷贝
    	function copyObj(obj){
            // constructor指向的是该引用类型的基类
            var newObj = obj.constructor === Array ? []:{};
            for( let keys in obj ){
                if(obj.hasOwnProperty(keys)){
                    if( obj[keys] && typeof obj[keys] === "object" ){
                        // 递归
                        newObj[keys] = copyObj(obj[keys])
                    }else{
                        newObj[keys] = obj[keys]
                    }
                }
            }
            return newObj
        }
5. == 与 === 的区别
1.==是非严格意义上的相等:比较的是值相等
2.===是严格意义上的相等:及比较数据类型同时也比较值
6. map与forEach的区别?
1.forEach: 可以通过在函数体内部使用索引修改数组元素,默认无返回值,其结果是undefined。
	代码演示:
		array.forEach(function(currentValue, index, arr), thisValue)
		// currentValue: 必需。当前元素
		// index: 可选。当前元素的索引值。
		// arr: 可选。当前元素所属的数组对象。
		// thisValue: 可选。传递给函数的值一般用"this"值。
		//            如果这个参数为空,"undefined"会传递给"this"值
2.map: 不管数组元素是undefined或者null,都会return出一个length和原数组一致的新数组,有返回值。用法和forEach基本相同。
7.this指向
1.this总是指向函数的直接调用者。
2.如果有new关键字,this指向new出来的对象。
3.在事件中,this指向触发这个事件的对象。
8.原型以及原型链
1.谁有原型
    函数拥有:prototype
    对象拥有:__proto__
2.对象查找属性或者方法的顺序
    先在对象本身查找 --> 构造函数中查找 --> 对象的原型 --> 构造函数的原型中 --> 当前原型的原型中查找 --> ... --> null(侧面说明了原型链)
3.原型链:就是把原型串联起来
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农小林子

个人整理不易,非常感谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值