es6块级作用域 let/var、const的使用、对象的增强写法

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

大概十年前, Brendan Eich就决定修复这个问题, 于是他添加了一个新的关键字: let.

我们可以将let看成更完美的var

 

块级作用域

JS 中使用 var 来声明一个变量时 , 变量的作用域主要是和函数的定义有关 .
针对于其他块定义来说是没有作用域的,比如 if/for 等,这在我们开发中往往会引起一些问题。
 
 
<!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之前因为if和for都没有块级作用域的概念,所以在很多时候,我们都必须借助于
  // function的作用域来解决应用外面变量的问题

  //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(); //打印kobe

  var name = 'why';
  function abc(name) { //此name在function作用域中
    console.log(name);
  }

  name = 'kobe';

  abc('aaa'); //打印aaa

  //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)
  //   btns[i].addEventListener('click',function () {
  //         console.log("第"+i+"个按钮被点击"); //只会打印 第5个按钮被点击
  //   });
  // }


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

</body>
</html>

观察前面ES5的写法 以及控制台的输出,可以看到for循环后 控制台只会打印   第5个按钮被点击 ;可以用闭包的形式解决,但是过于麻烦。

使用ES6写法后 可以得到想要的结果

可以得出:在使用ES6 let的时候变量都会有自己的作用域 别人的更改与它无关 类似于es5中function的作用域,而var是全局的 会根据i的改变而改变。

总结:ES5中的var是没有块级作用域的,ES6中的let是有块级作用域的

块级作用域(es5没闭包-有闭包)比较:

<!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>

  //1.没有块级作用域引起的问题:for的块级
  //为什么闭包可以解决问题: 函数是一个作用域

  var btns = document.getElementsByTagName("button");
  for (var i = 0;i<btns.length;i++){
    btns[i].addEventListener('click',function () {
          console.log("第"+i+"个按钮被点击"); //只会打印 第5个按钮被点击
    });
  }
  //1.情况一:ES5中没有使用闭包(错误的方式)
  i = 5;
  {
    btns[i].addEventListener('click',function () {
      console.log("第"+i+"个按钮被点击"); //只会打印 第5个按钮被点击
    });
  }
  {
    btns[i].addEventListener('click',function () {
      console.log("第"+i+"个按钮被点击"); //只会打印 第5个按钮被点击
    });
  }
  {
    btns[i].addEventListener('click',function () {
      console.log("第"+i+"个按钮被点击"); //只会打印 第5个按钮被点击
    });
  }

  //2.情况二:ES5中使用闭包
  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)
  }

  (function (num) {//i = 0
    btns[i].addEventListener('click',function () {
      console.log("第"+num+"个按钮被点击"); //实际上有五个函数
    })
  })(0)

  (function (num) {//i = 1
    btns[i].addEventListener('click',function () {
      console.log("第"+num+"个按钮被点击"); //实际上有五个函数
    })
  })(1)

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

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

</body>
</html>

const的使用

const关键字
在很多语言中已经存在 , 比如 C/C++ , 主要的作用是将某个变量修饰为常量 .
JavaScript 中也是如此 , 使用 const 修饰的标识符为常量 , 不可以再次赋值 .
什么时候使用const?
当我们修饰的标识符不会被再次赋值时 , 就可以使用 const 来保证数据的安全性 .
 
建议 : ES6 开发中 , 优先使用 const, 只有需要改变某一个标识符的时候才使用 let.
 
const的注意:
 
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>

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

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

  //注意三:常量的含义是指向的对象不能修改,但是可以改变对象内部的属性。
  const obje = {
    name: 'why',
    age: 18,
    height: 1.88
  }
  //obj = {} //错误的

  console.log(obje);

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

  console.log(obje);
</script>

</body>
</html>

对象的增强写法

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

<script>
  //angular -> google
  //TypeScript(microsoft)  -> ts有类型检测
  //flow(facebook) ->

  //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
  // }

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

  console.log(obj);


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

    },
    eat: function () {

    }
  }
  //ES6的写法
  const obj = {
    run() {

    },
    eat() {

    }
  }
</script>

</body>
</html>

猜你喜欢

转载自blog.csdn.net/qq_45441466/article/details/109754846
今日推荐