前端面经第二更(加更)

我的前言

  我的上一篇博客凉经记录了我的一面的几个问题,这几天我把二面的问题(顺序忘记了)也整理出来和大家分享分享,当然了,我只能分享我确定的问题,不会/不确定的问题希望大家在看到我的博客的时候给予解答。Thank you

1、手写ajax(原生js)
var xhr = new XMLHttpRequest();
		xhr.open('GET','http://a.html?name=1&age=20');
		//send方法,放在事件前后没有区别
		xhr.send();  //post请求的时候,send中放参数,get请求一般放在url地址中
		xhr.onreadystatechange(function(){
			if(xhr.status == 200 && xhr.readyState == 4){  //请求后,判断状态是否成功
				console.log(xhr.responseText);
			}
		})

  如果大家面试中遇到类似的问题,千万不要使用其他库,我刚开始使用的库,然后问我原生js咋写,写着写着就忘记单词了?,在看的时候一定要动手写写,防止眼高手低。。。
  在这里也顺便说一下里面的状态值:

  status: 是服务器返回的状态码,200代表响应成功,大家也要记着一些常用的状态码:200、301、302、304、307、400、401、403、404、500等一些常见的。

  readyState:
    0:(未初始化)还没有调用send()
    1:(载入)开始调用send(),发送内容
    2:(载入完成)send()发送完毕,开始解析内容
    3:(交互)正在解析内容
    4:(成功)解析完成,可以调用数据

2、get、post区别
  1. 参数区别:get请求参数放在url或Cookie,post的参数放在body中
  2. 安全问题:get的参数放在地址栏中,可见相对post来说不太安全,post参数页面上不可见。
  3. 长度问题:get的参数一般浏览器都会有限制,不宜过长
  4. 作用:get无副作用,一般用于关键字查找、数据查询;post有副作用,比如添加数据,操作了数据库改变了信息。
3、深拷贝问题

  这个问题我写过一篇博客,大家可以去看一下。我的那一篇博客写的拷贝都是js中的一些基本类型的数据,没有考虑到undefined、null等一些特殊的问题。如果要封装一个函数的话最好考虑一下,因为我写的时候面试官问这种情况怎样处理了。

function DeepCopy(obj){
	//判断一下类型
	if(!obj || typeof obj === 'undefined'){
		throw Error("err");
	}
	
    var res;
    if(Object.prototype.toString.call(obj)=='[object Array]'){    //判断传入参数是不是数组
        res = [];   //是数组的话定义为数组类型
        for(var i = 0;i<obj.length;i++){
            res[i] = DeepCopy(obj[i]);   //对其子元素再进行递归遍历
        }
    }else if(Object.prototype.toString.call(obj) == '[object Object]'){    //判断传入参数是不是对象
        res = {};
        for(var key in obj){
            res[key] = DeepCopy(obj[key]);
        }
    }else{
        return obj;
    }
    return res;
}

原文:https://blog.csdn.net/tang422622/article/details/87869707 
4、es6模块化和node(Common JS)中有什么区别

  要知道两者之间的区别,必须先要了解es6中Module是什么,Common JS又是什么,这样才能做一番评价,两者的区别读者自行搜索(一定要看),我在这就不细说了。

区别:

  • CommonJS 输出是值的拷贝,即原来模块中的值改变不会影响已经加载的该值,ES6静态分析,动态引用,输出的是值的引用,值改变,引用也改变,即原来模块中的值改变则该加载的值也改变
  • CommonJS 模块是运行时加载(只有运行到时才能得到这个对象),ES6 模块是编译时输出接口(只加载引入的方法)
  • CommonJS 加载的是整个模块,即将所有的接口全部加载进来,ES6 可以单独加载其中的某个接口(方法)
  • CommonJS this 指向当前模块,ES6 this 指向undefined(ES6模块采用严格模式,严格模式下this指向undefined)
  • CommonJS 模块输出的是一个值的拷贝,ES6 模块输出的是值的引用
5、浏览器事件循环机制(Event Loop)以及Promise()

  给了我一段代码,让我分析输出结果,代码我忘了,就给大家贴上类似的一题吧。

	async function async1() {
		  console.log("a");
		  //执行这一句后,await会让出当前线程,
		  //将后面的代码加到任务队列中,然后继续执行函数后面的同步代码
		  await  async2();
		  console.log("b");
	}
	async function async2() {
	 	 console.log( 'c');
	}
	console.log("d");
	setTimeout(function () {
	 	 console.log("e");
	},0);
	async1();
	new Promise(function (resolve) {
		  console.log("f");
		  resolve();
	}).then(function () {
		  console.log("g");    // then(console.log("g"))这种情况会立即执行,视为同步代码
	});
	console.log('h');

  答案是什么呢,什么呢 ?   输出:d a c f h g b e
  理解这题首先要知道浏览器的执行顺序是怎样的。一次弄懂Event Loop 分享这篇文章,写的很详细。浏览器将你的文件分为同步任务和异步任务,同步任务就按顺序直接执行,异步任务就会被放进任务队列中。
  其中又分为宏任务和微任务,执行顺序是这样的:js代码为宏任务会首先执行,等执行栈为空后,就会去任务队列中把所有的微任务全部执行,等到执行队列为空时再次执行下一个宏任务,这样循环执行。

