1.JavaScript数据类型
(1)六种基本数据类型:number、string、boolean、undefined、null、symbol(新)。
(2)null和undefined的区别:null表示一个对象被定义了,值为“空值”,而undefined表示不存在这个值;typeof null结果为object,typeof undefined结果为undefined。通常用undefined来表示系统级的、出乎意料的、类似错误的值的空缺,而null是表示程序级的、正常的、在意料中的值的空缺。
(3)symbol:调用Symbol()创建的值可以作为属性值来使用,这个属性值既不是字符串也不是对象,而是一个symbol类型的值,解决对象的属性名冲突。具体讲解
(4)其中数据类型:在基本数据类型的基础上,加了object。即number、string、boolean、undefined、null、symbol、object
(5)JS有两种数据类型:基本数据类型(6种),引用类型(Object)
(6)基本数据类型被存储在栈中,按值访问,因为其占据空间固定,是简单的数据段;引用类型存储在堆中,按址访问,因为其值的大小会改变。
(7)判断JS数据类型的方法:typeof,instanceof(多用于判断实例),constructor(不稳定,当重写prototype时,原有的constructor会丢失,被默认为object),toString(对象可以直接调用toString(),其他需要通过call/apply调用)
2.typeof操作符可能的结果,如何区分[]和{}类型
(1)typeof操作符的可能结果:number,string,boolean,undefined,object,function。具体如下:
- 对于基本数据类型,除null以外,均可以返回正确的结果
- 对于引用类型,除function以外,一律返回object
- 对于null,返回object
- 对于function,返回function
(2)区分[]和{}:
i. isArray()
ii. instanceof操作符:obj instanceOf Array
iii. isPrototypeOf()方法:Array.prototype.isPrototypeOf(obj)
iv.constructor属性:obj.constructor==Array
3.JavaScript内置对象
(1)JavaScript内置对象大致可分为三类:数据封装类对象(代表着JavaScript中不同的数据类型,包括Object、Array、Boolean、Number、String)、工具类对象(Math、Date、RegExp)、错误类对象(Error、SyntaxError、ReferenceError等)
(2)内建对象、內建构造器实际上都是一回事,无论是函数还是函数构造器,最后都是对象。
(3)宿主对象:执行JS脚本的环境提供的对象,对于嵌入到网页中的JS来说,其宿主对象就是浏览器提供的对象,所以又称为浏览器对象。浏览器对象有很多,包括Window、Document等。
4.字符串方法
(1)我们通过String()构造器函数来创建String对象,该对象提供了一系列用于文本操作的方法。
(2)较常用的方法有:toUpperCase()、toLowerCase()、charAt(index)、indexOf()、substring(startt,end)(返回索引为start到end-1的字符串)、slice(start,end)、substr(start,count)、split()(把字符串分割成数组)
5.数组方法
(1)不会改变自身的方法:
i. concat():连接两个或更多的数组,并返回合并后的数组
ii. join():将数组中的所有元素连接成一个字符串
iii. slice(start,end):把数组中的一部分浅复制存入一个新的数组对象,返回这个新的数组
iv. toString():返回一个字符串,该字符串中有数组中的每个元素的toString()返回值经调用join()方法连接而成
v. indexOf():返回指定元素能在数组中找到的第一个索引值,否则返回-1
(2)会改变自身的方法:
i. pop():删除数组最后一个元素并返回这个元素
ii. push():添加一个或多个元素到数组末尾,返回数组新的长度
iii. reverse():前后颠倒数组中元素的位置
iv. shift():删除数组的第一个元素,并返回这个元素
v. unshift():在数组的开头插入一个或多个元素,并返回数组新的长度
vi. sort():对数组进行排序,返回这个数组(注:V8引擎sort函数,数组长度小于等于22的用插入排序,其他的用快速排序)
vii. splice(start,count,item1,item2,...):在指定位置给数组添加或删除指定元素,返回被删除的元素组成的数组,没有则返回空数组
6.DOM节点操作方法(增删改查)
(1)创建新节点:createDocumentFragment()、createElement()、createTextNode()、createAttribute()
(2)添加、删除、替换、插入:appendChild()、removeChild()、replaceChild()、insertBefore()
(3)查找:getElementById()、getElementsByTagName()、getElementsByClassName()、querySelector()、querySelectorAll()(IE8以下不支持这两种)
7.JS/jQuery页面加载初始化
(1)js页面加载初始化方法:
(a)在html的body标签中设置onload="init()",然后在js中声明函数function init(){初始化内容}
(b)在js中window.onload=function(){初始化内容}
(2)jQuery页面加载初始化方法:
(a)在js中$(function(){初始化内容});
(b)在js中$(document).ready(function(){初始化内容});
(c)jQuery(function($){初始化内容});
(3)由于jQuery使用$符号,这样和有些组件(如dwr)会产生冲突,为了解决这个问题,可以使用var j=jQuery.noConflict(),然后用j来替换$
(4)js/jQuery页面加载初始化的区别:
(a)jQuery方法时页面结构加载完成之后执行;而js是页面结构及所有文件资源(如图片)加载完毕后执行
(b)jQuery方法可以写多个,js方法只能写一个
8.JavaScript中的事件模型?
CVTE面试官问过一个问题,当时懵逼,不知怎么回答:什么是事件?
《JavaScript权威指南》说明:事件本身并不是一个需要定义的技术名词。
简而言之,事件就是Web浏览器通知应用程序发生了什么事情。事件不是JavaScript对象,不会出现在程序源代码中。
(1)DOM0级事件模型:又称为原始事件模型,在该模型中,事件不会传播,即没有事件流的概念。
(2)IE事件模型:IE事件模型共有两个过程:
- 事件处理阶段(target phase),事件到达目标元素,触发目标元素的监听函数
- 事件冒泡阶段(bubbling phase),事件从目标元素冒泡到document,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
(3)DOM2级事件模型:属于W3C标准模型,现代浏览器(除了IE6-8之外)都支持该模型。在该模型中,一次事件共有三个过程:
- 事件捕获阶段(capturing phase)。事件从document一直向下传播到目标元素,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
- 事件处理阶段(target phase):事件到达目标元素,触发目标元素的监听函数。
- 事件冒泡阶段(bubbling phase):事件从目标元素冒泡到document,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
(4)DOM0和DOM2级事件模型的区别:
- DOM0级事件模型是早起的事件模型,所有的浏览器都支持,且实现也比较简单,解除事件则更加简单,只需要将null赋值给事件函数
- DOM2级事件模型是IE8以下不支持的,通过addEventListener和removeEventListener来注册和解除事件
- DOM1只能对一个DOM对象注册一个相同类型的事件,否则会发生事件的覆盖。
- DOM2级事件模型可以对一个DOM对象注册多个相同类型的事件,且会依次执行各个事件函数
(5)addEventListener('事件名称','事件函数','捕获(true)/冒泡(false)')
9.事件类型
(1)鼠标类事件:mousedown,mouseup,click,dblclick(双击),mouseover,mousemove,mouseenter,mouseout,mouseleave,contextmenu(右键)
(2)键盘类事件:keydown,keypress(非Ctrl,Alt,Shift,Meta),keyup
(3)载入/窗口类事件:beforeunload(窗口即将关闭),unload,load(页面加载成功),error(页面加载失败),pageshow,pagehide(通过前进/后退离开当前页面),scroll,resize
(4)表单类事件:focus,blur,select(选中文本),change,reset,submit
(5)拖动事件:dragstart,dragend,drop
(6)触控设备的触摸事件:touchstart,touchmove,touchend
9.toString()?
(1)toString()是Object的原型方法,这是一个内部属性,其格式为[object Xxx],其中Xxx是对象的类型。
(2)对于Object对象,直接调用toString(),就能返回[object Object]。而对于其他对象,则需要通过call/apply来调用才能返回正确的类型信息。
10.原型链?
(1)JavaScript中的每个函数中都有一个指向某对象的prototype属性。该函数被new操作符调用时会创建并返回一个对象,并且该对象中会有一个指向其原型对象的秘密链接。
通过该秘密链接(在浏览器环境中,该链接名为__proto__),我们就可以在新建的对象中调用相关原型对象的属性和方法。而原型对象自身也具有对象固有的普遍特征,因此
本身也包含了指向其原型的链接,由此就形成了一条链,称之为原型链。
(2)简要来说,就是在对象A的一系列属性中,有一个叫做__proto__的隐藏属性,它指向了另一个对象B。而B的__proto__属性又指向了对象C,以此类推,直至链条末端的
Object对象。
(3)Object对象是JavaScript中的最高级父对象,语言中所有对象都必须继承自它。
11.深拷贝与浅拷贝
(1)区别:简单来说,浅拷贝只是增加了一个指针指向已经存在的内存,而深拷贝则是连同内存也一起复制。区分两者则是看修改目的对象时源对象是否改变。
(2)浅拷贝的方法:
- for...in(直接赋值)
- ES6的对象新方法Object.assign()(注意操作的源对象应该存在对象的嵌套)
- jQuery的$.extend({},obj)方法
- lodash库的_.clone()方法
(3)深拷贝的方法:
- for...in(递归函数)
- Object.assign()(操作对象为一层,不存在对象的嵌套)
- JSON.stringify()+JSON.parse()
- jQuery的$.extend(true,{},obj)方法
- lodash库的_.cloneDeep()方法
12.作用域链?
(1)变量作用域:一个变量的作用域(scope)是程序源代码中定义这个变量的区域。全局变量拥有全局作用域,在JavaScript代码中的任何地方都是有定义的。而在函数内声明的变量只在函数体内有定义,它们是局部变量。在函数体内,局部变量的优先级高于同名的全局变量。
(2)作用域链(scope chain):如果将一个局部变量看作是自定义实现的属性的话,那么可以这样理解变量作用域。每一段JavaScript代码(全局代码或函
数)都有一个与之关联的作用域链。这个作用域链是一个对象列表或者链表,这组对象定义了这段代码“作用域中”的变量。当JavaScript需要查找变量x的值
的时候,它会从链中的第一个对象开始查找,如果这个对象有一个名为x的属性,则会直接使用这个属性的值。如果第一个对象中不存在名为x的属性,JavaScript
会继续查找链上的下一个对象。以此类推,如果作用域链上没有任何一个对象含有属性x,那么久认为这段代码的作用域链上不存在x,并最终抛出一个引用错误
(ReferenceError)异常。
13.什么是闭包?
JavaScript采用词法作用域(lexical scoping),也就是说,函数的执行依赖于变量作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的。
简单来说,一个持有外部环境变量的函数就是闭包,或者还可以理解为定义在一个函数内部的函数。
()