JS前端面试问答(一)

1.JS怎么控制一次加载一张图片,加载完后再加载一张?

答:获取所有图片的src使用onload事件。

2.代码的执行顺序?

答:如果既不使用异步也不使用延迟的话,从上至下,从左至右,而且当浏览器在解析js时,无论是外部引用还是内嵌的形式,都不能同时做其他的事情,如果浏览器遇到外部的js文件,会停下来去解析外部引用的js文件。

3.如何实现sleep的效果(ES5或ES6)?

答:有三种方式实现sleep:promiseasyncgenerate
(1) promise

function sleep(ms){
	const temple=new Promise((resolve)=>{
		console.log('sleep');
		setTimeout(resolve,ms);
	});
	return temple;
}
sleep(500).then(()=>{
	console.log('end');
});

(2) async

function sleep(ms){
	return new Promise((resolve)=>{setTimeout(resolve,ms);})
}
async function test(){
	var temple=await sleep(1000);
	return temple;
}
test();

(3) generate

function* sleep(ms){
	yield new Promise((resolve,reject)=>{
		setTimeout(resolve,ms);
	});
}
sleep(500).next().value.then(()=>{
	console.log('do something');
})

4.请你讲一下,实现JS所有对象的深度克隆(包括Date对象,包装对象,正则对象的方法是什么),特点是什么?

(1)递归实现克隆:
可以实现对象,数组的克隆,但是不能实现包括Date对象,包装对象,正则对象的克隆。

function deepClone(obj){
    var newObj= obj instanceof Array?[]:{};
    for(var i in obj){
       newObj[i]=typeof obj[i]=='object'?  
       deepClone(obj[i]):obj[i];    
    }
    return newObj;
}

(2)JSON实现

var deepCopy=obj=>JSON.parse(JSON.stringify(obj));

(3)包装实现克隆:
适用于Number,Boolean,String对象

function baseClone(base){
   return base.valueOf();
}

所有对象都有valueOf方法,valueOf方法对于:如果存在任意原始值,它就默认将对象转换为表示它的原始>值。对象是复合值,而且大多数对象无法真正表示为一个原始值,因此默认的valueOf()方法简单地返回对象>本身,而不是返回一个原始值。数组、函数和正则表达式简单地继承了这个默认方法,调用这些类型的实例>的valueOf()方法只是简单返回这个对象本身。
对于包装对象完全可以用=实现克隆且不存在克隆这一说法。

(4)Date对象的克隆

Date.prototype.clone=function(){
  return new Date(this.valueOf());
}

(5)正则对象的克隆

RegExp.prototype.clone = function() {
    var pattern = this.valueOf();
    var flags = '';
    flags += pattern.global ? 'g' : '';
    flags += pattern.ignoreCase ? 'i' : '';
    flags += pattern.multiline ? 'm' : '';
    return new RegExp(pattern.source, flags);
};

5.自己实现一个bind函数?

使用该方法需要深入理解call,apply的用法和区别。

if (!Function.prototype.bind) {
    Function.prototype.bind = function () {
        var self = this,                        // 保存原函数
        context = [].shift.call(arguments), // 保存需要绑定的this上下文
        args = [].slice.call(arguments);    // 剩余的参数转为数组
        return function () {                    // 返回一个新函数
            self.apply(context,[].concat.call(args, [].slice.call(arguments)));
        }
    }
}

6.请你讲一下,使用setTimeout()方法来模拟setInterval()与直接使用setInterval()有什么区别?

答:使用setTimeout()方法需要写一个函数A,再写一个setTimeou 在时间后执行之前的函数A,函数里边会再次调用之前的函数A形成无限循环就可以达到效果了,函数A必须先执行一次,否则会有延迟;或者使用链式调用的方法;使用setInterval()相对简单很多。参考:
https://www.cnblogs.com/youxin/p/3943549.html

7.谈谈你对get请求传参长度的理解?

(1) 首先即使有长度限制,也是限制的是整个 URI 长度,而不仅仅是你的参数值数据长度。
(2) HTTP 协议从未规定 GET/POST 的请求长度限制是多少。
(3) 所谓的请求长度限制是由浏览器和 web 服务器决定和设置的,各种浏览器和 web 服务器的设定:

  • IE 和 Safari 浏览器 限制 2k
  • Opera 限制4k
  • Firefox 限制 8k(非常老的版本 256byte)

参考:https://www.jianshu.com/p/512389822f8b

8.讲一下你对get和post请求在缓存方面的区别和理解?

1.get和post请求
HTTP定义了客户端与服务器交互的不同方法,最基本的方法是GET和POST方法。
两种请求区别如下:
(1)安全性问题:在客户端,GET方式在地址栏中可以被看到,POST方式放在HTTP请求内容中提交,不能被看到;
(2)GET方式提交的数据最多只能有1024字节,而POST没有限制;
(3)GET是从服务器上获取数据,POST是向服务器传送数据;
(4)GET和POST在HTTP中传送的方式不同,GET的参数是在HTTP的头部传送的,而POST的数据则是在HTTP请求的内容里传送;
(5)GET请求能够被缓存,POST请求不能被缓存下来。
2.缓存
HTTP缓存的基本目的就是使应用执行的更快,更易扩展,但是HTTP缓存通常只适用于idempotent request(也可以理解为查询请求,也就是不断更新服务端数据的请求),这也就导致了HTTP的世界中,一般都是对GET请求做缓存,POST请求很少有缓存。
GET多用来直接获取数据,不修改数据,主要目的就是查询语句,用缓存的目的就是使查询的速度变快;
POST则是发送数据到服务器端去存储,类似数据库中增删改操作,更新数据库,数据必须放在数据库中,一般都得去访问服务。

9.请用一句话概括以下你对闭包的理解?

答: 在父函数里面定义一个子函数,使得子函数可以访问或操作父函数的变量。

10.请简要介绍一下解决回调地狱的方法?

答:使用promise,async await,generator等新特性。

猜你喜欢

转载自blog.csdn.net/qq_32013641/article/details/86742437
今日推荐