个人学习理解笔记
- 1. 创建js对象的两种方法
- 2. 创建数组的两种方法
- 3. 数组去重
- 4.什么是变量提升
- 5.全局变量有什么风险,以及如何保护代码不受干扰?
- 6.什么是闭包(Closure)?
- 7.Java和JavaScript有什么不同
- 8.JavaScript的特性是什么
- 9.JS中的参数对象是什么&如何获得传递给函数的参数类型
- 10.什么是回调
- 11.列出一些内置方法和返回值
- 12.列出在JS代码中访问HTML元素的不同方式
- 12.window 与 document 的区别
- 13JS中的事件冒泡是什么
- 14.JS的原始类型(基本数据类型)和对象类型如何在函数中传递?
- 15.JS中的“严格”模式是什么以及如何启用?
- 16.call 和 apply有什么区别
- 17.如何在JS中清空数组
- 18.js中的delete有什么用
- 19.为什么要将JS源文件的全部内容包装在一个函数中
- 20.数组操作
- 21.JavaScript是同步的还是异步的语言
- 22.宏任务和微任务
- 23.js的原型链
- 24.深拷贝和浅拷贝
- 25.事件委托
- 26.ES6
1. 创建js对象的两种方法
- 使用new Object()或者{}
2. 创建数组的两种方法
- 使用new Array()或者[]
3. 数组去重
- 遍历数组法,实现思路:新建一新数组,遍历传入数组,值不在新数组就加入该新数组中;注意点:判断值是否在数组的方法“indexOf”是ECMAScript5 方法,IE8以下不支持,需多写一些兼容低版本浏览器代码
- 对象键值对法,实现思路:新建一个对象和一个新数组,取出每一个旧数组的值,然后看对象中有没有以该值为键的数据,如果没有则将该值作为键加入对象,取该值的数据类型type作为键的值,并把该值加入新数组,如果对象中有该对应的键,还需要使用indexof判断一下该键对应的值有没有type,没有则按照以上步骤添加新键和将值存入新数组
- 数组下标判断法,实现思路:使用indexof,如果当前数组的第i项在当前数组中第一次出现的位置不是i,那么表示第i项是重复的,忽略掉。否则存入结果数组
4.什么是变量提升
- 无论是那里的变量在它声明之后,js引擎会将这个变量的声明移到该变量作用域的顶部
5.全局变量有什么风险,以及如何保护代码不受干扰?
- 全局变量的危险之处在于其他人可以创建相同名称的变量,然后覆盖你正在使用的变量
- 解决方法:
- 创建一个包含其他所有变量的全局对象,然后当我们要添加全局变量的时候就可以直接添加到这个对象下
- 将所有代码封装到一个可以自动执行的函数里
6.什么是闭包(Closure)?
- 闭包就是将一个函数定义在一个外部函数的内部,用来读取外部函数的变量,外部函数将这个定义在外部函数的函数作为返回值。
-
- 闭包可以读取函数内部的值 2. 可以是变量的值始终保存在内存里
7.Java和JavaScript有什么不同
- Java是面向对象的编程语言,JavaScript是面向对象的脚本语言
- Java运行在虚拟机或者浏览器上,JavaScript运行在浏览器或者node环境上
8.JavaScript的特性是什么
- 轻量级、解释型的脚本语言
- 跨平台性
- 弱类型的脚本语言
- 单线程
- 面向对象
9.JS中的参数对象是什么&如何获得传递给函数的参数类型
- JS 变量arguments表示传递给函数的参数。 使用typeof运算符,可以获得传递给函数的参数类型
10.什么是回调
- 回调函数是作为参数传递给某个函数的普通js函数,它将在另一个函数执行完之后进行调用,所以称为回调函数
11.列出一些内置方法和返回值
- Concat:连接两个或多个字符串
- indexOf() :它返回指定值第一次出现时调用字符串对象中的索引。
- pop() 它从数组中删除最后一个元素并返回该元素。
- push() 它将一个或多个元素添加到数组的末尾,并返回数组的新长度
12.列出在JS代码中访问HTML元素的不同方式
- getElementById(‘idname’): 按id名称获取元素
- getElementsByClass(‘classname’): 获取具有给定类名的所有元素
- getElementsByTagName(‘tagname’): 获取具有给定标记名称的所有元素
- querySelector(): 此函数采用css样式选择器并返回第一个选定元素
12.window 与 document 的区别
- window是全局对象,它包含属性,方法,history,location
- documnet也是位于window之下
13JS中的事件冒泡是什么
- 事件冒泡是HTML DOM中事件传播的一种方式,当一个事件发生时,如果该元素和其祖先元素也定义了该事件的句柄,那么该事件会首先被在最内部的元素捕获和处理,然后被其父元素捕获和处理,然后这样一层层往上
14.JS的原始类型(基本数据类型)和对象类型如何在函数中传递?
- 原始类型是值传递
- 对象类型是引用传递
15.JS中的“严格”模式是什么以及如何启用?
- 严格模式是在代码中引入更好的错误检查的一种方法。
- 当使用严格模式时,不能使用隐式声明的变量,或为只读属性赋值,或向不可扩展的对象添加属性。
- 可以通过在文件,程序或函数的开头添加
use strict
来启用严格模式
16.call 和 apply有什么区别
- call和apply都是用来重新定义函数的执行环境,也就是this的指向,他们的差别在于参数,第一个参数两者都相同,是要重新定义的执行环境(也就是this指向),后面call是传入参数列表,apply是传入参数数组
17.如何在JS中清空数组
- arrayList = []:将变量arrayList设置为一个新的空数组(相当于新建一个数组),如果其他地方没有对这个数组的引用可以使用这种方法,否则对应堆中数组并没有清空
- arrayList.length = 0:将变量arrayList的长度设置为0,不管有没有其他地方引用该数组,都能清空
- arrayList.splice(0, arrayList.length):删除从0开始的length条数据
18.js中的delete有什么用
- 只能删除对象的属性
19.为什么要将JS源文件的全部内容包装在一个函数中
- 其实是用来解决不同js模块和库之间潜在的命名冲突问题,这样使得每个模块都有一个私有的命名空间
20.数组操作
- push():在数组末尾添加一个或多个元素,返回新的长度
- pop():删除返回数组的最后一个元素
- shift():删除返回数组的第一个元素
- unshift():添加一个或多个元素,返回新的长度
- splice():删除元素并向数组加入新元素
splice(index,length,arr1,arr2)
,删除、添加index位置开始的元素,包括index - reverse():将数组元素顺序颠倒
- sort():对数组元素进行排序(默认按照ASCII),可以自定义排序方式
sort((a,b)=>{只有返回值大于零,a、b位置互换})
- forEach():用于数组遍历,
Array.forEach(遍历处理函数)
- map():用于对数组里的元素执行相同的函数,返回一个处理后的数组
newArray = oldArray.map(遍历处理函数)
- concat():连接两个或多个数组
- join():将所有的元素拼接成一个字符串,指定分隔符进行分割
array.join(separator)
,separator是分隔符,可选 - indexOf():返回指定值在数组中第一次出现位置的下标
array.indexOf(值)
21.JavaScript是同步的还是异步的语言
- 准确来说JavaScript是一门单线程语言,不能同时处理多个任务和流程。所有任务分为两种,分别是同步任务和异步任务
- 同步任务是直接在主线程排队执行的任务,只有前一个任务执行完毕才能执行后一个任务。
- 异步任务则是不进入主线程,而进入任务队列的任务,只要异步任务有了运行结果,就会在任务队列放置一个事件。等主线程的同步任务执行完这些异步任务才会进入主线程执行。
22.宏任务和微任务
宏任务是由js运行的环境发起的(setTimeOut,setInterval),微任务是由JavaScript自身发起的(promise,process.nextTick)。Event loop(事件循环)执行顺序
- 先执行宏任务的同步代码
- 再执行微任务队列
- 如果执行环境为浏览器,会先进行渲染页面
- 再执行宏任务中的异步事件
23.js的原型链
js的实例对象有一个默认的属性_proto_指向该实例对象构造函数的原型(相当于上一层的实例对象),构造函数中的prototype属性指向原型,原型中的constructor指向构造函数。当我们访问一个对象的属性时,如果在该对象找不到该属性,就回到他的原型中寻找,找不到再去原型的原型中寻找,直到找到null对象,null对象没有原型
24.深拷贝和浅拷贝
他们的区别是否用的是同一块堆内存,浅拷贝只是复制了对象的引用,深拷贝则是新建一个对象,然后将源对象的所有属性和方法复制到新对象
25.事件委托
事件委托就是不在事件的发生地设置响应函数,而在父元素设置响应函数,通过冒泡,父元素可以监听到子元素事件的触发,父元素根据事件源的不同做出不同的响应。
其中有一个兼容性问题是标准浏览器用的是event.target,IE浏览器用的是event.srcElement。我们进行判断的时候会使用到target.nodeName.toLowerCase()转换成小写进行判断
26.ES6
let、const和var之间的区别
- var只有全局作用域和函数作用域,并且存在变量提升,声明的变量会作为全局对象window的属性
- let只有块作用域,并且不存在变量提升,在作用域顶部到变量声明之间的地方使用变量会报错,此称为“暂时性死区”
- const定义的是常量,块作用域,不存在变量提升
promise
promise对象表示将来要发生的事,用来传递异步操作的消息,promise对象有三种状态,pendding(初始状态)/fulfilled(操作成功)/rejected(操作失败),一旦状态改变就不会再变。有了promise对象,我们就可以将异步操作以同步操作的流程写出来,避免了层层嵌套的回调函数。
let promise = new Promise((resolve, reject) => {
if(success) {
resolve() // 执行成功
} else {
reject() // 执行失败
}
})
promise.then(res => {}).catch(err => {})
展开运算符…
将一个数组转为以逗号分隔的参数序列
async和await
- async作为一个关键字放在函数的前面个,用来表示这个函数是一个异步函数,这个函数的执行不会阻塞后面的代码的执行。改函数的返回值是一个promise对象,如果要获得promise对象的内容我们需要使用then方法
- await后面可以放任意的表达式,但通常会放一个返回promise对象的表达式,await需要放在async函数里面,await表示等待,需要等待promise对象执行完才执行后面的代码。
箭头函数
- 箭头函数是ES6的新特性,箭头函数没有this,它所用到的this是父作用域的this
- 箭头函数无法用call、apply指定this
- 箭头函数没用arguments参数对象
dom0和dom2
- dom0中事件使用.onClick:后面的事件会覆盖前面的事件
- dom2中使用.addEventListener:不会覆盖事件,删除事件用removeEventListener。addEventListener函数的第三个参数是一个布尔值,为true表示在捕获阶段调用事件处理函数,为false表示在冒泡阶段调用事件处理函数
document、documentElement和document.body三者之间的关系
document:表示整个html页面
documentElement表示<html>
标签
document.body表示<body>
标签
js事件流:事件流描述的是从页面接受事件的顺序。dom2级事件流中包括下面几个阶段:
- 事件捕获阶段
- 处于目标阶段
- 事件冒泡阶段
一些老版本的浏览器并不支持事件捕获,例如ie8
以上大都是个人理解总结,有些可能会用到第一人称进行叙述。大家切记不要死记硬背,可以参考答案,但是要经过自己的理解,遇到不懂的还是要自己去查查资料,最好能将自己理解的内容重新编辑成自己的话写下来,这样等面试官追问的时候也能说出自己的见解。祝大家都能通过面试,找到自己理想的工作。