黑马程序员技术交流社区
标题:
【西安校区】前端JS初级面试题(一)
[打印本页]
作者:
逆风TO
时间:
2020-2-12 17:07
标题:
【西安校区】前端JS初级面试题(一)
var 和 let const 的区别
typeof 返回哪些类型
列举强制类型转换和隐式类型转换
手写深度比较,模拟 lodash isEqual
split() 和 join() 的区别
数组的 pop push unshift shift 分别做什么
数组 slice 和 splice 的区别
[10,20,30].map(parseInt) 返回的结果是什么?
ajax 请求 get 和 post 的区别?
call() apply() bind() 作用和区别
事件代理(委托)是什么?
闭包是什么?有什么特性?有什么负面影响?
如何阻止事件冒泡和默认行为?
查找,添加,删除,移动DOM节点的方法
如何减少DOM操作?
解释 jsonp 的原理,为何它不是真正的ajax ?
document load 和 ready 的区别
== 和 === 的不同
函数声明和函数表达式的区别
new Object() 和 Object.create()的区别
关于 this 的场景题
关于作用域和自由变量的场景题-1
判断字符串以字母开头,后面字母数字下划线,长度 6 - 30
关于作用域和自由变量的场景题-2
手写字符串 trim 方法,保证浏览器兼容性
如何获取多个数字中的最大值
如何用JS实现继承?
如何捕获JS程序中的异常?
什么是JSON?
获取当前页面的url 参数
将url 参数解析为JS对象
手写数组 flatern, 考虑多层级
数组去重
手写深拷贝
介绍一下 RAF requestAnimateFrame
前端性能如何优化?一般从哪几个方面考虑?
更多详情:前端知识体系
1. var 和 let const 的区别
var 是 ES5 语法, let const 是 ES6 语法; var 有变量提升
var 和 let 是变量,可修改;const 是常量,不可修改
let const 有块级作用域(ES6),var 没有
var 的变量提升:
// 变量提升 ES5
console.log(a) // undefined
var a = 200
var a
console.log(a) // undefined
a = 200
let 块级作用域:
// 块级作用域
for (let i = 0; i < 10; i++) {
let j = i + 1
}
console.log(j) // 报错
2. typeof 返回哪些类型
值类型:undefined string number boolean symbol
引用类型:object (注意: typeof null === ‘object’)
函数类型:function
3. 列举强制类型转换和隐式类型转换
强制:parseInt parseFloat toString 等
隐式:if 逻辑运算 == +拼接字符串
4. 手写深度比较,模拟 lodash isEqual
实现效果如下:
// 实现如下效果
const obj1 = {a:10, b:{ x: 100, y: 200}}
const obj1 = {a:10, b:{ x: 100, y: 200}}
isEqual(obj1, obj2) === true
// 判断是否是对象或数组
function isObject(obj) {
return typeof obj === 'object' && obj !== null
}
// 全相等(深度)
function isEqual(obj1, obj2) {
if (!isObject(obj1) || !isObject(obj2)) {
// 值类型(注意,参与 equal 的一般不会是函数)
return obj1 === obj2
}
if (obj1 === obj2) {
return true
}
// 两个都是对象或数组,而且不相等
// 1. 先取出 obj1 和 obj2 的 keys ,比较个数
const obj1Keys = Object.keys(obj1)
const obj2Keys = Object.keys(obj2)
if (obj1Keys.length !== obj2Keys.length) {
return false
}
// 2. 以 obj1 为基准,和 obj2 一次递归比较
for (let key in obj1) {
// 比较当前 key 的 val —— 递归!!!
const res = isEqual(obj1[key], obj2[key])
if (!res) {
return false
}
}
// 3. 全相等
return true
}
// 测试
const obj1 = {
a: 100,
b: {
x: 100,
y: 200
}
}
const obj2 = {
a: 100,
b: {
x: 100,
y: 200
}
}
// console.log( obj1 === obj2 )
console.log( isEqual(obj1, obj2) )
const arr1 = [1, 2, 3]
const arr2 = [1, 2, 3, 4]
5. split() 和 join() 的区别
'1-2-3'.split('-') // [1,2,3]
[1,2,3].join('-') // '1-2-3'
6. 数组的 pop push unshift shift 分别做什么
功能是什么?
返回值是什么?
是否会对原数组造成影响?
const arr = [10, 20, 30, 40]
// pop
const popRes = arr.pop()
console.log(popRes, arr) // 40 [10,20,30]
// shift
const shiftRes = arr.shift()
console.log(shiftRes, arr) // 10 [20,30,40]
// push
const pushRes = arr.push(50) // 返回 length
console.log(pushRes, arr) // 5 [10,20,30,40,50]
// unshift
const unshiftRes = arr.unshift(5) // 返回 length
console.log(unshiftRes, arr) // 5 [5,10,20,30,40]
【扩展】数组的API,有哪些是纯函数?
纯函数:
不改变源数组(没有副作用);
返回一个数组
const arr = [10, 20, 30, 40]
1
// concat
const arr1 = arr.concat([50, 60, 70])
console.log(arr) // [10, 20, 30, 40]
console.log(arr1) //[10, 20, 30, 40, 50, 60, 70]
// map
const arr2 = arr.map(num => num * 10)
console.log(arr) // [10, 20, 30, 40]
console.log(arr2) //[100, 200, 300, 400]
// filter
const arr3 = arr.filter(num => num > 25)
console.log(arr) // [10, 20, 30, 40]
console.log(arr3) //[30, 40]
// slice
const arr4 = arr.slice()
console.log(arr) // [10, 20, 30, 40]
console.log(arr4) //[10, 20, 30, 40]
非纯函数
push pop shift unshift
forEach
some every
reduce
7. 数组 slice 和 splice 区别
功能区别 (slice - 切片,splice - 剪接)
参数和返回值
是否是纯函数
slice 纯函数
const arr = [10, 20, 30, 40, 50]
const arr1 = arr.slice()
console.log(arr1) // [10, 20, 30, 40, 50]
const arr2 = arr.slice(1, 4)
console.log(arr2) // [20, 30, 40]
const arr3 = arr.slice(2)
console.log(arr3) // [30, 40, 50]
const arr4 = arr.slice(-3)
console.log(arr4) // [30, 40, 50]
splice 非纯函数
const arr = [10, 20, 30, 40, 50]
// splice 非纯函数
const spliceRes = arr.splice(1, 2, 'a', 'b', 'c')
console.log(spliceRes, arr) //[20,30] [10, 'a', 'b', 'c', 40, 50]
const spliceRes1 = arr.splice(1, 2)
console.log(spliceRes1, arr)//[20,30] [10, 40, 50]
const spliceRes2 = arr.splice(1, 0, 'a', 'b', 'c')
console.log(spliceRes2, arr)//[] [10, "a", "b", "c", 20, 30, 40, 50]
8. [10,20,30].map(parseInt) 返回的结果是什么?
map 的参数和返回值
parseInt 参数和返回值
const res = [10, 20, 30].map(parseInt)
console.log(res) // [10, NaN, NaN]
拆解后等同于如下:
[10, 20, 30].map((num, index) => {
return parseInt(num, index)
})
parseInt(10, 0) // 10
parseInt(10, 10) // 10
parseInt(20,1) // NaN
parseInt(30, 2) // NaN
9. ajax 请求 get 和 post 的区别?
Ajax, jQuery ajax, fetch,axios ヾ(⌐■_■)ノ看完 你就明白了~~
get 一般用于查询操作,post 一般用于提交操作
get 参数拼接在url 上,post 放在请求体内(数据体积可更大)
安全性:post 易于防止CSRF
10. call() apply() bind() 作用和区别
fn.call(this, p1, p2, p3)
fn.apply(this, arguments)
var fn1 = fn.bind(this, p1, p2, p3)
fn1()
相同点:
改变对象的执行上下文(总的来说,就是改变this的指向)。
this关键字,就是所谓的执行上下文。this关键字在函数中,表示的是一个指向,this的指向永远是一个对象。
都可以指定调用实参。
不同点:
call()和bind()的参数是直接连续传递,而apply传递参数是以一个数组传递。
bind()会返回一个方法。
注意:
如果call()和apply()的第一个参数是null或者undefined,那么this的指向就是全局变量,在浏览器里就是window对象。
代码演示:
var num = "全局中的num";
var o1 = {
num:"o1中的num",
f1:function(){
console.log(this.num);
},
f2:function (a,b) {
console.log(a+b);
return a+b;
}
}
var o2 = {
num:"o2中的num"
}
o1.f1.call(o2); //输出:o2中的num
o1.f1.apply(o2);//输出:o2中的num
var f3 = o1.f1.bind(o2);
f3();//输出:o2中的num
o1.f2.call(o2,1,2); //输出:3
o1.f2.apply(o2,[1,2]);//输出:3
var f4 = o1.f2.bind(o2,1,2);
f4();//输出:3
11. 事件代理(委托)是什么?
js中事件冒泡我们知道,子元素身上的事件会冒泡到父元素身上。
事件代理就是,本来加在子元素身上的事件,加在了其父级身上。
那就产生了问题:父级那么多子元素,怎么区分事件本应该是哪个子元素的?
答案是:event对象里记录的有“事件源”,它就是发生事件的子元素。
它存在兼容性问题,在老的IE下,事件源是 window.event.srcElement,其他浏览器是 event.target
用事件委托有什么好处呢?
第一个好处是效率高,比如,不用for循环为子元素添加事件了
第二个好处是,js新生成的子元素也不用新为其添加事件了,程序逻辑上比较方便
const p1 = document.getElementById('p1')
const body = document.body
bindEvent(p1, 'click', e => {
e.stopPropagation() // 注释掉这一行,来体会事件冒泡
alert('激活')
})
bindEvent(body, 'click', e => {
alert('取消')
})
12. 闭包是什么?有什么特性?有什么负面影响?
JS基础知识:作用域和闭包 ლ(´ڡ`ლ)一样的话题,一样的配方!
作用域和自由变量
闭包应用场景:作为参数被传入,作为返回值被返回
注意:自由变量的查找,要在函数定义的地方(而非执行的地方)
闭包影响:
变量会常驻内存,得不到释放。闭包不要乱用
13. 如何阻止事件冒泡和默认行为?
event.stopPropagation()
event.preventDefault()
14. 查找,添加,删除,移动DOM节点的方法
DOM操作 ᕙ༼ ͝°益° ༽ᕗ 就是这么吊!
15. 如何减少DOM操作?
DOM操作 ᕙ༼ ͝°益° ༽ᕗ 就是这么吊!
缓存DOM 查询结果
多次DOM操作,合并到一次插入
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2