走进 JAVASCRIPT 黑洞,涵盖 es5 / es6 / es7 / es8 知识点

  • A+
所属分类:Web前端
摘要

让程序跑起来与避免延迟: 变量声明基础知识: 体验解析过程与变量提升:

让程序跑起来与避免延迟:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">     <!-- <script src="1.js"></script> --> </head> <body>   CYY    <!-- 建议把js写在文档内容结束的地方,避免影响DOM的渲染 -->   <script src="1.js"></script> </body> </html>

 

变量声明基础知识:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">     <!-- <script src="1.js"></script> --> </head> <body>   CYY    <script>     //   一次定义多个变量 //    var a = 1, b = 2, c = 3;  //    var a = b = c = 4;  //    var name = 99; //    console.log(name);    console.log(window.name);  //    var a = 1; //    console.log(a);    console.log(window.a);     console.log(window);  //    弱类型语言    var web = 'cyy';    console.log(typeof web);    web = 99;    console.log(typeof web);    web = {};    console.log(typeof web);   </script> </body> </html>

 

体验解析过程与变量提升:

把变量的声明提前(var)

这是属于js不好的地方,因此我们推荐使用let和const来声明变量

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"> </head> <body>    <script>     // 没有打印出a,而是直接报错     // 说明在执行代码之前,js已经先分析一遍了  //    var a = 1; //    console.log(a); //    var class = 2; //    console.log(class);      // 先提升处理 var a;     // 然后console.log(a);     // 然后赋值a = 1;     // console.log(a);     // var a = 1;      // function hd(){     //     if(false){     //         var a = 1;     //     }     //     console.log(a);     // }     // hd();     // 以上代码相当于     function hd(){         var a; // 变量提升         if(false){             a = 1;         }         console.log(a);     }     hd();      </script> </body> </html>

 

let&const 暂时性死区TDC:

使用let的话,必须先声明再使用,不存在变量提升;

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>     <script>         // console.log(a);         // var a = 1;          // console.log(b);         // let b = 1;          // console.log(c);         // const c = 1;          // 如果函数内部没有定义a,则会去函数外部找         // let a = 1;         // function func(){         //     console.log(a);         // }         // func();          // let a = 1;         // function func(){         //     // 如果函数内部声明了a,则必须先声明,再使用,否则报错         //     console.log(a);         //     let a = 2;         // }         // func();          function func2(a=b,b=3){}         func2();          function func2(a=3,b=a){}         func2();     </script> </body> </html>

 

var-let-const的共同点:

函数中可以访问到外部全局的变量

函数内部如果找不到变量,会顺着作用域链向外查找,直到null
<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>     <script>         // 函数内部如果找不到变量,会顺着作用域链向外查找,直到null         // var a = 1;         // function func(){         //     console.log(a);         // }         // func();         // console.log(a);          // let a2 = 1;         // function func2(){         //     console.log(a2);         // }         // func2();         // console.log(a2);          // const a3 = 1;         // function func3(){         //     console.log(a3);         // }         // func3();         // console.log(a3);  ////////////////////////////////////////////////////////          // var a = 1;         // function func(){         //     var a = 3;         //     // 此时打印函数内部的变量a,与函数外部的变量a无关         //     console.log(a);         // }         // func();         // console.log(a);          // var a = 1;         // function func(){         //     a = 3;         //     // 此时修改的是函数外部的变量a,因为函数内部并没有声明变量a         //     console.log(a);         // }         // func();         // console.log(a);  ////////////////////////////////////////////////////////          // let a = 1;         // function func(){         //     let a = 3;         //     // 此时打印函数内部的变量a,与函数外部的变量a无关         //     console.log(a);         // }         // func();         // console.log(a);          // let a = 1;         // function func(){         //     a = 3;         //     // 此时修改的是函数外部的变量a,因为函数内部并没有声明变量a         //     console.log(a);         // }         // func();         // console.log(a);  ////////////////////////////////////////////////////////          const a = 1;         function func(){             const a = 3;             // 此时打印函数内部的变量a,与函数外部的变量a无关             console.log(a);         }         func();         console.log(a);          const a = 1;         function func(){             a = 3;             // 此时修改的是函数外部的变量a,因为函数内部并没有声明变量a             console.log(a);         }         func();         console.log(a);     </script> </body> </html>

 

可怕的全局污染:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>     <script>         // 不使用var声明也可以使用变量         // web = 'cyy';         // console.log(web);          // 污染全局,全局也可以访问到函数内部的变量         // function func(){         //     a = 1;         // }         // func();         // console.log(a);          // 严格模式可以解决不使用var声明造成的全局污染问题         "use strict";         function func(){             a = 1;         }         func();         console.log(a);     </script> </body> </html>

 

块级作用域这个先进的特性:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>     <script>         // var没有块级作用域,直接是全局作用域,因此循环结束后影响到了全局的变量         // var i = 99;         // for(var i=0;i<5;i++){         //     console.log(i);         // }         // console.log(i);          // es6存在块级作用域,使用let不会影响到全局作用域         // let i = 99;         // for(let i=0;i<5;i++){         //     console.log(i);         // }         // console.log(i);     </script> </body> </html>

 

