JavaScript基础知识

前言

  其实我个人认为JavaScript是一种非常随便的语言,也是一门很神奇很强大的语言。

  因为之前使用过一段时间的JavaScript并做了些学习笔记都是放在word上的显得十分杂乱,所以这次也是打算认认真真的重新填一下坑并且认真整理一下JavaScript笔记到博客园。

  以前在群里聊JavaScript的时候会经常出现一张图,我认为这个很有意思,所以就放在这里做一个填坑目标吧。

  https://www.w3cschool.cn/javascript/javascript-skillmap.html  这里放上一个学习路线图,非常详细非常精彩。当然我的笔记不可能做的十分的全面,所以可以配合看这张学习路线图与笔记,这个路线图好像有很多新版特性都没介绍到,不过在我的笔记中会有相应的介绍。

查看源图像

  我还是希望将整个的笔记好好整理一下,并且以一种文档格式进行书写,也方便后期查阅。

理论知识

语言介绍

  JavaScript官方名称是 ECMAScript 是一种属于网络的脚本语言,已经被广泛用于Web应用开发,常用来为网页添加各式各样的动态功能,为用户提供更流畅美观的浏览效果。

  1995年2月Netscape的布兰登.艾奇开发了针对网景公司的 Netscape Navigator浏览器的脚本语言LiveScript。之后Netscape与Sun公司联盟后LiveScript更名为JavaScript

  微软在JavaScript发布后为了抢占市场推出了JavaScript。为了让脚本语言规范不在混乱,根据JavaScript 1.1版本推出了ECMA-262的脚本语言标准。

  ECMA是欧洲计算机制造商协会由Sum、微软、NetScape公司的程序员组成。

  文档中会经常使用 JS 简写来代替 JavaScript

  Ps:其实整个JavaScript最早的开发周期只用了两周,所以在未来很长一段时间里JavaScript的语法非常混乱,但是随着时间的更迭慢慢的越来越完善起来。

适用场景

  • 浏览器网页端开发

  • 做为服务器后台语言使用Node.js

  • 移动端手机APP开发,如Facebook的 React NativeuniappPhoneGapIONIC

  • 跨平台的桌面应用程序,如使用 electronjs

  所以JS是一专多能的语言,非常适合学习使用。

发展历史

  • 1994年Netscape(网景)公司发布了 Navigator 浏览器1.0版本,市场占用率超过90%

  • 1995年发布了JavaScript 语言

  • 1996年 JS在 Navigator浏览器中使用

  • 1996年微软发布JScript在IE3.0中使用

  • 1996年11月网景公司将JS提交给ECMA(国际标准化组织)成为国际标准,用于对抗微软。

    由ECMA的第39号技术专家委员会(Technical Committee 39,简称TC39)负责制订ECMAScript标准,成员包括Microsoft、Mozilla、Google等大公司。

  • 1997年 ECMA发布ECMA-262标准,推出浏览器标准语言 ECMAScript 1.0

    ECMAScript 是标准而Javascript是实现

  • ...

  • 2009年ECMAScript 5.0发布

  • 2011年ECMAScript5.1发布,成为ISO国际标准,从而推动所有浏览器都支持

  • ...

  • 2015年ECMAScript6发布,更名为ECMAScript 2015。

  • 2016年ECMAScript7发布,ECMAScript2016

  • 2017年ECMAScript8发布,ECMAScript2017

  • 2018年ECMAScript9发布,ECMAScript2018

  • 2019年ECMAScript10,ECMAScript2019

  • 2020年ECMAScript11,ECMAScript2020

  • ....

  从2015年开始 tc39委员会决定每年发布新的ECMAScript版本

chrome使用

  在学习Js的过程中,推荐使用chrome浏览器作为你的开发工具。

image-20200725004121425

引入方式

嵌入式

  HTML文档中使用<script>标签,在<script>标签中嵌入Js代码即可,关于type什么的文档类型声明可写可不写。

  使用这种在方式最好是将Js代码写在尾部。也就是写在HTMLCSS代码之后。

  这种做法是因为如果我们的Js代码需要去查找某一标签而将其放在头部的话HTML的代码可能还没有加载出来,会出现一些不稳定的特殊情况。

  我个人是非常喜欢夹在<body>标签后的...

