一般比较基础的面试题都是出一个js执行代码,让你回答输出什么
原题:
<ul>
<li>这是第一个li</li>
<li>这是第二个li</li>
<li>这是第三个li</li>
</ul>
<script>
var lis=document.querySelectorAll('li')
for(var i=0;i<lis.length;i++){
lis[i].onclick=function(){
console.log(i);
}
}
</script>
这段代码输出是3,不管点击哪个都是3,但是需要改造成点击哪个li就显示它的索引
第一种方法
<script>
var lis=document.querySelectorAll('li')
for(let i=0;i<lis.length;i++){ //将var改成let,就多了块级作用域
lis[i].onclick=function(){
console.log(i);
}
}
</script>
第二种方法
<script>
var lis=document.querySelectorAll('li')
for(var i=0;i<lis.length;i++){
(function(i){ // 添加一个立即执行函数,就多了函数级作用域
lis[i].onclick=function(){
console.log(i);
}
})(i)
}
</script>
这里其实产生了一个闭包,函数外部可以访问到函数内部的值
什么是闭包呢
function fn1(){
var a=10;
function fn2(){
console.log(++a);
}
return fn2()
}
fn1() // 输出11
闭包就是可以访问另一个函数作用域内的变量,return是接收返回值,不然拿不到fn2里的值
闭包主要是延长变量的作用域
var、let、const的区别
var 会有一个变量提升,是因为在声明变量的时候,会从栈内预开辟一个存储空间,如果值是对象,则会引用堆的内存地址
let和const是es6新增的语法,在es5之前没有块级作用域,只有函数级的,let和const就是es6新增的块级作用域,它们没有变量提升,不会在栈内预分配内存地址,也不能重复声明,const不能修改基础数据类型,引用数据类型可以修改值
再补充一点
事件委托:通过给父元素监听事件,冒泡到子元素,这样就减少了dom操作,因为多次操作dom会影响页面性能
var ul=document.querySelector('ul')
ul.onclick=function (e){
e.target.style.backgroundColor='pink'
}