#鄙视面试题

162 阅读8分钟

1. 面试题:if vs switch

	1、switch:缺点:必须要知道最后的结果才能使用,不能做范围判断
		  优点:执行效率相对较高

	2、if         : 优点:可以做范围判断
		 缺点:执行效率相对较慢

	建议:代码优化:尽量的将if替换为switch或者三目或短路
            

2.面试题: while和do...while的区别?

	只看第一次,如果大家都满足,则没区别
		   如果不满足,while一次都不执行,而dowhile至少会执行一次
                       

3.鄙视时:给你一个数组,将他无缝拼接在一起:

*****arr 转为 str:

      1、语法:var str=arr.join("自定义连接符");
	作用:
	   1、**鄙视时**:给你一个数组,将他无缝拼接在一起:
		var arr=["h","e","l","l","o"];
		var str=arr.join("");
		console.log(str);  

4.Array API

鄙视题*****排序:

     鄙视时:不允许使用数组的API - 冒泡排序:拿着数组中的每一个元素,
	       让前一个和后一个做比较,如果前一个>后一个,两者应该交换位置:固定公式
		var arr=[32,14,43,453,6,58,56,531,5,57];
		for(var j=1;j<arr.length;j++){
			for(var i=0;i<arr.length-j;i++){
				if(arr[i]>arr[i+1]){
					var m=arr[i];
					arr[i]=arr[i+1];
					arr[i+1]=m;
				}
			}
		}
		console.log(arr);

5.检索字符串:检查索引:获取关键字的下标

笔试题:默认只能获取到第一个关键字的下标,如何才能获取到所有的关键字的下标

		var str="no zuo no die no can no bibi";
		var i=-1;
		while((i=str.indexOf("no",i+1))!=-1){
			console.log(i);
		}
                    
                    

6.*笔试题:要求不允许使用toFixed,自己封装出toFixed的操作

7.***函数的执行原理:

1、程序加载时  

     创建执行环境栈(ECS): 保存函数调用顺序的数组
     首先压入全局执行环境(全局EC)
     全局EC引用着全局对象window
     window中保存着全局变量

2、定义函数时
      创建函数对象:封装代码段
      在函数对象中有一个scope(作用域)属性:记录着函数来自的作用域是哪里
      全局函数的scope都是window

3、调用前
      在执行环境栈(ECS)压入新的EC(函数的EC)
      创建活动对象(AO):保存着本次函数调用时用到的局部变量
      在函数的EC中有一个scope chain(作用域链)属性引用AO
      AO有一个parent属性是函数的scope引用的对象

4、调用时
      正是因为有前面三步,我们才有了变量的使用规则:优先使用局部的,局部没有找全局,全局没有就报错

5、调用完:
      函数的EC会出栈,没人引用AO,AO自动释放,所以局部变量也就释放了

8.两链一包:

作用域链:以函数的EC中的scope chain属性为起点,经过AO,逐级引用,  
形成的一条链式结构,就称之为叫做作用域链
	作用:变量的使用规则,查找变量

9.*****闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构,其实函数一个函数,写法和以后有点不一样

何时使用:希望保护一个可以【反复使用的局部变量】
如何使用:41、两个函数相互嵌套
	2、外层函数创建出受保护的变量
	3、外层函数要return返回内层函数
	4、内层函数要操作受保护的变量

强调:
   1、判断是不是闭包,有没有两个函数嵌套,返回内层函数,内层函数在操作受保护的变量
   2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有了几个副本
   3、同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量

缺点:受保护的变量,永远不会被释放,使用过多,造成内存泄漏
使用场景:防抖节流 - 有三个事件需要做防抖节流:执行的速度非常的快,减少DOM树的渲染
	1、elem.onmousemove - 鼠标移动事件
	2、input.oninput            - 输入内容有变化就会触发
	3window.onresize	      - 当前窗口的尺寸如果发生了变化就会触发:JS版本的媒体查询
	公式:
		elem.on事件名=function(){
			inner();
		}
		function fdjl(){
			var timer=null;//1 2 3 - 定时器序号
			return function(){
				if(timer){clearTimeout(timer);timer=null}
				timer=setTimeout(function(){
					//操作
				},1000)
			}
		}		
		var inner=fdjl();

10.*面试题:两链一包:

	作用域链:查找变量
	闭包:保护一个可以反复使用的局部变量的一种词法结构
	原型链:每个对象都有一个属性:__proto__,可以一层一层的找到每个人的父亲,形成的一条链式结构,就称之为叫做原型链
	可以找到所有父对象的成员(属性和方法),作用:查找属性和【方法】
	最顶层是Object的原型,上面放着我们眼熟的toString,怪不得人人都可以使用toString
	JS种万物皆对象

11. 关于对象的笔试题

***笔试题1:判断自有和共有:

		1、判断自有:
			obj.hasOwnProperty("属性名");
				如果结果为true,说明一定是自有,如果结果为false,可能是共有可能是没有
		2、判断共有:
			if(obj.hasOwnProperty("属性名")==false&&"属性名" in obj){//in 会自动在整条圆形脸上进行查找,找到结果为true,找不到结果为false
				说明是共有
			}else{
				说明是没有
			}

		完整版公式:
			if(obj.hasOwnProperty("属性名")){
				自有
			}else{
				if("属性名" in obj){
					共有
				}else{
					没有
				}
			}

