1.数据类型 值的存储
7种基本数据类型
Undefined、Null、Boolean、Number、String、Symbol(es6新增,表示独一无二的值)和BigInt(es10新增);
1种引用数据类型
Object(Object本质上是由一组无序的名值对组成的)。里面包含 Dunction、Array、Date等
原始数据类型:栈
空间小 内存固定 频繁使用
引用数据类型:栈(指针)和堆(实体)
空间大 内存大小不固定
2.&& 、 || 和 !! 运算符分别能做什么
&&
|| 初始化函数默认参数值
!!右侧强行转换为布尔值
3.数据类型转换
Boolean()
Number() parseInt()parseFloat()
.toString() String()
null和underfined没有.toString方法,因为没有原型链
4.数据类型判断
typeof xxx
原始数据类型可以,引用为Object
xxx instanceof someType
找对象原型的方式,基本数据类型无引用,所以无原型,所以不能判断
constructor
实例化对象的构造函数
原型链修改了对应构造函数也要改
Object.prototype.toString.call(xxx)
实例传入原型中执行给xxx的toString方法打印type
5.js内置对象
全局变量值 NaN、undefined,全局函数如 parseInt()、parseFloat() 用来实例化对象的构造函数如 Date、Object 等,还有提供数学计算的单体内置对象如 Math 对象
值属性 Infinity、NaN、undefined、null
函数属性 eval()、parseFloat()、parseInt()
基本对象 Object、Function、Boolean、Symbol、Error
数字和日期对象 Number、Math、Date
字符串 String、RegExp
可索引的集合对象 数组也是内核对象 Array
有key的Map、Set、WeakMap、WeakSet
矢量集合
结构化数据 JSON
控制抽象对象 Promise Generator
反射 Reflect Proxy
国际化 Intl、Intl.Collator
WebAssembly
其他 例如 arguments
6.undefined和undeclared区别
未定义 空指针 有栈的值
未声明 有堆的值
typeof undeclared 报 undefined
7.null和undefined区别(内存 typeof 等不等于)
undefined空指针
null 栈和堆都有定义 但内存是空的 空对象
typeof null 返回 object
双等号是true
三等号是false
8.{} [] valueOf和toString
- {} 的 valueOf 结果为 {} ,toString 的结果为 “[object Object]”
- [] 的 valueOf 结果为 [] ,toString 的结果为 “”
9.作用域和作用域链
10.创建对象方式
new 构造函数
定义字面量对象
工厂模式传参内部创建
原型的构造函数
原型内实现
构造函数和原型结合
11.继承
12.call和apply
相同点:
- 改变第三方函数对象的this指针,将其指向作用域链外的传入的那个this指针,在指针上进行操作。
- 提升性能,例子:
Array.prototype.push.apply(arr1,arr2);
Math.max.apply(null,arr);
不同点:
- func.call(func1,var1,var2,var3)
- func.apply(func1,[var1,var2,var3])
13.原型和原型链
JS获取实例化对象原型链的方法
p.__proto__
p.constructor.prototype
Object.getPrototypeOf(p)
14.什么是闭包,为什么要用?
- 闭包是指有权限访问另一个函数作用域的变量的函数
- 下面的代码要会手写
function a() {
var i = 0;
function b() {
console.log(++i);
}
return b;
}
var c = a();
c();
- 用途:
- 函数外部能够访问函数内部变量,可以创建私有变量
- 已经执行结束的函数上下文变量对象继续内存中,因为闭包保留了对这个变量对象的引用,所以不会被回收
15.了解DOM和BOM吗?
- DOM文档对象模型
- BOM浏览器对象模型,核心是window,window既是通过js访问浏览器窗口的接口,又是一个全局对象,网页中定义的任何对象(变量和函数)都作为全局对象的属性方法
- window 对象含有 location 对象、navigator 对象、screen 对象等子对象,并且 DOM 的最根本的对象 document 对象也是 BOM 的 window 对象的子对象
16.三种事件模型是什么?
事件是用户和网页的交互
- DOM0级模型:网页中定义监听函数或者执行js监听
- IE事件模型:
事件处理:执行目标元素绑定的监听事件
事件冒泡:从目标元素一直向上冒泡一直到document,看依次经过的节点有无事件监听,并执行 - DOM2级事件模型:
事件捕获:从document上到下捕获
17.事件委托是什么?
因为浏览器事件冒泡,在每个子节点绑定监听事件然后执行过后向上冒泡,要造成内存消耗和内存泄露。
所以把子节点监听事件绑定到父节点,父节点处理多个子节点。
18.事件传播是什么?
- 事件捕获:从window开始,向下到每个元素,直到到达目标元素事件或者event.target
- 目标阶段:已经到达目标元素
- 冒泡阶段:从目标元素冒泡一直上升到每个元素,直到window
19.事件捕获是什么?
事件从window开始,一直到触发事件的元素,
window-- document-- html-- body--目标元素
- 给出一个html结构要求,写一个模拟事件捕获的代码
<div class="grandparent">
<div class="parent">
<div class="child">
1
</div>
</div>
</div>
function addEvent(element,event,callback,isCapture = false){
//判断输入是否错误
if(!element || !event || !callback || typeof callback !== 'function')
return;
if(typeof element === 'string'){
element = document.querySelector(element);
};
element.addEventListener(event, calllback, isCapture);
}
addEvent(document,'DOMContentLoaded',()=>{
const child = document.querySelector('.child');
const parent = document.querySelector('.parent');
const grandparent = ducument.quetySelector('.grandparent');
addEvent(child,'click',function(e){console.log('child')});
addEvent(parent,'click',function(e){console.log('parent')});
addEvent(grandparent,'click',function(e){console.log('grandparent')});
addEvent(document,'click',function(e){console.log('document')});
addEvent(html,'click',function(e){console.log('html')});
addEvent(window,'click',function(e){console.log('window')});
})
- 思路:
- 首先获取事件元素
- 因为
element.addEventListener(event, callback, isCapture);
中,要传对应元素、监听事件、回调执行函数
;isCapture
是可选参数,默认为false,事件在冒泡阶段发生,如果为true,事件将在捕获阶段发生。 - 将事件元素、对应事件、回调执行的函数传入之前要判断传入参数是否正确(有元素、事件、回调函数且回调函数是function)
- 判断如果传入的元素是字符串,那么还要进行一个querySelector获取
- 然后进行监听事件,发生了就触发回调函数
20.事件冒泡
上述事件捕获阶段,我们把isCapture的参数调为false就是冒泡阶段
结果是
window document html grandparent parent
21.DOM操作
- 创建新节点
createDocumentFragment()//创建DOM片段
createElement()//创建具体元素
createTextNode()//创建一个文本节点
- 增删改插入
appendChild(node)
removeChild(node)
replaceChild(new,old)
insertBefore(new,old)
- 查找
getElementById()
getElementByName()
getElementByTagName()
//document.getElementByTagName("p")[3]
getElementByClassName()
querySelector()
querySelevtorAll()
- 属性操作
getArribute(key)
getArribute(value)
hasArribute(key)
document.getElementByTagName("button")[0].hasArribute("onclick")
removeAttribute(key)
22.数组和字符串
23.正则表达式
24.创建Ajax五个步骤
- Ajax是什么?
- 异步通信的方法,直接通过js脚本向服务器发起http通信,然后根据服务器返回的数据刷新网页的部分元素,而不用刷新全部
- 原生手写四个步骤
//1.创建ajax对象
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP')//兼容IE6以下版本
//2.配置请求和地址
xhr.open('get','index.xml',true)
//3.发起请求
xhr.send(null);//严谨写法
//4.监听请求,接受响应
xhr.onreadysatechange = function(){
if(xhr.readySate == 4 && xhr.status == 200 || xhr.status == 304)
/*
0:请求未初始化,还没有调用 open()。
1:请求已经建立,但是还没有发送,还没有调用 send()。
2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)。
3:请求在处理中;通常响应中已有部分数据可用了,没有全部完成。
4:响应已完成;您可以获取并使用服务器的响应了。
*/
console.log(xhr.responseXML);
}
- jq
- promise
25.js延迟加载的方式有哪些?
js的延迟加载、解析、执行会阻塞页面的渲染过程,因此希望js脚本能延迟加载,提到渲染速度
- 将脚本放在文档底部,尽可能最后来执行
- 给脚本添加defer属性,这个属性会让脚本加载和文档解析同步解析,然后文档解析完过后执行
- 给js脚本添加async属性,这个属性会使脚本异步加载,但是加载完成过后会立即执行,如果文档某些部分没解析完同样会阻塞
- 动态创建DOM标签,对文档加载事件进行监听,加载完成过后再动态创建script标签引入脚本
26.谈谈你对模块化开发的理解?
- 一个模块是实现一个特定功能的一组方法。
- 一种实现是:利用函数独立作用域,用几个函数作为模块,但是容易造成全局变量污染,并且模块间没有联系
- 另一种是:将函数作为一个对象的方法实现,但是会暴露所有的模块成员,外部代码可以修改内部属性值
- 现在最常用的是立即执行函数的写法,用闭包来实现模块私有作用域的建立,不会对全局作用域造成污染。