js面试题总结
1.js的typeof返回哪些数据类型?
alert(typeof null) //object
alert(typeof undefined) //undefined
alert(typeof NaN) //number
alert(NaN == undefined)//false
alert(NaN == NaN) //false
var str = "123abc"
alert(typeof str++) //number
alert(str) //NaN
2.列举至少3种强制类型转换和2种隐式类型转换
1.强制类型转换:明确调用内置函数,强制把一种类型的值转换为另一种类型。
强制转换类型主要有:Boolean number string parselnt parsefloat
2.隐式类型转换:在使用算是运算符时,运算符两边的数据类型可以是任意的,比如,一个字符串可以和数字相加。之所以不同的数据类型之间做运算,是因为js引擎再运算之前会悄悄地把他们进行了隐世类型转换。
隐式类型转换主要有:+ - == !
3.js的事件流模型都有什么?
事件流描述的是从页面中接收事件的顺序。dom结构是树形结构,当页面中的某一个元素触发了某一个事件,事件会从最顶层的window对象开始,向下传播到目标元素,途径的祖先节点都会触发对应的事件,如果当前节点的该事件绑定了事件处理函数的话,则会执行该函数当前事件达到目标元素并执行绑定函数(如果有绑定的话)后,事件又会向上传播到window元素,途径的祖先节点都会触发对应的事件(如果绑定事件处理处理函数的话)
事件流包含三个阶段:
- 事件捕捉阶段:事件开始由顶层对象触发,然后逐级向下传播,直到目标的元素;
- 处于目标阶段:处在绑定事件的元素上;
- 事件冒泡阶段:事件由具体的元素先接收,然后逐级向上传播,直到不具体的元素
4.bom对象有哪些,列举window对象?
1.window对象,是js的最顶层对象,其他的bom对象都是window对象的属性;
2.document对象,文档对象;
3.location对象,浏览器当前url信息;
4.navigator对象,浏览器本身信息;
5.screen对象:客户端屏幕信息;
6.history对象:浏览器访问的历史信息
5.简述ajax及基本步骤
AJAX:即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
基本步骤:
1.初始化ajax对象;
2.连接请求,准备数据;
3.发送请求;
4.接收数据(正在接收,尚未完成)
5.接收数据完成
6.http状态消息200,302,304,403,404,500分别表示什么?
- 200:请求已完成,请求所希望的响应头或数据体将随此响应返回
- 302:请求的资源临时从不同的URL响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在cache-control或者express中进行了指定的情况下,这个响应才是可缓存的
- 304:如果客户端发送了一个带条件的GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个304状态码。简单的表达就是:服务端已经执行了GET,但文件未变化。
- 403:服务器已经理解请求,但是拒绝执行它
- 404:请求失败,请求所希望得到的资源未被在服务器上发现
- 500:服务端遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器端的源码出现错误时出现
7.get和post的区别,什么时候使用post?
GET:一般用于数据查询,使用URL传递参数,由于浏览器对地址栏长度有限制,所以使用get方式所发送信息的数量有限制,同时浏览器会记录(历史记录,缓存)中保存请求地址的信息,包括地址后面的数据。get只能发送普通格式(URL编码格式)的数据。
POST:一般用于向服务器发送数据,对发送的数据大小理论上是没有限制,浏览器会缓存记录地址,但是不会记录post提交的数据。post可以发送纯文本,URL编码格式,二进制格式的字符串,形式多样
以下情况,使用post请求:
1.已提交为目的的请求(类似语义化,get表示请求,post表示提交);
2.发送私密类数据(用户名,密码)(因为浏览器缓存记录特性);
3.向服务器发送大量数据(数据大小限制区别);
4.上传文件图片(数据类型区别)
8.js字符串操作函数?
concat():将两个或多个字符的文本组合起来,返回一个新的字符串
indexOf():返回字符串中一个子串第一处出现的索引。如果没有匹配项,返回-1
charAt():返回指定位置的字符
lastIndexOf():返回字符串中一个子串最后一处出现的索引,如果没有匹配项,返回-1
substr():返回从string的startPos位置,长度为length的字符串
slice():提取字符串的一部分,并返回一个新字符串
replace():用来查找匹配一个正则表达式的字符串,然后使用新字符串代替匹配的字符串
split():通过将字符串划分成子串,将一个字符串做成一个字符串数组
length():返回字符串的长度,所谓字符串的长度是指其包含的字符的个数
toLowerCase():将整个字符串转换成小写字母
toUpperCase():将整个字符串转换成大写字母
9.数组的常用方法(含es6)
1.push()后增
push()方法可以向数组后添加一个新的元素,并返回新数组的长度。
2.unshift() 前增
unshift()可以向数组前添加一个或多个元素,并返回新的长度
3.pop() 后删
pop() 用于删除并返回最后一个元素。
4.shift() 前删
shift() 用于删除并返回首个元素
5.splice() 修该删除
splice(index,length,增加的元素1,增加的元素2…,增加的元素N) 表示从index开始删除length个元素,并从index开始新增元素1~N,放回被删除的元素组成的数组
var a = [1,2,3]
var b = a.splice(1,1,3,[2,3,4],5)
console.log(a) // [1,3,[2,3,4],5,3]
console.log(b) // [2]
6.concat() 拼接
concat() 方法用来合并两个或多个数组
合并两个或多个数组,返回新数组,不会改变原数组
var a = [1,2,3]
var b = [4,5]
var c = a.concat(b)
console.log(a) // [1,2,3]
console.log(b) // [4,5]
console.log(c) // [1,2,3,4,5]
7.slice() 剪切
slice(startIndex,endIndex) 返回从startIndex开始(包括),到endIndex(不包括)之间的原属组成的数组
包左不包右
var a = [1,2,3]
var b = a.slice(0,1)
// 不填参数则表示剪切整个数组
var c = a.slice()
console.log(a) // [1,2,3]
console.log(b) // [1]
console.log(c) // [1,2,3]
console.log(a===c) // false // 注意 a !== c
// 负数表示从后往前数
var d = a.slice(-1,-2)
console.log(d) // [] 从左向右截取,所以说为[]
var e = a.slice(-1)
console.log(e) // [3]
————————————————
版权声明:本文为CSDN博主「挥别了青春」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wang729506596/article/details/83019131
8.join()
join() 方法用来将数组转换为字符串
9.sort() 排序
按ascii码排序
10.reverse() 颠倒顺序
reverse() 方法用于颠倒数组中元素的顺序。
返回的是颠倒后的数组,会改变原数组。
11.indexOf()和lastIndexOf()
indexOf(某元素,startIndex) 从startIndex开始,查找某元素在数组中的位置,若存在,则返回第一个位置的下标,否则返回-1
lastIndexOf(某元素,startIndex) 和indexOf()相同,区别在于从尾部向首部查询
不会改变原数组,返回找到的index,否则返回-1
若不使用下标,则一般通过includes()方法代替indexOf()
var a = [1,2,4,3,4,5]
console.log(a.indexOf(4)) // 2
console.log(a.indexOf(4,3)) // 4
12.filter()过滤
filter() 方法返回数组中满足条件的元素组成的新数组,原数组不变
var a = [1,2,3,4,11]
// 第一个参数为一个方法,有三个参数,current:当前值 index:当前值下标 array:这个数组对象
var b = a.filter(function(current,index,array){
return current < 10
})
console.log(b) // [1,2,3,4]
console.log(a) // [1,2,3,4,11]
13.map() 格式化数组
map() 方法来根据需求格式化原数组,返回格式化后的数组。原数组不变
14.every()
对数组的每一项都运行给定的函数,若每一项都返回 ture,则返回 true
15.some()
对数组的每一项都运行给定的函数,若存在一项或多项返回 ture,则返回 true
16.forEach() 数组遍历
ES6新增的方法
find()
findIndex()
includes()
Array.isArray()
10.怎样添加,移除,移动,复制,创造和查找节点?
1.创建新节点
createElement()//创建一个具体的元素
2.添加,移除
appendChild()//添加
removeChild()//移除
3.查找
document.getElementsByTagName()//通过标签名称获取的是数组document.getElementsByName()//通过元素的Name属性的值document.getElementByld()//通过元素ld,唯一性document.querySelector('#id')查找元素唯—性document.querySelectorAll('#id')查找元素获取的是数组
11.写出三个使用this的典型应用
1.在html元素事件属性中使用,如:
<input type=”button” onclick=”showInfo(this);” value=”点击一下”/>
2.构造函数
function Animal(name, color) {
this.name = name;
this.color = color;
}
3.input点击,获取值
<input type="button" id="text" value="点击一下" />
<script type="text/javascript">
var btn = document.getElementById("text");
btn.onclick = function() {
alert(this.value); //此处的this是按钮元素
}
</script>
4.apply()/call()求数组最值
<input type="button" id="text" value="点击一下" />
<script type="text/javascript">
var btn = document.getElementById("text");
btn.onclick = function() {
alert(this.value); //此处的this是按钮元素
}
</script>
12.js中call和apply的区别?
apply:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。
call:调用一个对象的一个方法,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。
call 与 apply 的相同点:
- 方法的含义是一样的,即方法功能是一样的;
- 第一个参数的作用是一样的;
call 与 apply 的不同点:两者传入的列表形式不一样
- call可以传入多个参数;
- apply只能传入两个参数,所以其第二个参数往往是作为数组形式传入
13.闭包是什么,有什么特性,对页面有什么影响?
我们都知道,js的作用域分两种,全局和局部,基于我们所熟悉的作用域链相关知识,我们知道在js作用域环境中访问变量的权利是由内向外的,内部作用域可以获得当前作用域下的变量并且可以获得当前包含当前作用域的外层作用域下的变量,反之则不能,也就是说在外层作用域下无法获取内层作用域下的变量,同样在不同的函数作用域中也是不能相互访问彼此变量的,那么我们想在一个函数内部也有限权访问另一个函数内部的变量该怎么办呢?闭包就是用来解决这一需求的,闭包的本质就是在一个函数内部创建另一个函数。
特性:
函数嵌套函数
函数内部可以引用函数外部的参数和变量
参数和变量不会被垃圾回收机制回收
好处:
保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)
匿名自执行函数可以减少内存消耗
坏处:
其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;
其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响
14.js中的正则表达式
修饰符 可以在全局搜索中不区分大小写:
修饰符 | 描述 |
---|---|
i | 执行对大小写不敏感的匹配。 |
g | 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。 |
m | 执行多行匹配。 |
方括号用于查找某个范围内的字符:
表达式 | 描述 |
---|---|
[abc] | 查找方括号之间的任何字符。 |
[0-9] | 查找任何从 0 至 9 的数字。 |
(x|y) | 查找任何以 | 分隔的选项。 |
元字符是拥有特殊含义的字符:
元字符 | 描述 |
---|---|
\d | 查找数字。 |
\s | 查找空白字符。 |
\b | 匹配单词边界。 |
\uxxxx | 查找以十六进制数 xxxx 规定的 Unicode 字符。 |
量词:
量词 | 描述 |
---|---|
n+ | 匹配任何包含至少一个 n 的字符串。 |
n* | 匹配任何包含零个或多个 n 的字符串。 |
n? | 匹配任何包含零个或一个 n 的字符串。 |
15.es6的新语法
https://es6.ruanyifeng.com/#docs/let
16.用js递归的方式写1-100求和?
function add(num1,num2){
var num=num1+num2
if(num2+1>100){
return num
}else{
return add(num,num2+1)
}
}
var sum=add(1,2)