6、页面首次加载时执行了什么事件

  这到题我没有答上来,只说了个load加载事件,然后就说不清啦,面试官一听不知道也没有继续往下问,也没有说说这题的思想(?),事后我查和搜索了各种资料,只找到了蛛丝马迹,如果有读者清楚,一定要告诉我哦 ?

  • load是等页面中DOM元素、css、js、图片等加载完成之后才执行的事件
  • DOMContentLoaded是DOM元素构建完成之后就执行的事件(jquery中封装)
7、居中方式、js数据类型(区别)
8、盒子模型、position的值以及区别
9、将类数组转为数组
  • Array.from()
  • Array.prototype.slice.call()
10、防抖和节流

  这个题目面试官不是直接问我这两个是什么意思,我发现越是大神越从小问题问你,然后看你会不会运用到知识,巧了,我就是那个不会运用的?,推荐个大神的一篇博客
  防抖: 有个特点是延时执行 就是带着前面的一起做,如果在我规定的时间内,又触发了新的,就从头开始计算时间,只关心用户的最后一次操作,比如搜索框输入时。
  节流: 是在规定的时间内触发,如果时间未到就不触发事件


  以上几个问题是我了解并整理的,还有几个问题我不是太了解的,我也贴出来让大家看看 希望会的童鞋一定一定要留言或者私信告诉我答案???

不清楚的问题(望解答)?
  1. ajax和服务器交互的过程
  2. 两中盒子模型怎样兼容??(我回答了个display:content-box,好像不对,是不是在文件开头声明 !DOCTYPE ?)
  3. absolut的父元素设置为static可以定位吗?为什么(肯定是不可以的,why??)更新:我理解的是:static是position的默认值,它会忽略top、bottom、left、right 这一些列的值,而定位就是根据这些值来计算位置的,所以子元素不能根据父元素设置了static的值进行定位。(个人理解,望解答?)
  4. 上一题中解决resizse频繁触发(应该用节流吧,resize()和scroll()差不多都应该使用节流吧)

  基本上也就这些知识了,和大家分享一下,共同进步?

会的一定要帮我解答哦!!!


第四题:使用节流
  对于窗口的滚动事件、onresize事件,可以使用节流,使用定时器让事件在规定的时间后触发这样不会频繁的触发时事件,影响页面的整体性能。

简单的代码:

var timer = null;
function throttle(){
    clearTimeout(timer);
    timer = setTimeout(function(){
        console.log('1')
    },500)
}

window.onresize = throttle;

加更加更

数组去重:(出现的频率超高)
  我已经把数组去重和数据的深拷贝给弄混了,我也是醉了,所以我在这里好好总结总结:

1、利用ES6的 set

let arr = [1,2,5,3,2,1,4,2,5];
let set = new Set(arr);//去重
Array.from(set); //转为数组,也可以利用扩展运算符(...)

2、利用 indexOf

let arr = [1,2,2,3,1,5];
let newarr=[];
for(let i = 0;i<arr.length;i++){
    if(newarr.indexOf(arr[i])==-1){
        newarr.push(arr[i]);
    }
}
console.log(newarr)

3、对象+数组

function unique(arr){
    let res = [];
    let obj = {};
    for(var i = 0;i<arr.length;i++){
        if(!obj[arr[i]]){
            obj[arr[i]] = true;  //随便赋值
            res.push(arr[i]);
        }
    }
    return res;
}

4、利用对象的key值不能重复(对象数组)

let arrs = [
	{name:1,age:12},
	{name:2,age:13},
	{name:3,age:11},
	{name:1,age:12},
]
function unique(arrs){
   let obj = {};
   let res = [];
   for(let i = 0;i<arrs.length;i++){
       obj[arrs[i].name] = arrs[i];
   }
   for(let key in obj){
       res.push(obj[key]);
   }
}

判断是不是空对象:

  1. JSON.stringify(obj) === “{}”
  2. Object.keys(obj) ===[]; //返回的是数组,判断是不是空数组
  3. Object.getOwnPropertyNames(obj) === []; //同上

从上一题引出的两题:

1、 Object.keys() 和 Object.getOwnPropertyNames() 的区别:
   两个方法返回值都是数组,不包含Symbol属性
   Object.keys() 是遍历对象自身所有 可枚举 的属性,可以遍历到原型上的值。
   而Object.getOwnPropertyNames()是遍历对象 无论是否可枚举

2、JSON的语法:

let obj = {
    a:123,
    b:null,
    c:undefined
}
JSON.parse(JSON.stringify(obj));// c不会输出

   JSON的语法值,可以是true/false、number、string、null、对象、数组。除此之外不能是其他类型的值(undefined、NaN、函数…)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值