1、js延迟加载的方式有哪些?
- defer和async
- 动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)
- 按需异步载入js
2、使用箭头函数需要注意的地方
- 在使用=>定义函数的时候,this的指向是定义时所在的对象,而不是使用时所在的对象;
- 不能够用作构造函数,这就是说,不能够使用new命令,否则就会抛出一个错误;
- 不能够使用arguments对象;
- 不能使用yield命令;
3、var、let、const之间的区别
- var声明变量可以重复声明,而let不可以重复声明
- var是不受限于块级的,而let是受限于块级
- var会与window相映射(会挂一个属性),而let不与window相映射
- var可以在声明的上面访问变量,而let有暂存死区,在声明的上面访问变量会报错
- const声明之后必须赋值,否则会报错
- const定义不可变的量,改变了就会报错
- const和let一样不会与window相映射、支持块级作用域、在声明的上面访问变量会报错
4、cookies sessionStorage和localstorage 的异同
相同点:
都存储在客户端
不同点:
- 存储大小
- cookie数据大小不能超过4k。
- sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
- 有效时间
- localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
- sessionStorage 数据在当前浏览器窗口关闭后自动删除。
- cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
- 数据与服务器之间的交互方式
- cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端
- sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
5、wiondow.onload和onDocumentReady和区别?
- window.onload在页面所有元素(包括图片、引入的文件)加载完成后执行,
- onDocument在html DOM和css DOM 加载后(部分图片可能没有加载完成)就可执行;
- window.onload只能执行一次,如果定义多次,后者将覆盖前者,onDocument可定义多次,并且都能运行;
6、call() 和 apply() 的区别和作用?
- apply()函数有两个参数:第一个参数是上下文,第二个参数是参数组成的数组。如果上下文是null,则使用全局对象代替。
- call()的第一个参数是上下文,后续是实例传入的参数序列。
7、如何阻止冒泡?
- w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true
8、如何阻止默认事件?
- w3c的方法是e.preventDefault(),IE则是使用e.returnValue = false
9、new 操作符干了什么?
- new关键字 通过构造函数创建出来的实例可以访问到构造函数原型链中的属性,
- 也就是说通过 new 操作符,实例与构造函数通过原型链连接了起来
- 先创建了一个新的空对象
- 然后让这个空对象的proto指向函数的原型prototype
- 将对象作为函数的this传进去,如果return 出来东西是对象的话就直接返回 return 的内容,没有的话就返回创建的这个对象
10、null和undefined的区别
- null类型,代表“空值”,代表一个空对象指针,使用typeof运算得到 “object”,所以你可以认为它是一个特殊的对象值。
- undefined类型,代表“未定义”,代表一个变量已经声明但是还未赋值,就是此处应该有一个值,但是还没有定义。
11、闭包
概念:
- 闭包是函数和声明该函数的词法环境的组合。
- 使用闭包主要是为了设计私有的方法和变量。
- 闭包的优点是可以避免全局变量的污染,
- 缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
特征:
- 函数嵌套函数
- 函数内部可以引用外部的参数和变量
- 参数和变量不会被垃圾回收机制回收
12、事件循环 event-loop
- 浏览器js引擎遇到了setTimeout,识别了这是一个异步任务,不会将其放入运行栈,而是把它拿走,
- 拿走了之后也没有立马放到异步任务队列中,按延迟时间放入到任务队列中。
- 同步任务没有正在执行的东西,就会读异步任务,
- 把任务放到运行栈中,执行完了又去读异步任务,把任务放到运行栈中,如此循环。
注意:setTimeout 的时间间隔,并不代表着时间间隔到了以后就会立马执行,他仅仅表示最少延迟时间,而非确切的等待时间
基本上,setTimeout
需要等待当前队列中所有的消息都处理完毕之后才能执行,即使已经超出了由第二参数所指定的时间。
13 、数据类型
基本数据类型:undefined、string、number、boolean
引用类型:对象、数组、函数
基本数据类型存储在栈中,复杂数据类型存储在堆中。
typeof 结果:
typeof 1 --------- 'number'
typeof 'ab' --------- 'string'
typeof true --------- 'boolean'
typeof false--------- 'boolean'
typeof undefined ---- 'undefined'
typeof null --------- 'object'
typeof [] --------- 'object'
typeof {} --------- 'object'
typeof function(){} - 'function'
// es6 新增
typeof Symbol(1) ---- 'symbol'
14、内存泄漏
造成内存泄漏:
- 垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。
- setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
- 闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
- DOM 引用
解决:
- 可以在 JavaScript 文件开头添加 “use strict”,使用严格模式。这样在严格模式下解析 JavaScript 可以防止意外的全局变量。
- 在使用完之后,对其赋值为 null 或者重新分配。
浏览器方案:
- 引用计数垃圾收集:是最初级的垃圾收集算法,此算法把“对象是否不再需要”简化定义为“对象有没有其他对象引用到它”。如果没有引用指向该对象(零引用),对象将被垃圾回收机制回收。但是有个限制,两个对象互相引用,就会造成内存泄漏。
- 标记-清除算法:这个算法假定设置一个叫做根(root)的对象(在Javascript里,根是全局对象)。垃圾回收器将定期从根开始,找所有从根开始引用的对象,然后找这些对象引用的对象……从根开始,垃圾回收器将找到所有可以获得的对象和收集所有不能获得的对象。这个算法比前一个要好,因为“有零引用的对象”总是不可获得的,但是相反却不一定,参考“循环引用”。从2012年起,所有现代浏览器都使用了标记-清除垃圾回收算法。所有对JavaScript垃圾回收算法的改进都是基于标记-清除算法的改进,并没有改进标记-清除算法本身和它对“对象是否不再需要”的简化定义。解决了循环引用的问题
15、dom事件流?
捕获:从上到下
冒泡:从当前元素往上
捕获-> 目标阶段->冒泡
16、dom绑定多个事件,如何阻止其他事件
event.stopImmediatePropagation()
17、ajax
var xhr = new XMLHttpRequest();
xhr.open(method, url, false); // method:请求方式,url:请求的地址,async:是否异步请求,默认true(异步)
xhr.send(null); // xhr.send(data)
xhr.onreadtstatechange = function () {
if (xhr.readystate == 4) {
//响应内容解析完成,可以在客户端调用了
if (xhr.status == 200) {
//客户端的请求成功了
alert(xhr.responseText);
}
}
}
状态:
0:(未初始化)还没有调用send()方法
1:(载入)已调用send()方法,正在发送请求
2:(载入完成)send()方法执行完成,已经接收到全部响应内容
3:(交互)正在解析响应内容
4:(完成)响应内容解析完成,可以在客户端调用了
18、AMD 和 CMD
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。依赖前置
CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。就近依赖
19、 fetch、axios 和 XMLHttpRequest 的异同
20、 typeof null 为什么等于 object
原理是这样的,不同的对象在底层都表示为二进制,在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型,
null 的二进制表示是全 0,自然前三位也是 0,所以执行 typeof 时会返回“ object ”。
这个bug是第一版Javascript留下来的。在这个版本,数值是以32字节存储的,由标志位(1~3个字节)和数值组成。