***笔试题2:修改/删除自有和共有

		自有:修改:obj.属性名=新值;
		           删除:delete obj.属性名;
		
		共有:修改:obj.__proto__.属性名=新值;
		           删除:delete obj.__proto__.属性名;

			共有千万不要操作本地:
				修改:会在本地添加同名属性
				删除:没有效果

***笔试题3:如何为老IE的数组添加indexOf方法:如何为一类人添加某个方法

		原理:
		if(Array.prototype.indexOf===undefined){//老IE
			Array.prototype.indexOf=function(key,starti){
				starti===undefined&&(starti=0);
				for(var i=starti;i<this.length;i++){
					if(key==this[i]){
						return i;
					}
				}
				return -1;
			}
		}

***笔试题4:判断x是不是一个数组:4种方式

		1、判断x是不是继承自Array.prototypeArray.prototype.isPrototypeOf(x);

		2、判断x是不是由Array这个构造函数创建的
			x instanceof Array

		3、只有数组可用:ES5提供的一个叫Array.isArray(x);

		4、最麻烦:输出【对象的字符串】形式
		     在Object的原型上保存着最原始的toString方法
		     最原始的toString方法输出:[object 构造函数名]
		     ***多态:子对象觉得父对象的成员不好用,在本地定义了同名成员,覆盖了父对象的成员
		     如果我们这道题能够跳过数组的爸爸,拿到数组的爷爷上面的toString也就能判断了
		     固定套路:借用:Object.prototype.toString.apply(x);
		

***笔试题5:实现自定义继承:

			1、两个对象之间的继承:
				子对象.__proto__=父对象
		
			2、多个对象之间设置继承:
				构造函数名.prototype=父对象
				注意时机:一定要在创建对象之前

12.面试题:严格模式:很严格

   开启:在你的任何作用域的顶部加上一句话:"use strict";
   功能:1、禁止给未声明的变量赋值 - 解决全局污染
         2、静默失败升级为报错
             

ES5&ES6

13*****call/apply/bind:

 不是自己的方法也可以使用 - 笔试面试也很容易碰到
   call/apply:临时替换了函数中的this - 借用
	语法:函数名.call(借用的对象,实参,...); - 单独传入每一个实参
	      函数名.apply(借用的对象,arr); - 只能传入一个实参是一个数组,apply其实会悄悄的将数组打散
	强调:call/apply,相当于立刻调用函数,立即执行

   bind:永久替换了函数中的this - 买
	3件事:
	1、创建了一个和原函数完全相同功能的新函数
	2、将新函数中的this永久绑定为了指定对象,别人都借不走了
	3、将新函数中的部分参数永久固定
	用法:var 新函数=原函数.bind(指定对象,永久实参,...) - 不是立刻执行的,需要自己调用
	强调:bind绑定的新函数没有办法被call/apply借走

   个人更推荐:call/apply,借,白嫖

   固定套路:
	1、Math.max/min.apply(Math,arr);
	2、Object.prototype.toString.call/apply(arr);
	3、***类数组转为普通数组:类数组名称=Array.prototype.slice.call/apply(类数组);  

DOM

14.## HTML/XHTML/DHTML/XML?

1HTML - 网页
2XHTML - 更严格的网页
3DHTML - Dynamic:动态的网页,其实并不是新技术,也不是新概念,而是现有技术的一个整合统称:让我们的网页再离线版也能具有动态效果
		DHTML:HTML+CSS+JS
4XML - 全部自定义,数据格式:淘汰了:JSON数据格式

  DOM:原本是可以操作一切结构化文档的 HTMLXML,后来为了方便各类开发者分为了3个方向
1、核心DOM:【无敌】,既可以操作HTML也可以操作XML
	         缺点:API比较繁琐,getAttribute/setAttribute()

2HTML DOM:只能操作HTMLAPI简单:缺点:自定义的东西操作不了

3XML DOM:只能操作XML - 不会学习他

开发建议:优先使用HTML DOMHTML DOM实现不了再用核心DOM补充
   

15.面试题:getXXXX和queryXXXX的区别?

	返回的结果不一样:
		1、getXXXX:返回的是一个动态集合HTMLCollection
			特点:每一次DOM树修改过后,js都会悄悄的再次查找元素,保证数据和页面对应,效率相对较低

		2、queryXXX:返回的是一个静态集合Nodelist
			特点:只管查找的一次找出来的结果,后续DOM树的修改,我们的数据也不会变化,效率相对较高
			优点:1、查找简单
			     2、还支持forEach

BOM

16. 面试题:函数和循环和定时器,都可以反复执行代码,区别在哪里?- 时机

	1、函数:要么程序员调用几次执行几次,要么用户触发几次执行几次
	2、循环:几乎是一瞬间就完毕了
	3、定时器:需要先等待一段时间才会执行