避免污染全局的js方法:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>     <script>         var web = 2;     </script>      <script src="script.js"></script>      <script>         // console.log(web);         // console.log(url);         console.log($.getUrl());     </script> </body> </html>

script.js

(function(){     var $ = window.$ = {};     $.web = 1;     var url = 'abc';     $.getUrl = function(){         return url;     } }.bind(window)());

 

使用es6块级作用域避免全局污染:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>     <script>         var web = 2;     </script>      <script src="script.js"></script>      <script>         // console.log(url);         console.log(url2);          // var 没有块级作用域         // {         //     var a = 1;         // }         // console.log(a);          // let有块级作用域         // {         //     let a = 1;         // }         // console.log(a);     </script> </body> </html>

script.js

// 使用花括号给插件中的变量一个块级作用域 {     let url = 'abc';     var url2 = 'xxx'; }

 

const常量声明:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>      <!-- <script src="script.js"></script> -->      <script>         // const定义常量,不可更改;为了便于区分,一般使用大写         // const WEB = 'baidu.com';         // WEB = '111';          // let是可以更改的,用于变量的声明定义         // let WEB = 'baidu.com';         // WEB = '111';          // 常量的范围受限于作用域,不同作用域可以出现同名的常量         // const a = 1;         // function func(){         //     const a = 2;         // }         // func();          // 如果常量是引用类型,则可以更改         // const CONFIG = {};         // CONFIG.a = 1;         // CONFIG.a = 2;         // console.log(CONFIG.a);          // 块级作用域         const a = 1;         {             const a = 2;             console.log(a);         }         console.log(a);     </script> </body> </html>

 

window全局对象污染与重复声明:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>      <!-- <script src="script.js"></script> -->      <script>         // 使用var声明的变量实际上是挂载到window对象上的         // var a = 1;         // console.log(window.a);          // console.log(window);          // 使用let声明的变量不会作为window的属性         // let a = 1;         // console.log(window.a);          // let screenLeft = 88;         // console.log(screenLeft);         // console.log(window.screenLeft);          // var 存在重复声明的问题,let和const不会         // var a = 1;         // var a = 2;         // console.log(a);          // let a = 1;         // let a = 2;         // console.log(a);          // 不同的作用域没有关系         let a = 1;         function func(){             let a = 2;         }     </script> </body> </html>

 

Object.freeze 冻结变量:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>      <!-- <script src="script.js"></script> -->      <script>         const HOST = {             url:'https://www.baidu.com/api/v1',             port:443         };         HOST.port = 80;         console.log(HOST);          // 使用Object.freeze冻结之后,修改无效         Object.freeze(HOST);         HOST.port = 8080;         console.log(HOST);       </script> </body> </html>

 

标量与引用类型的传值与传址特性:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>      <!-- <script src="script.js"></script> -->      <script>         // 传值,把a复制一份,给了b         // let a = 1;         // let b = a;         // b = 3;         // console.log(a,b);          // 传址,a和b共用一个地址         // let a = {name:'cyy'};         // let b = a;         // b.name = 'haha';         // console.log(a,b);      </script> </body> </html>

 

null与undefined详解:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>      <!-- <script src="script.js"></script> -->      <script>         // 一般来说,保存一个变量,可以使用undefined         // 保存一个引用类型,可以使用null         // 但是通常也会引用类型直接定义成空对象         // 变量直接定义成0或者空字符串         // let a = null;         // let b = undefined;          // let a = {};         // let b = '';          // 如果函数没有返回值,就会返回undefined         // function func(){}         // console.log(func());          // 使用一个声明了还没有赋值的变量,结果是undefined         // 使用一个没有声明的变量,会报错         // let a;         // console.log(a);         // console.log(b);          // function star(num){         //     num = num || 5;          //     // if(num == undefined){         //     //     num = 5;          //     // }          //     for(let i=0;i<num;i++){         //         document.write('*');         //     }         // }         // star(10);         // document.write('<hr/>');         // star();          function star(num=5){             for(let i=0;i<num;i++){                 document.write('*');             }         }         star(10);         document.write('<hr/>');         star();     </script> </body> </html>

 

use strict 严格模式,高质量代码守卫:

<!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title>Document</title>     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"> </head> <body>      <!-- <script src="script.js"></script> -->      <script>         // 'use strict';         // a = 1;         // console.log(a);          // a = 1;         // function func(){         //     a = 2;         // }         // func();         // console.log(a);          // 会警告关键词不能使用         // var public = 1;         // console.log(public);          // 严格模式的作用域是从当前作用域向下来进行查找         // 此时报错的是被调用的函数         // 'use strict';         //     function func1(){         //         a = 1;         //     }         //     func1();          //     function func2(){         //         b = 1;         //     }         //     func2();          //    此时报错的是被调用的,且有定义严格模式的函数         //     function func1(){         //         a = 1;         //     }         //     func1();          //     function func2(){         //         'use strict';         //         b = 1;         //     }         //     func2();          // 解构赋值         // let {a,b} = {a:1,b:2};         // console.log(a,b);          'use strict';         ({a,b} = {a:1,b:2});         console.log(a,b);     </script> </body> </html>