问题1、前++、后++、区别?
var i=2 ;a = i++ //将i的值赋给a , 即a = i,之后再执行i = i + 1; 2a = ++i //将i+1 的值赋给a,即a = i + 1 ,之后再执行i = i + 1; 3console.log(a)
【总结】:
前++是先自加后计算、后++是后自加先计算
1:前置++ 是将本身+1 后的值赋给变量,同时本身加1;
2:后置++ 是将本身的值赋给变量,之后本身再加1;
JS 有哪些数据类型?
Js罕用数据类型undefined null boolean number string
Js援用类型object Array function
ES6根本数据类型多了个symblo
js判断类型?
1、typeof
检测不出null 和 数组,后果都为object,所以typeof罕用于检测根本类型
2、instanceof
不能检测出number、boolean、string、undefined、null、symbol类型,所以instancof罕用于检测简单类型以及级成关系
3、constructor
null、undefined没有construstor办法,因而constructor不能判断undefined和null。然而contructor的指向是能够被扭转,所以不平安
4、Object.prototype.toString.call
全类型都能够判断
数据类型怎么检测
1、typeof例:console.log(typeof true) // boolean2、instanceof例:console.log([1,2] instanceof Array) // true3、constructor例: console.log([1, 2].constructor === Array) // ture4、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()办法有什么区别?
话不多说,来看第一个例子:
var arr=[0,1,2,3,4,5,6,7,8,9];//设置一个数组console.log(arr.slice(2,7));//2,3,4,5,6console.log(arr.splice(2,7));//2,3,4,5,6,7,8//由此咱们简略揣测数量两个函数参数的意义,slice(start,end)第一个参数示意开始地位,第二个示意截取到的地位(不蕴含该地位)splice(start,length)第一个参数开始地位,第二个参数截取长度
接着看第二个:
var x=y=[0,1,2,3,4,5,6,7,8,9]console.log(x.slice(2,5));//2,3,4console.log(x);[0,1,2,3,4,5,6,7,8,9]原数组并未扭转//接下来用同样形式测试spliceconsole.log(y.splice(2,5));//2,3,4,5,6console.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 外部服务器谬误
说说你对闭包的了解
应用闭包次要是为了设计公有的办法和变量。闭包的长处是能够防止全局变量的净化,毛病是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
闭包有三个个性:
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)return false;(2) ev.preventDefault();
增加 删除 替换 插入到某个节点的办法?
1)创立新节点createElement() //创立一个具体的元素createTextNode() //创立一个文本节点 2)增加、移除、替换、插入appendChild() //增加removeChild() //移除replaceChild() //替换insertBefore() //插入 3)查找getElementsByTagName() //通过标签名称getElementsByName() //通过元素的Name属性的值getElementById() //通过元素Id,唯一性
document load 和document ready的区别?
document.onload 是在构造和款式,内部js以及图片加载完才执行js
document.ready是dom树创立实现就执行的办法,原生种没有这个办法,jquery中有 $().ready(function)
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 以后被点击元素
null和undefined的区别?
null是一个示意"无"的对象,转为数值时为0;undefined是一个示意"无"的原始值,转为数值时为NaN。
当申明的变量还未被初始化时,变量的默认值为undefined。 null用来示意尚未存在的对象,罕用来示意函数希图返回一个不存在的对象。
js提早加载的形式有哪些?
defer和async、动态创建DOM形式(创立script,插入到DOM中,加载结束后callBack)、按需异步载入js
call() 和 .apply() 的区别和作用?
相同点:两个办法产生的作用是齐全一样的,都是扭转this指向的
不同点:办法传递的参数不同
Object.call(this,obj1,obj2,obj3)
Object.apply(this,arguments)
Apply()接管两个参数,一个是函数运行的作用域(this),另一个是参数数组。
Call()办法的第一个参数与apply()雷同,但传递的参数必须列举进去。
mvc和mvvm模式原理:
JS为什么要辨别微工作和宏工作?
(1)js是单线程的,然而分同步异步
(2)微工作和宏工作皆为异步工作,它们都属于一个队列
(3)宏工作个别是:script,setTimeout,setInterval、setImmediate
(4)微工作:原生Promise
(5)遇到微工作,先执行微工作,执行完后如果没有微工作,就执行下一个宏工作,如果有微工作,就按程序一个一个执行微工作
setTimeout和setInterval
//setTimeout是3秒后执行 setTimeout(function(){ alert(123) },3000)//setInterval是每隔三秒执行一次,一直的反复执行 setInterval(function(){ alert(1121222) },3000)//两个执行都是异步进行的
深拷贝浅拷贝
深拷贝和浅拷贝最基本的区别在于是否真正获取一个对象的复制实体,而不是援用。
假如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"}]
重排重绘
回流(重排):
当render tree中的一部分(或全副)因为元素的规模尺寸,布局,暗藏等扭转而须要从新构建。这就称为回流(reflow)。每个页面至多须要一次回流,就是在页面第一次加载的时候,这时候是肯定会产生回流的,因为要构建render tree。在回流的时候,浏览器会使渲染树中受到影响的局部生效,并从新结构这部分渲染树,实现回流后,浏览器会从新绘制受影响的局部到屏幕中,该过程成为重绘。
重绘:
当render tree中的一些元素须要更新属性,而这些属性只是影响元素的外观,格调,而不会影响布局的,比方background-color。则就叫称为重绘。
区别:
回流必将引起重绘,而重绘不肯定会引起回流。比方:只有色彩扭转的时候就只会产生重绘而不会引起回流
当页面布局和几何属性扭转时就须要回流
比方:增加或者删除可见的DOM元素,元素地位扭转,元素尺寸扭转——边距、填充、边框、宽度和高度,内容扭转。
防抖和节流?
在前端开发的过程中,咱们常常会须要绑定一些继续触发的事件,如 resize、scroll、mousemove keyup 等等,但有些时候咱们并不心愿在事件继续触发的过程中那么频繁地去执行函数。
通常这种状况下咱们怎么去解决的呢?一般来讲,防抖和节流是比拟好的解决方案。
1、防抖:
指触发事件后在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')//1、不加防抖 ,会始终触发change事件 input1.addEventListener('keyup', function(){ console.log(input1.value) })//2、简略实现防抖 let timer = null input1.addEventListener('keyup', function(){ if(timer){ clearTimeout(timer) } timer = setTimeout(() => { //模仿触发change事件 console.log(input1.value) //清空定时器 timer = null }, 1000) })//3、将防抖函数这个工具进行封装 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) } }
2、节流:
间断发送的事件在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') //1、简略实现节流 let timer = null div1.addEventListener('drag', function(e){ if(timer){ return } timer = setTimeout(() => { console.log(e.offsetX, e.offsetY) timer = null //定时器执行了,才让timer为空 }, 1000) }) //2、将节流函数这个工具进行封装 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) } }
说说你对语义化的了解?
1,去掉或者失落款式的时候可能让页面呈现出清晰的构造
2,有利于SEO:和搜索引擎建设良好沟通,有助于爬虫抓取更多的无效信息:爬虫依赖于标签来确定上下文和各个关键字的权重;
3,不便其余设施解析(如屏幕阅读器、盲人阅读器、挪动设施)以意义的形式来渲染网页;
4,便于团队开发和保护,语义化更具可读性,是下一步吧网页的重要动向,遵循W3C规范的团队都遵循这个规范,能够缩小差异化
你如何对网站的文件和资源进行优化?
期待的解决方案包含:
文件合并
文件最小化/文件压缩
应用 CDN 托管
缓存的应用(多个域名来提供缓存)
其余
请说出三种缩小页面加载工夫的办法?
1、压缩css、js文件
2、合并js、css文件,缩小http申请
3、内部js、css文件放在最底下
4、缩小dom操作,尽可能用变量代替不必要的dom操作
你有哪些性能优化的办法?
(详情请看雅虎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) 图片预加载,将样式表放在顶部,将脚本放在底部 加上工夫戳。
平时如何治理你的我的项目?
先期团队必须确定好全局款式(globe.css),编码模式(utf-8) 等;
编写习惯必须统一(例如都是采纳继承式的写法,单款式都写成一行);
标注款式编写人,各模块都及时标注(标注要害款式调用的中央);
页面进行标注(例如 页面 模块 开始和完结);
CSS跟HTML 分文件夹并行寄存,命名都得对立(例如style.css);
JS 分文件夹寄存 命名以该JS性能为准的英文翻译。
你如何优化本人的代码?
代码重用
防止全局变量(命名空间,关闭空间,模块化mvc…)
拆分函数防止函数过于臃肿
正文
什么是 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>元素就能够了。
js提早加载的形式有哪些?
defer和async、动态创建DOM形式(创立script,插入到DOM中,加载结束后callBack)、按需异步载入js
什么叫优雅降级和渐进加强?
优雅降级:Web站点在所有旧式浏览器中都能失常工作,如果用户应用的是老式浏览器,则代码会查看以确认它们是否能失常工作。因为IE独特的盒模型布局问题,针对不同版本的IE的hack实际过优雅降级了,为那些无奈反对性能的浏览器减少候选计划,使之在新式浏览器上以某种模式降级体验却不至于齐全生效.
渐进加强:从被所有浏览器反对的基本功能开始,逐渐地增加那些只有旧式浏览器才反对的性能,向页面减少有害于根底浏览器的额定样
对前端界面工程师这个职位是怎么样了解的?它的前景会怎么样?
前端是最贴近用户的程序员,比后端、数据库、产品经理、经营、平安都近。
1、实现界面交互2、晋升用户体验3、有了Node.js,前端能够实现服务端的一些事件
前端是最贴近用户的程序员,前端的能力就是能让产品从 90分进化到 100 分,甚至更好,
参加我的项目,疾速高质量实现实现效果图,准确到1px;
与团队成员,UI设计,产品经理的沟通;
做好的页面构造,页面重构和用户体验;
解决hack,兼容、写出柔美的代码格局;
针对服务器的优化、拥抱最新前端技术。
说说最近最风行的一些货色吧?常去哪些网站?
Node.js、Mongodb、npm、MVVM、MEAN、three.js,React 。
网站:w3cfuns,sf,hacknews,CSDN,慕课,博客园,InfoQ,w3cplus等