<!DOCTYPE html>
<html lang="en"><head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
</head><body></body>
    <script>
        console.log("hello,world");  // hello,world
    </script>
</html>

引入式

  同样的,也是使用<script>标签,并为其src属性指定好Js文件路径即可,关于type什么的文档类型声明可写可不写。

  还是推荐将它放在尾部,但是也有很多是放在<head>标签中的。

image-20200724212027898

<script src="./first_js.js" type="application/x-javascript"></script>

代码注释

  Js中的注释有两种,一种单行注释,一种多行注释。

单行注释

  使用//放在语句前,即可完成单行注释。

<script>
        // 下面是个自执行函数
       
        (function (){
                console.log("hello,world");
        })()
</script>

多行注释

  使用/*开头,*/结束,可包含多行。

<script>
        /* 下面是个自执行函数
        它没有参数 */
        
        (function (){
                console.log("hello,world");
        })()
</script>

自动分号

自动分号

  在一段语句结束后,应当加上;号,但是这并不是强制性的而是一种规范。

<script>

        (function (){
                console.log("hello,world");
                alert("hello,world");
                document.write("hello,world");
        })();

</script>

意义作用

  尽管你可以不加,但是请注意前端的代码一般来说在上线部署后都会进行压缩。

  在使用构建工具时,不使用分号结束可能会造成异常!

  我们可以看一下一个非常常见的JsjQuery的生产版源码。

image-20200724214109570

变量声明

  变量就是存储着一个允许变的值。

  如年龄,爱好,居住地等都可以定义为变量。

  变量的使用都是先声明后使用,这个应该是非常基础的,在每个语言中都是这样。

  那么在JavaScript中关于变量声明有很多有意思的点,可以慢慢往下看。

命名规则

  Js中的变量是弱类型可以保存所有类型的数据,即变量没有类型而值有类型。变量名以字母$_开始,后跟字母数字_

  Js中的语言关键字不能用来做变量名,比如 true、if、while、class 等。

  请不要轻易使用用$来作为变量名的起始,因为它被jQuery给霸占了,目前请谨记这一点。

  正确的命名规范

<script>

        var username = "Yunya";
        var _age = 18;
        var $select = "Please do not use $ to start variable names lightly, although it is not wrong";
        
</script>

  错误的命名规范

