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.*****闭包:希望保护一个可以【反复使用的局部变量】的一种词法结构,其实函数一个函数,写法和以后有点不一样
何时使用:希望保护一个可以【反复使用的局部变量】
如何使用:4步
1、两个函数相互嵌套
2、外层函数创建出受保护的变量
3、外层函数要return返回内层函数
4、内层函数要操作受保护的变量
强调:
1、判断是不是闭包,有没有两个函数嵌套,返回内层函数,内层函数在操作受保护的变量
2、外层函数调用了几次,就创建了几个闭包,受保护的变量就有了几个副本
3、同一次外层函数调用,返回的内层函数,都是在操作同一个受保护的变量
缺点:受保护的变量,永远不会被释放,使用过多,造成内存泄漏
使用场景:防抖节流 - 有三个事件需要做防抖节流:执行的速度非常的快,减少DOM树的渲染
1、elem.onmousemove - 鼠标移动事件
2、input.oninput - 输入内容有变化就会触发
3、window.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.prototype:
Array.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?
1、HTML - 网页
2、XHTML - 更严格的网页
3、DHTML - Dynamic:动态的网页,其实并不是新技术,也不是新概念,而是现有技术的一个整合统称:让我们的网页再离线版也能具有动态效果
DHTML:HTML+CSS+JS
4、XML - 全部自定义,数据格式:淘汰了:JSON数据格式
DOM:原本是可以操作一切结构化文档的 HTML 和 XML,后来为了方便各类开发者分为了3个方向
1、核心DOM:【无敌】,既可以操作HTML也可以操作XML
缺点:API比较繁琐,getAttribute/setAttribute()
2、HTML DOM:只能操作HTML,API简单:缺点:自定义的东西操作不了
3、XML DOM:只能操作XML - 不会学习他
开发建议:优先使用HTML DOM,HTML DOM实现不了再用核心DOM补充
15.面试题:getXXXX和queryXXXX的区别?
返回的结果不一样:
1、getXXXX:返回的是一个动态集合HTMLCollection
特点:每一次DOM树修改过后,js都会悄悄的再次查找元素,保证数据和页面对应,效率相对较低
2、queryXXX:返回的是一个静态集合Nodelist
特点:只管查找的一次找出来的结果,后续DOM树的修改,我们的数据也不会变化,效率相对较高
优点:1、查找简单
2、还支持forEach
BOM
16. 面试题:函数和循环和定时器,都可以反复执行代码,区别在哪里?- 时机
1、函数:要么程序员调用几次执行几次,要么用户触发几次执行几次
2、循环:几乎是一瞬间就完毕了
3、定时器:需要先等待一段时间才会执行