【前端面试】(四)JavaScript var let const的区别

视频链接:

参考链接:

练习网站:

初步认识: 功能实现

HTML的部分:

<input type="text" placeholder="帕图纳克斯">
<button>发表评论</button>
<div></div>

JS的部分:

//首先要要我想弄一个评论功能,
//通过document.querySelector获取到HTML中input标签的type属性为"text"的输入框的部分
//于是赋值给这个var变量text,该变量就成类似容器一样的存在
var text = document.querySelector("input[type='text']");
var button = document.querySelector("button");
var div = document.querySelector("div");

button.onclick = function(){
//用var创建变量content,把输入的内容赋值给content
  var content = text.value;
//接着就把内容赋值给下面的评论显示区域
  div.innerText = content;
};

现在我输入内容就显示出评论的结果了:

重复声明

在不新增变量以及不该写整体结构的前提下,我们可以利用var变量可以重复声明的性质,改写原来评论输入的内容:

JS部分改写:

var text = document.querySelector("input[type='text']");
var button = document.querySelector("button");
var div = document.querySelector("div");

button.onclick = function(){
  var content = text.value;
  var content = "下次一定";
  div.innerText = content;
};

值的修改

而 如果我们不声明 var 这个变量,直接赋值就叫值的修改:

button.onclick = function(){
  var content = text.value;
  content = "下次一定";
  div.innerText = content;
};

当我们使用let变量时,想重复定义是不可以的,但是可以进行值的修改或者创建一个新的let变量

而const变量则更加严格,即不能重复定义,也不存在值修改,但是可以创建一个数组,利用数组通过指针指向和被引用的特点,来存新的变量达到我们修改评论的目的,例子如下。

JS的部分:

button.onclick = function(){
  const content = [];
  content[0] = text.value;
  content[1] = "下次一定";
  div.innerText = content[1];
};
声明提升

接下来弄一个新的例子来说明 HTML部分:

<p class="p1">听君一席话</p>
<p class="p2"></p>

JS部分:

var p1 = document.querySelector("p.p1");
var p2 = document.querySelector("p.p2");

p2.innerText=content;

var content = "如听一席话"

之所以p2的类没有显示内容,则是因为var变量可以声明提示,类似如下的效果:

var content

p2.innerText=content;

content = "如听一席话"

此外let、const声明的变量是没有声明提升,但是可以利用值的修改可令let声明的变量不报错。

创建块级作用域

就是弄个函数,一个函数尽管使用了函数外的同名变量,但是可以选择是否调用,来达到改变该案例p2段落的情况。

不过这样太麻烦了,其实用let/const+花括号内容括起来就可以形成块级作用域的效果:

循环

注意:ES6之前的循环不算是块级作用域的一种 以下就弄也给循环案例 HTML部分:

<ul>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
  <li></li>
</ul>

JS部分:

var li = document.querySelectorAll("li");
//这里进行5次循环
for(var i=0;i<5;i++){
  //每次循环都为li元素添加鼠标事件
  li[i].onmouseover = function(){
    //在这个监听事件,就添加文本节点用循环里的i赋值
    var text = document.createTextNode(i);
    this.appendChild(text);
    //并且修改li元素的高度
    this.style.height = i * 10 + "px";
  }
}

鼠标逐个移动每个li,可以看到它们的间距确实变大了,但是变大的间距都是一致的,并不是逐个上升的,这里是回调函数的问题。

该函数的具体实现流程如下:

首先鼠标事件里的内容是回调函数

需要等执行栈里面的正常任务执行以后才会执行任务队列里面的回调函数的结果,var关键字没有形成块级作用域,回调函数只保存了参数i,等正常任务执行后,i就为5了。

可以在循环声明一个新的let变量j,把i的数值赋给j,并且令鼠标事件只认j,这样因为块级作用域的关系,每次迭代可以进行重新绑定,这样就可以使任务队列里面的回调函数都有不一样的i了

var li = document.querySelectorAll("li");

for(var i=0;i<5;i++){
  let j=i;
  li[j].onmouseover = function(){
    var text = document.createTextNode(j);
    this.appendChild(text);
    this.style.height = i * 10 + "px";
  }
}

可以看到现在就达到我们希望可以逐个增大的效果了

当然也可以把块级作用域锁定在循环里面达到同样的效果(我测试不成功,不知道为什么i参数的0与1总是重合) JS修改:

var li = document.querySelectorAll("li");

for(let i=0;i<5;i++){
  li[i].onmouseover = function(){
    var text = document.createTextNode(i);
    this.appendChild(text);
    this.style.height = i * 10 + "px";
  }
}
总结:

24人参与, 0条评论 登录后显示评论回复

你需要登录后才能评论 登录/ 注册