总结一些前端js的知识,将笔记整理跟你们分享,有些知识会常常在前端面试的时候会问到,因此作个记录,但愿对你们有所帮助,若是有什么问题,能够指出,会积极修正。
若是你们喜欢,能够点赞或留言我再继续更新面试题~~~~,谢谢你们~~~javascript
一、前++、后++、区别?
var i=2 ; a = i++ //将i的值赋给a , 即a = i,以后再执行i = i + 1; 2 a = ++i //将i+1 的值赋给a,即a = i + 1 ,以后再执行i = i + 1; 3 console.log(a) 复制代码
【总结】:css
前++是先自加后计算、后++是后自加先计算html
1:前置++ 是将自身+1 后的值赋给变量,同时自身加1;前端
2:后置++ 是将自身的值赋给变量,以后自身再加1;java
二、JS 有哪些数据类型?
Js基本数据类型 undefined null boolean number string bigint
Js引用类型 object Array function
ES6基本数据类型 多了个symboljquery
三、js判断类型?
一、typeof
检测不出null 和 数组,结果都为object,因此typeof经常使用于检测基本类型
二、instanceof
不能检测出number、boolean、string、undefined、null、symbol类型,因此instancof经常使用于检测复杂类型以及级成关系
三、constructor
null、undefined没有construstor方法,所以constructor不能判断undefined和null。可是contructor的指向是能够被改变,因此不安全
四、Object.prototype.toString.call
全类型均可以判断git
四、数据类型怎么检测?
1、typeof 例:console.log(typeof true) // boolean 2、instanceof 例:console.log([1,2] instanceof Array) // true 3、constructor 例: console.log([1, 2].constructor === Array) // ture 四、Object.prototype.toString.call 例:Object.prototype.toString.call([1, 2]) // [object Array] 复制代码
五、Js数组的方法
join()数组转换成字符串
push()尾部添加
pop()尾部删除
shift() 头部删除
unshift() 头部添加
sort()排序
reverse()反转
concat()连接两个或多个数组
slice()
var arr=[1,2,3,4,5]
console.log(arr.slice(1)) //[2,3,4,5]选择序列号从1到最后的全部元素组成的新数组
console.log(arr.slice(1,3)) //[2,3]不包含序列号,序号为3的元素
splice()
splice(index,howmany,item1,...itemx)
index参数:必须,整数,规定添加或删除的位置,使用负数,从数组尾部规定位置
howmany参数:必须,要删除的数量,若是为0则不删除项目
item1,...itemx参数:可选,向数组添加的新项目
var arr=[1,2,3,4,5]
console.log(arr.splice(2,1,"hello"));//[3]返回的新数组
console.log(arr);//[1,2,"hello",4,5]
indexOf()和 lastIndexOf() (ES5新增)
forEach() (ES5新增)
map() (ES5新增)
filter() (ES5新增)
every() (ES5新增)
some() (ES5新增)
reduce()和 reduceRight() (ES5新增)程序员
六、JS中的Array.splice()和Array.slice()方法有什么区别?
话很少说,来看第一个例子:es6
var arr=[0,1,2,3,4,5,6,7,8,9];//设置一个数组 console.log(arr.slice(2,7));//2,3,4,5,6 console.log(arr.splice(2,7));//2,3,4,5,6,7,8 //由此咱们简单推测数量两个函数参数的意义, slice(start,end)第一个参数表示开始位置,第二个表示截取到的位置(不包含该位置) splice(start,length)第一个参数开始位置,第二个参数截取长度 复制代码
接着看第二个:github
var x=y=[0,1,2,3,4,5,6,7,8,9] console.log(x.slice(2,5));//2,3,4 console.log(x);[0,1,2,3,4,5,6,7,8,9]原数组并未改变 //接下来用一样方式测试splice console.log(y.splice(2,5));//2,3,4,5,6 console.log(y);//[0,1,7,8,9]显示原数组中的数值被剔除掉了 复制代码
slice和splice虽然都是对于数组对象进行截取,可是两者仍是存在明显区别,函数参数上slice和splice第一个参数都是截取开始位置,slice第二个参数是截取的结束位置(不包含),而splice第二个参数(表示这个从开始位置截取的长度),slice不会对原数组产生变化,而splice会直接剔除原数组中的截取数据!
slice不会改变原数组,splice会改变原数组
七、数值转换
JSON.parse() 转json对象
JSON.stringify() 转json字符串
String(),toString() 转字符串类型
Number parseInt()字符串转数值类型
split 字符串转数组
join 数组转字符串
八、什么是跨域,常见跨域
因为浏览器获取数据遵循同源策略,因此当访问非同源资源的时候,就须要跨域,常见的跨域方式有jsonp,a img src cors
同源策略:同协议,端口,域名的安全策略
jsonp原理
动态建立script标签,利用callpack回调函数获取值
function callbackFunction(){ alert("回滚"); } var script=document.createElement("script"); script.src="http://frergeoip.net.json/?callback=callbackFunction"; 复制代码
CORS的原理:
当传输数据量比较大,get形式搞不定的时候,能够用到cors跨域,cors原理是定义一种跨域访问的机制,可让ajax实现跨域访问。Cors容许一个域上的网络应用向另外一个域提交跨域ajax请求。实现此功能很是简单,只需由服务器发送一个响应标头便可。 Jsonp是get形式,承载的信息量有限,因此信息量较大的时cors是不二选择。
九、http协议:
http协议是定义服务器端和客户端之间文件传输的沟通方式
请求服务器上的资源,请求html css js 图片文件等
请求方法(全部方法全为大写)有多种,各个方法的解释以下:
GET (get) 请求获取Request-URI所标识的资源 --获取资源
POST (post) 在Request-URI所标识的资源后附加新的数据 ---传输资源
HEAD (head) 请求获取由Request-URI所标识的资源的响应消息报头 ---获取报文首部
PUT (put) 请求服务器存储一个资源,并用Request-URI做为其标识 ---更新资源
DELETE (delete) 请求服务器删除Request-URI所标识的资源 ---删除资源
TRACE (trace) 请求服务器回送收到的请求信息,主要用于测试或诊断
CONNECT(connect) 保留未来使用
OPTIONS(options) 请求查询服务器的性能,或者查询与资源相关的选项和需求
常见状态码:
200 请求成功
301 资源(网页等)被永久转移到其余url
404 请求的资源不存在
500 内部服务器错误
十、HTTP状态码
100 Continue 继续,通常在发送post请求时,已发送了http header以后服务端将返回此信息,表示确认,以后发送具体参数信息
200 OK 正常返回信息
201 Created 请求成功而且服务器建立了新的资源
202 Accepted 服务器已接受请求,但还没有处理
301 Moved Permanently 请求的网页已永久移动到新位置。
302 Found 临时性重定向。
303 See Other 临时性重定向,且老是使用 GET 请求新的 URI。
304 Not Modified 自从上次请求后,请求的网页未修改过。
400 Bad Request 服务器没法理解请求的格式,客户端不该当尝试再次使用相同的内容发起请求。
401 Unauthorized 请求未受权。
403 Forbidden 禁止访问。
404 Not Found 找不到如何与 URI 相匹配的资源。
500 Internal Server Error 最多见的服务器端错误。
503 Service Unavailable 服务器端暂时没法处理请求(多是过载或维护)。
十一、说说你对闭包的理解?
使用闭包主要是为了设计私有的方法和变量。闭包的优势是能够避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易形成内存泄露。
闭包有三个特性:
1.函数嵌套函数
2.函数内部能够引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
闭包用途
1缓存
设想咱们有一个处理过程很耗时的函数对象,每次调用都会花费很长时间,那么咱们就须要将计算出来的值存储起来,当调用这个函数的时候,首先在缓存中查找,若是找不到,则进行计算,而后更新缓存并返回值,若是找到了,直接返回查找到的值便可。闭包正是能够作到这一点,由于它不会释放外部的引用,从而函数内部的值能够得以保留。
2 实现封装
能够先来看一个关于封装的例子,在person以外的地方没法访问其内部的变量,而经过提供闭包的形式来访问:
var person = function(){ //变量做用域为函数内部,外部没法访问 var name = "default"; return { getName : function(){ return name; }, setName : function(newName){ name = newName; } } }(); print(person.name);//直接访问,结果为undefined print(person.getName()); person.setName("abruzzi"); print(person.getName()); 复制代码
十二、如何阻止事件冒泡?
ie:阻止冒泡ev.cancelBubble = true;
非IE ev.stopPropagation();
1三、如何阻止默认事件?
(1)return false;(2) ev.preventDefault();
1四、事件代理
事件代理是指,对父盒子绑定事件,而后子盒子触发事件,因为产生事件冒泡,致使父盒子事件也被触发,此时,在父盒子的时间处理函数中,能够经过srcElement或者target属性来获取目标时间,并对其进行相应的处理
1五、添加 删除 替换 插入到某个节点的方法?
1)建立新节点 createElement() //建立一个具体的元素 createTextNode() //建立一个文本节点 2)添加、移除、替换、插入 appendChild() //添加 removeChild() //移除 replaceChild() //替换 insertBefore() //插入 3)查找 getElementsByTagName() //经过标签名称 getElementsByName() //经过元素的Name属性的值 getElementById() //经过元素Id,惟一性 复制代码
1六、document load 和document ready的区别?
document.onload 是在结构和样式,外部js以及图片加载完才执行js
document.ready是dom树建立完成就执行的方法,原生种没有这个方法,jquery中有 $().ready(function)
1七、Javascript的事件流模型都有什么?
“事件捕捉”:是从上往下,window,document,document.documentelment(获取的html) document,body 、……..目标元素
“事件冒泡”:是从下往上:反之
“DOM事件流”:三个阶段:事件捕捉、目标阶段、事件冒泡
Dom事件类:
Dom0 element.onclick=function(){} DOM2 element.addEventlistener(‘click’,function(){},flase) DOM3 element.addEventlistener(‘keyup’,function(){},flase) Event.preventdefault() 阻止默认事件 Event.stoppropagation() 阻止冒泡 Event.currenTtarget()事件代理 Event.target 当前被点击元素 复制代码
1八、null和undefined的区别?
null是一个表示"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。
当声明的变量还未被初始化时,变量的默认值为undefined。 null用来表示还没有存在的对象,经常使用来表示函数企图返回一个不存在的对象。
1九、call() 和 .apply() 的区别和做用?
相同点:两个方法产生的做用是彻底同样的,都是改变this指向的
不一样点:方法传递的参数不一样
Object.call(this,obj1,obj2,obj3)
Object.apply(this,arguments)
Apply()接收两个参数,一个是函数运行的做用域(this),另外一个是参数数组。
Call()方法的第一个参数与apply()相同,但传递的参数必须列举出来。
20、mvc和mvvm模式原理:
2一、JS为何要区分微任务和宏任务?
(1)js是单线程的,可是分同步异步
(2)微任务和宏任务皆为异步任务,它们都属于一个队列
(3)宏任务通常是:script,setTimeout,setInterval、setImmediate
(4)微任务:原生Promise
(5)遇到微任务,先执行微任务,执行完后若是没有微任务,就执行下一个宏任务,若是有微任务,就按顺序一个一个执行微任务
2二、setTimeout和setInterval
//setTimeout是3秒后执行 setTimeout(function(){ alert(123) },3000) //setInterval是每隔三秒执行一次,不断的重复执行 setInterval(function(){ alert(1121222) },3000) //两个执行都是异步进行的 复制代码
2三、深拷贝浅拷贝
深拷贝和浅拷贝最根本的区别在因而否真正获取一个对象的复制实体,而不是引用。
假设B复制了A,修改A的时候,看B是否发生变化:
若是B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)
若是B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不一样的值)
浅拷贝实现:
var a = [1, 2, 3, 4, 5]; var b = a; a[0] = 2 console.log(a);//[2,2,3,4,5] console.log(b);//[2,2,3,4,5] ////b会随着a的变化而变化 复制代码
深拷贝实现:
var a = [{"name":"weifeng"},{"name":"boy"}]; var a_copy =[].concat(JSON.parse(JSON.stringify(a)));//深拷贝 a_copy[1].name = "girl" console.log(a);//[{"name":"weifeng"},{"name":"boy"}] console.log(a_copy );//[{"name":"weifeng"},{"name":"girl"}] 复制代码
2四、重排重绘
回流(重排):
当render tree中的一部分(或所有)由于元素的规模尺寸,布局,隐藏等改变而须要从新构建。这就称为回流(reflow)。每一个页面至少须要一次回流,就是在页面第一次加载的时候,这时候是必定会发生回流的,由于要构建render tree。在回流的时候,浏览器会使渲染树中受到影响的部分失效,并从新构造这部分渲染树,完成回流后,浏览器会从新绘制受影响的部分到屏幕中,该过程成为重绘。
重绘:
当render tree中的一些元素须要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,好比background-color。则就叫称为重绘。
区别:
回流必将引发重绘,而重绘不必定会引发回流。好比:只有颜色改变的时候就只会发生重绘而不会引发回流 当页面布局和几何属性改变时就须要回流 好比:添加或者删除可见的DOM元素,元素位置改变,元素尺寸改变——边距、填充、边框、宽度和高度,内容改变。
2五、防抖和节流?
在前端开发的过程当中,咱们常常会须要绑定一些持续触发的事件,如 resize、scroll、mousemove keyup 等等,但有些时候咱们并不但愿在事件持续触发的过程当中那么频繁地去执行函数。
一般这种状况下咱们怎么去解决的呢?通常来说,防抖和节流是比较好的解决方案。
一、防抖:
指触发事件后在n秒后函数执行,若是在n秒内又触发了事件,则会从新计算函数执行时间。应用场景(适合屡次事件只响应一次的状况):给按钮加防抖函数防止表单屡次提交;判断scroll是否滑到底部;对于输入框连续输入进行AJAX验证时,用函数防抖能有效减小请求次数。
现给一个场景:现监听一个输入框,文字变化后触发change事件。若直接用keyup事件,则会频繁触发change事件。加了防抖后,用户输入结束或暂停时,才会触发change事件。
所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,若是在 n 秒内又触发了事件,则会从新计算函数执行时间。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <input type="text" id="input1"> </body> <script> const input1 = document.getElementById('input1') //一、不加防抖 ,会一直触发change事件 input1.addEventListener('keyup', function(){ console.log(input1.value) }) //二、简单实现防抖 let timer = null input1.addEventListener('keyup', function(){ if(timer){ clearTimeout(timer) } timer = setTimeout(() => { //模拟触发change事件 console.log(input1.value) //清空定时器 timer = null }, 1000) }) //三、将防抖函数这个工具进行封装 function debounce(fn, delay = 50){ //timer是闭包中的,不能被别人修改 let timer = null return function(){ if(timer){ clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, arguments) timer = null }, delay) } } input1.addEventListener('keyup', debounce(function(){ console.log(input1.value) }, 600)) </script> </html> 复制代码
则封装后的防抖函数为:
function debounce(fn, delay = 50){ let timer = null //timer是闭包中的,不能被别人修改 return function(){ if(timer){ clearTimeout(timer) } timer = setTimeout(() => { fn.apply(this, arguments) timer = null }, delay) } } 复制代码
二、节流:
连续发送的事件在n秒内只执行一次函数。应用场景(适合大量事件按时间作平均分配触发):DOM元素拖拽;Canvas画笔功能。
现给一个场景:拖拽一个元素,要随时拿到该元素被拖拽的位置。若直接用drag事件,则会频繁触发,很容易致使卡顿。加了节流后,不管拖拽速度多快,都会每隔固定时间触发一次。
所谓节流,就是指连续触发事件可是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> #div1{ border: 1px solid #ccc; width: 200px; height: 100px; } </style> </head> <body> <div id = "div1" draggable="true">可拖拽</div> <script> const div1 = document.getElementById('div1') //一、简单实现节流 let timer = null div1.addEventListener('drag', function(e){ if(timer){ return } timer = setTimeout(() => { console.log(e.offsetX, e.offsetY) timer = null //定时器执行了,才让timer为空 }, 1000) }) //二、将节流函数这个工具进行封装 function throttle(fn, delay = 100){ let timer = null return function(){ if(timer){ return } timer = setTimeout(() => { fn.apply(this, arguments) timer = null },delay) } } div1.addEventListener('drag', throttle(function(e){ //形参e会传给throttle函数运行后返回的函数 console.log(e.offsetX, e.offsetY) },200)) </script> </body> </html> 复制代码
则封装后的节流函数为:
function throttle(fn, delay = 100){ let timer = null return function(){ if(timer){ return } timer = setTimeout(() => { fn.apply(this, arguments) timer = null },delay) } } 复制代码
2六、一个页面从输入 URL 到页面加载显示完成,这个过程当中都发生了什么?
分为4个步骤:
(1),当发送一个URL请求时,无论这个URL是Web页面的URL仍是Web页面上每一个资源的URL,浏览器都会开启一个线程来处理这个请求,同时在远程DNS服务器上启动一个DNS查询。这能使浏览器得到请求对应的IP地址。
(2), 浏览器与远程Web服务器经过TCP三次握手协商来创建一个TCP/IP链接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试创建起通讯,然后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。
(3),一旦TCP/IP链接创建,浏览器会经过该链接向远程服务器发送HTTP的GET请求。远程服务器找到资源并使用HTTP响应返回该资源,值为200的HTTP响应状态表示一个正确的响应。
(4),此时,Web服务器提供资源服务,客户端开始下载资源。
请求返回后,便进入了咱们关注的前端模块
简单来讲,浏览器会解析HTML生成DOM Tree,其次会根据CSS生成CSS Rule Tree,而javascript又能够根据DOM API操做DOM
详情:从输入 URL 到浏览器接收的过程当中发生了什么事情?
2七、说说TCP传输的三次握手策略
为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。用TCP协议把数据包送出去后,TCP不会对传送 后的状况置之不理,它必定会向对方确认是否成功送达。握手过程当中使用了TCP的标志:SYN和ACK。 发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。最后,发送端再回传一个带ACK标志的数据包,表明“握手”结束 若在握手过程当中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。
2八、说说你对语义化的理解?
1,去掉或者丢失样式的时候可以让页面呈现出清晰的结构
2,有利于SEO:和搜索引擎创建良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来肯定上下文和各个关键字的权重;
3,方便其余设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页;
4,便于团队开发和维护,语义化更具可读性,是下一步吧网页的重要动向,遵循W3C标准的团队都遵循这个标准,能够减小差别化
2九、你如何对网站的文件和资源进行优化?
期待的解决方案包括:
文件合并
文件最小化/文件压缩
使用 CDN 托管
缓存的使用(多个域名来提供缓存)
其余
30、请说出三种减小页面加载时间的方法?
一、压缩css、js文件
二、合并js、css文件,减小http请求
三、外部js、css文件放在最底下
四、减小dom操做,尽量用变量替代没必要要的dom操做
3一、js延迟加载的方式有哪些?
defer和async、动态建立DOM方式(建立script,插入到DOM中,加载完毕后callBack)、按需异步载入js
3二、你有哪些性能优化的方法?
(详情请看雅虎14条性能优化原则)。
(1) 减小http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,CDN托管,data缓存 ,图片服务器。
(2) 前端模板 JS+数据,减小因为HTML标签致使的带宽浪费,前端用变量保存AJAX请求结果,每次操做本地变量,不用请求,减小请求次数
(3) 用innerHTML代替DOM操做,减小DOM操做次数,优化javascript性能。
(4) 当须要设置的样式不少时设置className而不是直接操做style。
(5) 少用全局变量、缓存DOM节点查找的结果。减小IO读取操做。
(6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。
(7) 图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳。
3三、异步加载和延迟加载
1.异步加载的方案: 动态插入script标签
2.经过ajax去获取js代码,而后经过eval执行
3.script标签上添加defer或者async属性
4.建立并插入iframe,让它异步执行js
5.延迟加载:有些 js 代码并非页面初始化的时候就马上须要的,而稍后的某些状况才须要的。
3四、GET和POST的区别,什么时候使用POST?
GET:通常用于信息获取,使用URL传递参数,对所发送信息的数量也有限制,通常在2000个字符
POST:通常用于修改服务器上的资源,对所发送的信息没有限制。
GET方式须要使用Request.QueryString来取得变量的值,而POST方式经过Request.Form来获取变量的值,也就是说Get是经过地址栏来传值,而Post是经过提交表单来传值。
然而,在如下状况中,请使用 POST 请求:
没法使用缓存文件(更新服务器上的文件或数据库)
向服务器发送大量数据(POST 没有数据量限制)
发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
3五、平时如何管理你的项目?
先期团队必须肯定好全局样式(globe.css),编码模式(utf-8) 等;
编写习惯必须一致(例如都是采用继承式的写法,单样式都写成一行);
标注样式编写人,各模块都及时标注(标注关键样式调用的地方);
页面进行标注(例如 页面 模块 开始和结束);
CSS跟HTML 分文件夹并行存放,命名都得统一(例如style.css);
JS 分文件夹存放 命名以该JS功能为准的英文翻译。
3六、你如何优化本身的代码?
代码重用
避免全局变量(命名空间,封闭空间,模块化mvc…)
拆分函数避免函数过于臃肿
注释
3七、什么是 FOUC(无样式内容闪烁)?你如何来避免 FOUC?
FOUC - Flash Of Unstyled Content 文档样式闪烁
<style type="text/css" media="all">@import "../fouc.css";</style>
复制代码
而引用CSS文件的@import就是形成这个问题的罪魁祸首。IE会先加载整个HTML文档的DOM,而后再去导入外部的CSS文件,所以,在页面DOM加载完成到CSS导入完成中间会有一段时间页面上的内容是没有样式的,这段时间的长短跟网速,电脑速度都有关系。
解决方法简单的出奇,只要在<head>之间加入一个<link>或者<script>元素就能够了。
复制代码
3八、网站重构的理解?
网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。也就是说是在不改变UI的状况下,对网站进行优化,在扩展的同时保持一致的UI。
对于传统的网站来讲重构一般是:
表格(table)布局改成DIV+CSS
使网站前端兼容于现代浏览器(针对于不合规范的CSS、如对IE6有效的)
对于移动平台的优化
针对于SEO进行优化
深层次的网站重构应该考虑的方面
减小代码间的耦合
让代码保持弹性
严格按规范编写代码
设计可扩展的API
代替旧有的框架、语言(如VB)
加强用户体验
一般来讲对于速度的优化也包含在重构中
压缩JS、CSS、image等前端资源(一般是由服务器来解决)
程序的性能优化(如数据读写)
采用CDN来加速资源加载
对于JS DOM的优化
HTTP服务器的文件缓存
3九、什么叫优雅降级和渐进加强?
优雅降级:Web站点在全部新式浏览器中都能正常工做,若是用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工做。因为IE独特的盒模型布局问题,针对不一样版本的IE的hack实践过优雅降级了,为那些没法支持功能的浏览器增长候选方案,使之在旧式浏览器上以某种形式降级体验却不至于彻底失效.
渐进加强:从被全部浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面增长无害于基础浏览器的额外样
40、栈和队列的区别?
栈的插入和删除操做都是在一端进行的,而队列的操做倒是在两端进行的。
队列先进先出,栈先进后出。
栈只容许在表尾一端进行插入和删除,而队列只容许在表尾一端进行插入,在表头一端进行删除
4一、栈和堆的区别?
栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
堆区(heap) — 通常由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。
堆(数据结构):堆能够被当作是一棵树,如:堆排序;
栈(数据结构):一种先进后出的数据结构。
4二、对前端界面工程师这个职位是怎么样理解的?它的前景会怎么样?
前端是最贴近用户的程序员,比后端、数据库、产品经理、运营、安全都近。
一、实现界面交互
二、提高用户体验
三、有了Node.js,前端能够实现服务端的一些事情
前端是最贴近用户的程序员,前端的能力就是能让产品从 90分进化到 100 分,甚至更好,
参与项目,快速高质量完成实现效果图,精确到1px;
与团队成员,UI设计,产品经理的沟通;
作好的页面结构,页面重构和用户体验;
处理hack,兼容、写出优美的代码格式;
针对服务器的优化、拥抱最新前端技术。
代码算法之类
4三、数组去重indexOf
var arr=[1,1,2,2,3,4,5,7,8,9,6,4,6,2,] var arr2=[] for(var i=0;i<arr.length;i++){ if(arr2.indexOf(arr[i])<0){ arr2.push(arr[i]) } } console.log(arr2) 复制代码
4四、es6方法数组去重
let a = [1,5,6,3,8,0,5,7,0,4,2,7,5,4,5,9,22] let b=new Set([...a]) console.log(b); b=[...b]; console.log(b) 复制代码
4五、冒泡排序
var arr=[1,3,4,6,8,0,2,5,7,4,9,2]; var temp=0; for (var i=0;i<arr.length;i++) { for(var j=0;j<arr.length-i;j++){ if(arr[j]<arr[j+1]){ temp=arr[j+1]; arr[j+1]=arr[j]; arr[j]=temp; } } } console.log(arr) 复制代码
4六、获取url中的参数
//测试地址:http://www.runobb.com/jqur/dfev.html?name=xiaohong&age=22 function showWindowHref(){ var sHref=window.location.href; var args=sHref.split('?'); if(args[1]==sHref){ return ''; } var aa=args[1].split('&'); var obj={} for (var i=0;i<aa.length;i++) { var bb=aa[i].split('=') obj[bb[0]]=bb[1] } return obj; } 复制代码
4七、降维数组
//利用[].concat.apply实现降维 var arr=[[1,2],[3,4]]; function Jw(obj){ console.log(Array.prototype.concat.apply([],obj)) return Array.prototype.concat.apply([],obj); } Jw(arr); //若是concat方法的参数是一个元素,该元素会直接插入新数组中;若是参数是一个数组,该数组的各个元素将被插入到新数组中 function reduceDimension(arr){ let ret = []; for(let i=0;i<arr.length;i++){ ret=ret.concat(arr[i]) } console.log(ret) return ret; } reduceDimension(arr) //递归 function reduceDimension(arr){ let ret = []; let toArr = function(arr){ arr.forEach(function(item){ item instanceof Array ? toArr(item) : ret.push(item); }); } toArr(arr); console.log(ret) return ret; } reduceDimension([1, 2, [3, 4, [5, 6]]]) //flat let list = [1, 2, 3, [4, [5]]]; let res = list.flat(Infinity) console.log(res) // [1, 2, 3, 4, 5] 复制代码
4八、js判断一个字符串中出现次数最多的字符,统计这个次数
var str = 'asdfssaaasasasasaa'; var json = {}; for (var i = 0; i < str.length; i++) { if(!json[str.charAt(i)]){ json[str.charAt(i)] = 1; }else{ json[str.charAt(i)]++; } }; var iMax = 0; var iIndex = ''; for(var i in json){ if(json[i]>iMax){ iMax = json[i]; iIndex = i; } } console.log('出现次数最多的是:'+iIndex+'出现'+iMax+'次'); //出现次数最多的是:a出现 9次 复制代码
let string = 'kapilalipak'; const table={}; for(let char of string) { table[char]=table[char]+1 || 1; } // 输出 console.log(table)// {k: 2, a: 3, p: 2, i: 2, l: 2} 复制代码
4九、写一个function,清除字符串先后的空格。(兼容全部浏览器)
function trim(str) { if (str & typeof str === "string") { return str.replace(/(^s*)|(s*)$/g,""); //去除先后空白符 } } 复制代码
50、如何用jquery禁用浏览器的先后进退按钮?
<script type="text/javascript" language="javascript"> $(document).ready(function() { window.history.forward(1); //OR window.history.forward(-1); }); </script> 复制代码
获取页面中全部的checkbox怎么作?(不使用第三方框架)
var inputs = document.getElementsByTagName("input");//获取全部的input标签对象 var checkboxArray = [];//初始化空数组,用来存放checkbox对象。 for(var i=0;i<inputs.length;i++){ var obj = inputs[i]; if(obj.type=='checkbox'){ checkboxArray.push(obj); } } 复制代码
5一、程序中捕获异常的方法?
try{ }catch(e){ }finally{ } 复制代码
5二、js排序
升序降序排序函数sortNumber
const arr1 = [6,1,2,3,4]; function sortNumber(a,b){ return b-a; } arr1.sort(sortNumber); console.log(arr1) // [6, 4, 3, 2, 1] 复制代码
按照flag排序,为true的在前面显示
const arr2 = [ { id: 10, flag: true }, { id: 5, flag: false }, { id: 6, flag: true }, { id: 9, flag: false } ]; const r = arr2.sort((a, b) => b.flag - a.flag); console.log(r); // [ // { id: 10, flag: true }, // { id: 6, flag: true }, // { id: 5, flag: false }, // { id: 9, flag: false } // ] 复制代码
喜欢的小伙伴点个赞吧,感受对身边人有帮助的,麻烦动动手指,分享一下。感谢各位花时间阅读完,同时也感谢各位的点赞和分享。