关于javascript:js面试总结

42次阅读

共计 10783 个字符,预计需要花费 27 分钟才能阅读完成。

问题 1、前 ++、后 ++、区别?

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)

【总结】:

前 ++ 是先自加后计算、后 ++ 是后自加先计算

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) // boolean

2、instanceof
例:console.log([1,2] instanceof Array) // true

3、constructor
例:console.log([1, 2].constructor === Array) // ture

4、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,6
console.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,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 外部服务器谬误

说说你对闭包的了解

应用闭包次要是为了设计公有的办法和变量。闭包的长处是能够防止全局变量的净化,毛病是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。

闭包有三个个性:

    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 等

正文完
 0