拓展:块级作用域var、let、const的使用

拓展:块级作用域var、let、const的使用

let/var

事实上var的设计可以看成JavaScript语言设计上的错误. 但是这种错误多半不能修复和移除, 以为需要向后兼容.

  • 大概十年前, Brendan Eich就决定修复这个问题, 于是他添加了一个新的关键字: let.
  • 我们可以将let看成更完美的var
块级作用域
  • JS中使用var来声明一个变量时, 变量的作用域主要是和函数的定义有关.
  • 针对于其他块定义来说是没有作用域的,比如if/for等,这在我们开发中往往会引起一些问题。

image-20210427234307441

image-20210427234313968

块级作用域

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>
<button>按钮4</button>
<button>按钮5</button>

<script>
  // ES5中的var是没有块级作用域的(if/for)
  // ES6中的let是由块级作用的(if/for)

  // ES5之前因为iffor都没有块级作用域的概念, 所以在很多时候, 我们都必须借助于function的作用域来解决应用外面变量的问题.
  // ES6中,加入了let, let它是有iffor的块级作用域.
  // 1.变量作用域: 变量在什么范围内是可用.
  // {
  //   var name = 'why';
  //   console.log(name);
  // }
  // console.log(name);

  // 2.没有块级作用域引起的问题: if的块级
  // var func;
  // if (true) {
  //   var name = 'why';
  //   func = function () {
  //     console.log(name);
  //   }
  //   // func()
  // }
  // name = 'kobe'
  // func()
  // // console.log(name);

  var name = 'why'
  function abc(bbb) { // bbb = 'why'
    console.log(bbb);
  }
  abc(name)
  name = 'kobe'

  // 3.没有块级作用域引起的问题: for的块级
  // 为什么闭包可以解决问题: 函数是一个作用域.
  // var btns = document.getElementsByTagName('button');
  // for (var i=0; i<btns.length; i++) {
  //   (function (num) { // 0
  //     btns[i].addEventListener('click', function () {
  //       console.log('第' + num + '个按钮被点击');
  //     })
  //   })(i)
  // }

  const btns = document.getElementsByTagName('button')
  for (let i = 0; i < btns.length; i++) {
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }
  // ES5
  // var i = 5
  // {
  //   btns[i].addEventListener('click', function () {
  //   console.log('第' + i + '个按钮被点击');
  // })
  // }
  //
  // {
  //   btns[i].addEventListener('click', function () {
  //     console.log('第' + i + '个按钮被点击');
  //   })
  // }
  //
  //
  // {
  //   btns[i].addEventListener('click', function () {
  //     console.log('第' + i + '个按钮被点击');
  //   })
  // }
  //
  //
  // {
  //   btns[i].addEventListener('click', function () {
  //     console.log('第' + i + '个按钮被点击');
  //   })
  // }
  //
  // {
  //   btns[i].addEventListener('click', function () {
  //     console.log('第' + i + '个按钮被点击');
  //   })
  // }
  //
  // // ES6
  // { i = 0
  //   btns[i].addEventListener('click', function () {
  //     console.log('第' + i + '个按钮被点击');
  //   })
  // }
  //
  // { i = 1
  //   btns[i].addEventListener('click', function () {
  //     console.log('第' + i + '个按钮被点击');
  //   })
  // }
  // { i = 2
  //   btns[i].addEventListener('click', function () {
  //     console.log('第' + i + '个按钮被点击');
  //   })
  // }
  // { i = 3
  //   btns[i].addEventListener('click', function () {
  //     console.log('第' + i + '个按钮被点击');
  //   })
  // }
  // { i = 4
  //   btns[i].addEventListener('click', function () {
  //     console.log('第' + i + '个按钮被点击');
  //   })
  // }

</script>

</body>
</html>

块级作用域(es5没闭包-有闭包-let对比)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<button>按钮1</button>
<button>按钮2</button>
<button>按钮3</button>

<script>
  // 1.没有块级作用域引起的问题: for的块级
  // 为什么闭包可以解决问题: 函数是一个作用域.
  var btns = document.getElementsByTagName('button');
  for (var i=0; i<btns.length; i++) {
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }

  // 1.情况一: ES5中没有使用闭包(错误的方式)
  i = 2
  {
    // i = 0
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }

  {
    i = 1
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }

  {
    // i = 2
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }

  // 2.情况二: ES5中使用闭包
  var btns = document.getElementsByTagName('button');
  for (var i=0; i<btns.length; i++) {
    (function (i) { // 0
      btns[i].addEventListener('click', function () {
        console.log('第' + i + '个按钮被点击');
      })
    }) (i)
  }

  i = 100000000
  function (i) { // i = 0
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }(0)

  function (i) { // i = 1
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }(1)

  function (i) { // i = 2
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }(2)

  // ES6中的let
  const btns = document.getElementsByTagName('button')
  for (let i = 0; i < btns.length; i++) {
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }
  i = 10000000
  { i = 0
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }

  { i = 1
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }

  { i = 2
    btns[i].addEventListener('click', function () {
      console.log('第' + i + '个按钮被点击');
    })
  }

</script>

</body>
</html>

const的使用

const关键字

  • 在很多语言中已经存在, 比如C/C++中, 主要的作用是将某个变量修饰为常量.
  • 在JavaScript中也是如此, 使用const修饰的标识符为常量, 不可以再次赋值.

什么时候使用const呢?

  • 当我们修饰的标识符不会被再次赋值时, 就可以使用const来保证数据的安全性.

**建议: 在ES6开发中,优先使用const, 只有需要改变某一个标识符的时候才使用let. **

const的注意

  • const注意一:

    image-20210428001238006

  • const注意二:

    image-20210428001305298

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script>
  // 1.注意一: 一旦给const修饰的标识符被赋值之后, 不能修改
  // const name = 'why';
  // name = 'abc';

  // 2.注意二: 在使用const定义标识符,必须进行赋值
  // const name;

  // 3.注意三: 常量的含义是指向的对象不能修改, 但是可以改变对象内部的属性.
  const obj = {
    name: 'why',
    age: 18,
    height: 1.88
  }
  // obj = {}
  console.log(obj);

  obj.name = 'kobe';
  obj.age = 40;
  obj.height = 1.87;

  console.log(obj);
</script>

</body>
</html>

对象增强写法

  • ES6中,对对象字面量进行了很多增强。
  • 属性初始化简写和方法的简写:

image-20210428001430771

image-20210428001444472

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

<script>
  // const obj = new Object()

  // const obj = {
  //   name: 'why',
  //   age: 18,
  //   run: function () {
  //     console.log('在奔跑');
  //   },
  //   eat: function () {
  //     console.log('在次东西');
  //   }
  // }

  // 1.属性的增强写法
  const name = 'why';
  const age = 18;
  const height = 1.88

  // ES5的写法
  // const obj = {
  //   name: name,
  //   age: age,
  //   height: height
  // }

  // const obj = {
  //   name,
  //   age,
  //   height,
  // }
  //
  // console.log(obj);


  // 2.函数的增强写法
  // ES5的写法
  // const obj = {
  //   run: function () {
  //
  //   },
  //   eat: function () {
  //
  //   }
  // }
  const obj = {
    run() {

    },
    eat() {

    }
  }
</script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

贾维斯Echo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值