<script>

        var 9username = "ERROR";
        var (age = "ERROR";
        var --select = "ERROR";
        
</script>

image-20200724220024928

声明赋值

  早期的Js使用者都同一用var来声明变量,但是es6后推出了let,具体的作用我们这里先不管。先看一下最基本的使用,由于Js是一门弱类型语言,所以不用强调变量声明的类型。

  先声明并赋值,后使用

<script>
        
        // 先声明并且赋值
        var username = "YunYa";
        let age = 18;
        // 后使用
        console.log(username);  // YunYa
        console.log(age);  // 18

</script>

  上面是最常用的方式,其实也可以先声明,再赋值,后使用。

<script>

        // 先声明
        var username;
        let age;
        // 再赋值
        username = "YunYa";
        age = 18;
        // 后使用
        console.log(username);  // YunYa
        console.log(age);  // 18

</script>

  我们还可以一次性声明赋值多个变量。

<script>

        var username = "YunYa", age = 18, gender = "male";
        console.log(username);  // YunYa
        console.log(age);  // 18
        console.log(gender);  // male

</script>

  也可以进行链式赋值

<script>

        var a=b=c=1;
        console.log(a);  // 1
        console.log(b);  // 1
        console.log(c);  // 1

</script>

弱类型

  弱类型其实就是说存的是什么类型的值,就是什么类型的变量。

  不用提前声明变量变量再进行存储。

<script>

        var username = "YunYa";
        var age = 18;
        var other = {"hobby":"basketball","marriage":false,"height":192,"weight":126,};

        // typeof 是查看变量的类型方法
        console.log(typeof username);  // string
        console.log(typeof age);  // number
        console.log(typeof other);  // object

</script>

常量声明

  常量存储一些不允许被改变的值。

  PI,性别,籍贯等等都可以定义为常量。

命名规则

  常量的命名规则和变量基本一致,但是一定要注意!常量的命名规则是全部大写形式,这是一种规范。

  常量名建议全部大写

  只能声明一次变量

  声明时必须同时赋值

  不允许再次全新赋值

  可以修改引用类型变量的值

  拥有块、函数、全局作用域

<script>
        // 常量声明全用大写
        const PI = 3.1415926535897;
        console.log(PI);  // 3.1415926535897

</script>

声明赋值

  常量我们一般都会使用const来进行声明并赋值,它有一个特点,即声明之后不允许改变。

<script>
        
        // 常量声明全用大写
        const PI = 3.1415926535897;
        PI = 100;
        console.log(PI); 
        // Uncaught TypeError: Assignment to constant variable.
        // 类型错误: 将值分配给了一个不变的变量(常量)

</script>

var let const 区别

意义作用

  不使用他们会全部乱套,因为有不同的作用域存在,如果不使用他们则代表将所有的变量全部放进全局作用域中。

  代码及易出现问题!

<script>

        username = "YunYa";
 
        function test(params) {

                console.log(username); // YunYa
                username = "Jack";   
                console.log(username); // Jack
        };
        test();

        // 可以看到,被污染了..
        console.log(username); // Jack

</script>
<script>

        var username = "YunYa";
 
        function test(params) {

                console.log(username); // undefined 这是因为自身局部作用域有一个 username,但是此时还未定义。所以不去找全局的name了,只好显示undefined。
                var username = "Jack";   
                console.log(username); // Jack
        };
        test();

        // 可以看到,未污染了..
        console.log(username); // YunYa

</script>

变量提升

  变量提升其实你可以将它当做是预加载,它会预先来检查所有声明的变量名字是否合法。

<script>

        console.log("执行我了...");  // 没执行
        let for = "YunYa";  //  Uncaught SyntaxError: Unexpected token 'for'
        console.log("执行我了...");  // 没执行
        
</script>

  很明显的看到,代码都没执行,但是却抛出异常。这是预加载做的第一步事情,检查名称是否合法。

  当预加载第一步执行完毕后,开始做第二步事情,对var声明的变量进行开辟内存空间(注意:是开辟内存空间,并未赋值,并且letconst声明的变量都不会开辟内存空间)。

  也就是说,当Js代码开始运行时,检查完变量名是否合法后,它会预先拿到所有var声明的变量名的名字(函数名也会),但并不会进行赋值。

  只有当真正开始执行代码并且走到赋值代码时才会进行赋值操作,所以你可以看到下面的这种情况。

<script>

        // 为什么没抛出异常?
        console.log(username)  // undefined
        var username = "YunYa";
        
</script>

  如果使用一个未被定义的名字,那么才是真正的会抛出异常。

<script>

        console.log(age)  // Uncaught ReferenceError: age is not defined
        var username = "YunYa";   
  
</script>

TDZ暂时性死区

  TDZ又称暂时性死区,指变量在作用域内已经存在,但必须在let/const声明后才可以使用。

  TDZ可以让程序保持先声明后使用的习惯,让程序更稳定。

  变量要先声明后使用

  建议使用let/const而少使用var

  使用let/const 声明的变量在声明前存在临时性死区(TDZ)使用会发生错误。

  其实说白了就是letconst来声明的变量必须遵守先声明后使用的原则。

<script>
        
        // 意思就说,不能在完成之前访问name这个变量
        console.log(username)  // Uncaught ReferenceError: Cannot access 'name' before initialization
        let username = "YunYa";   
  
</script>
<script>

        // 意思就说,不能在完成之前访问name这个变量
        console.log(username)  // Uncaught ReferenceError: Cannot access 'username' before initialization
        const username = "YunYa";   
  
</script>

块作用域

  作用域你可以简单的理解为,只要有{}括起来的地方全是作用域,它的作用就是让相同名字的变量名之间互不冲突。

作用域 
全局作用域 变量名全局有效。
局部作用域 变量名在函数,类中有效,可访问全局作用域中的变量。
块作用域 对于var来说不存在,对于let来说则存在,常见for循环,通俗讲只要有不是局部作用域和全局作用域而被{}包裹的代码块全部称为块作用域。

  注意:letconst都具有块作用域,而var则不具有。

  下面例子使用var则会造成污染(会当成全局作用域来看待,不具有块作用域),而使用let则不会(const不可多次赋值应用)。

<script>

        var i = 100;
        for(var i = 0;i < 5;i++){
                console.log(i);  // 0 1 2 3 4 
        }

        // 此时我们在想用 100 的那个 i 抱歉,被替换了。

        console.log(i);  // 5
  
</script>
<script>

        let i = 100;
        for(let i = 0;i < 5;i++){
                console.log(i);  // 0 1 2 3 4 
        }

        // 未替换。

        console.log(i);  // 100
  
</script>

重复定义

  在同一作用域下,使用var定义的变量名可重复定义,而letconst则不可重复定义。

  var

<script>

        var num = 100;
        var num = 1000;

        // 明显不太好

        console.log(num);   // 1000
  
</script>

  let

<script>
        
        // Uncaught SyntaxError: Identifier 'num' has already been declared
        // 语法错误 num 已经被定义
        let num = 100;
        let num = 1000;

        console.log(num); 
  
</script>

  const

<script>

        // Uncaught SyntaxError: Identifier 'num' has already been declared
        // 语法错误 num 已经被定义
        const num = 100;
        const num = 1000;

        console.log(num);   // 1000
  
</script>

windows对象

  使用var定义的变量会被存入windows对象,而letconst却不会。

  var

<script>

        var username = "YunYa";
        console.log(window["username"]);  // YunYa
  
</script>

  let

<script>

        let username = "YunYa";
        console.log(window["username"]);  // undefined
  
</script>

  const

<script>

        const username = "YunYa";
        console.log(window["username"]);  // undefined
  
</script>

差异总结

var let const区别   
  var let const
变量提升
TDZ暂时性死区
块作用域
同一作用域下重复定义 允许 不允许 不允许
windows对象 添加 不添加 不添加
总结:尽量少使用var多使用let   

严格模式

  严格模式可以让我们及早发现错误,使代码更安全规范,推荐在代码中一直保持严格模式运行。

  只需要在书写代码前加上"use strict";即可。

  主流框架都采用严格模式,严格模式也是未来JS标准,所以建议代码使用严格模式开发

基本差异

  变量必须使用关键词声明,未声明的变量不允许赋值。

<script>

        //  Uncaught ReferenceError: username is not defined

        "use strict";
        
        username = "YunYa";  

        console.log(username);

</script>

  关键词不允许做变量使用

<script>

        //  Uncaught SyntaxError: Unexpected token 'try'

        "use strict";
        
        var try = "YunYa";  

        console.log(username);

</script>

  变量参数不允许重复定义

<script>

        //  Uncaught SyntaxError: Duplicate parameter name not allowed in this context

        "use strict";
        
        function test(x,x){
                console.log("执行了...");
        };

        test();

</script>

  单独为函数设置严格模式

<script>
        
        function test(){
                "use strict";
                console.log("执行了...");  // 执行了...
        };

        test();

</script>

  为了在多文件合并时,防止全局设置严格模式对其他没使用严格模式文件的影响,将脚本放在一个执行函数中。

<script>
        
        (function (param) {

                "use strict";
                let url = "www.google.com";
                console.log(url);
                
          })();

</script>

解构差异

  非严格模式可以不使用声明指令,严格模式下必须使用声明。所以建议使用 let等声明。

<script>

        // "use strict"; 
        // 在严格模式下不允许这样使用

        ({ name, other } = { "name":"YunYa-cnblogs","other":"good" });
        console.log(name, other); // YunYa-cnblogs good


</script>
posted @ 2020-07-25 13:30  云崖先生  阅读(600)  评论(2编辑  收藏  举报