基础知识

起步入门

语言介绍


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

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

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

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

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

适用场景

  • 浏览网页端开发
  • 做为服务器后台语言开发Node.js
  • 移动端手机APP开发,如Facebook的ReactNative ,uniapp ,PhoneGap,IONIC
  • 跨平台的桌面应用程序,如使用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,ECMAScript202

  • ....
    从2015年开始 tc39 委员会决定每年发布一个行的ECMAScript版本

学习准备

浏览器

本文章中会讲到新的JS课程,所以请使用Chrime 或 firefox浏览器来进行学习。

编辑器

推荐使用 vscode 编辑器开始学习,你可能需要安装一些插件长可以高效使用,可以百度进行安装自己需要的插件。

运行流程

所有内容需要在特定的环境中运行,就像PSD需要在类似PS的软件处理一样。浏览器内置了处理的JS的解析器,但不同浏览器的性能不同,所以JS一般都在浏览器中执行,当然也有可以在服务器后台执行的JS解析器。

JS请求处理步骤如下:


image

脚本定义

内嵌脚本

像style标签一样,可以使用html文档中使用script标签嵌入javascript代码。


外部文件

通过设置 src 属性引入外部js文件。


引入外部文件在标签体内的脚本不会执行,下面的alert弹窗不会执行


避免延迟

如果js放在 标签中要等到js加载并解析后才会显示 标签中的内容。

延迟体验


    
        第一个js学习项目
        
    
    
        

要不我偷电瓶养你

1.js内容如下

alert('你养我吗?');

h1会在1.js加载并解析后才会显示。

推荐做法

为了解决上面的问题,可以讲js放在 body标签下方


        

要不我偷电瓶养你

代码注释

和大部分语言使用的注释方式相仿,有单行和多行注释。

单行注释


多行注释


自动分号

使用分号表示一段指令结束,当没有输入分号是如果有换行付JS会自动添加分号,减少错误的发生。

  • 但推荐每个指令都以分号结束
  • 在使用构建工具是,不适用分号结束可能会造成异常
            let stat = true;
            if (stat) {
                document.write('xhspay.cn');
            }

变量声明

命名规范

js中的变量是弱类型可以保存所有类型的数据,即变量没有类型而值有类型。变量名以字母,$, _ 开始,后跟字母,数字,_。
下面都是合法的命名

let name = 'heishan';
let $= 'heishan';

JS语言关键字不能用来做为变量名,比如 true,if,while,class 等。

let class = 'heishan';

变量声明

可以适用多种方式定义变量如var,let等 (后面作用域章节会再讨论变量)。

let name = 'heishan';

以上代码是声明和赋值的结合

let name;
name = 'heishan';

变量其他细节使用会在函数,对象等章节中体验

使用,后可以同时声明多个变量

let n = 2,b = 3;
console.log(b);

下面演示变量可以更换不同的数据

let hd = 'xhs';
console.log(typeof hd);
hd = 123;
console.log(typeof hd);

弱类型

在JS中变量类型由所引用的值决定

var web = "hdcms";
console.log(typeof web); //string
web = 99;
console.log(typeof web); //number
web = {};
console.log(typeof web); //object

变量提升

解析器会先解析代码,然后把声明的变量的声明提升到最前,这就叫做变量提升。

下面代码在解析过程中发现while不能做为变量名,没有到执行环节就出错了,这是一个很好的解析过程的体验。

 var web = 'heishan';
console.log(web)
let while = 'xiaoheishan'; //Uncaught SyntaxError: Unexpected token while

使用var 声明代码会被提升到前面

console.log(a);
var a = 1;
console.log(a)
以上代码执行过程如下
var a;
console.log(a);
a = 1;
console.log(a);

下面 if(false) 中定义的var也会发生变量提升,注释掉 if 结果会不同

            var web = 'heishan';
            function hd(){
                if (false){
                    var web = "黑山";
                }
                console.log(web);
            }
            hd();

使用 var 定义的代码,声明会被提升到前面,赋值还在还原位置

            var web = 'heishan';
            function hd(){
                if (false){
                    var web = "黑山";
                }
                console.log(web);
            }
            hd();

TDZ

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

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

  • 变量要先声明后使用
  • 建议使用let/const 而少使用var
    使用 let/const 声明的变量在声明前存在临时性死区(TDZ)使用会发生错误
 console.log(x);
 let x = 1; //Uncaught ReferenceError: x is not defined

在 run 函数作用域中产生TDZ ,不允许变量在未声明前使用。

            hd = 'houdunren';
            function run(){
                console.log(hd);
                let hd = 'heishan';
            }
            run();  //Uncaught ReferenceError: hd is not defined

下面的代码b没有声明赋值不允许直接使用


            function hd (a = b, b = 3){}
            hd() //Uncaught ReferenceError: b is not defined

因为a已经赋值,所以b可以使用a变量,下面代码访问正常

function hd(a = 2, b= a){}
hd();

块作用域

共同点

var/let/const 共同点是全局作用域中定义的变量,可以在函数中使用

        var hs = 'hscms';
        function show(){
            return hs;
        }
        console.log(show())

函数中声明的变量,只能在函数及其子函数中使用

        function hs(){
            var web = '黑山';
            function show(){
                console.log(web);
            }
            show(); //子函数结果:黑山
            console.log(web);   //函数结果:黑山

        }
        hs();    
        console.log(web); //web is not defined

函数中声明的变量就像声明了私有领地,外部无法访问

        var web = 'xhspay.cn';
        function hs(){
            var web = "houdunren.com";
            console.log(web);   //houdunren.com
        }
        hs();
        console.log(web);   //xhspay.cn

var

使用 var 声明的变量存在于最近的函数或全局作用域中,没有块级作用域的机制。
没有块作用域很容易污染全局,下面函数的变量污染了全局环境

function run(){
    web = 'heishan';
}
run();
console.log(web);  //heishan

没有块作用域时var也会污染全局

          for(var i = 0;i<10; i++){
            console.log(i);
        }
        console.log(i)

使用 let 有块作用域时则不会

         let i = 100;
        for (let i = 0; i<10; i++){
            console.log(i);
        }
        console.log(i);

下列中体验到 var 没有块作用域概念,do/while 定义的变量可以在块外部访问到

        var num = 0;
        function show(){
            var step = 10;
            do {
                var res =0;
                console.log(num = step++);
                res = num;
            }while (step < 20);
            console.log(`结果是${res}`);
        }
        show()

var 全局声明的变量也存在于 windows对象中

        var hs = 'heishan';
        console.log(window.hs);

以往没有块任用时使用立即执行函数模拟块作用域

        (function() {
            var $ = this.$ ={};
            $.web = '黑山';
        }.bind(window)());
        console.log($.web);

有了块作用域后实现就变得简单多了

{
            let $ =(window.$ ={});
            $.web = "黑山";
        }
        console.log($.web);

let

与 var 声明的区别是 let/const 拥有块作用域,下面代码演示了块外部是无法访问到let声明的变量。

  • 建议讲 let 在代码块前声明
  • 用逗号分隔定义多个
    let 存在块作用域特性,变量只在块作用域中有效
        if(true){
            let web = 'hscms' ,url = 'xhspay.cn';
            console.log(web); //hscms
        }
        console.log(web);   //web is not defined

块内部是可以访问到上层作用域的变量

        if (true) {
        let user = "向军大叔";
        (function() {
        if (true) {
            console.log(`这是块内访问:${user}`);
        }
        })();
        }
        console.log(user);

每一层都是独立作用域,里层作用域可以声明外层作用域同名变量,但不会改变外层变量

        function run() {
        hd = "houdunren";
        if (true) {
            let hd = "hdcms";
            console.log(hd); //hdcms
        }
        console.log(hd); //houdunren
        }
        run();

const

使用 const 用来声明常量,这与其他语言差别不打,比如可以用来声明后台接口的URL地址

  • 常量名建议全部大写
  • 只能声明一次变量
  • 声明时必须同时赋值
  • 不允许再次全新赋值
  • 可以修改应用类型变量的值
  • 拥有块, 函数 ,全局作用域
    常量不允许全新赋值举例
          try {
        const URL = "https://www.houdunren.com";
        URL = "https://www.hdcms.com"; //产生错误
        } catch (error) {
        throw new Error(error);
        }

改变常量的引用类型值

const INFO = {
  url: 'https://www.houdunren.com',
  port: '8080'
};
INFO.port = '443';
console.log(INFO);

下面演示了在不同作用域中可以重名定义常量

const NAME = '后盾人';

function show() {
  const NAME = '向军大叔';
  return NAME;
}
console.log(show());
console.log(NAME);

重复定义

使用var可能造成不小心定义了同名变量

        var price = 90;
        var price = 100;
        console.log(`商品优惠券是:${price}`);

使用 let 可以避免上面的问题,因为let声明后的变量不允许在同一作用域中重新声明

        let web = 'heishan';
        let web = '黑山';   //Identifier 'web' has already been declared

不同作用域可以重新声明

        let web = 'heishan';
        if (true){
            let web = '黑山';
        }

但可以改变值这是与const不同点

        let price = 80;
        price = 99;
        console.log(`值改变了:${price}`);

let 全局声明的变量不存在于 window 对象中,这与 var 声明不同

       let hs = 'heishan';
       console.log(window.hs)  //undefined

Object.freeze

如果冻结变量后,变量也可以修改了,使用严格模式会报错。

        "use strict"
        const INFO = {
            url: 'www.xhspay.cn',
            port: '8080'
        };
        Object.freeze(INFO);
        INFO.port = '443';  //Cannot assign to read only property 'port' of object '#'
        console.log(INFO)

传值与传址

基本数据类型指数值,字符串等简单数据类型。引用类型指对象数据类型。

类型的详细介绍会在后面章节讲解
基本类型复制是值的复制,互相不受影响。下列中a变量的值赋值给b变量后,因为基本类型变量是独立的所以a的改变不影响b变量的值。

        let a = {
            web : '黑山'
        };
        let b = a;
        a.web = "hscms";
        console.log(b);

undefined

对声明但未赋值的变量返回类型未 undefined 表示值未定义

        let hd;
        console.log(typeof hd);     //undefined

对未声明的变量使用会报错,但判断类型将会显示 undefined

        console.log(typeof heishan);  //undefined
        console.log(heishan);    //Uncaught ReferenceError: heishan is not defined

我们发现未赋值与未定义的变量值都为 undefined ,建议声明变量设置初始值,这样就可以区分出变量状态了。

函数参数或无返回值是为 undefined

       function hs(web){
           console.log(web); //undefined
           return web;
       }
       console.log(hs()); //undefined

null

null 用于定义一个空对象,即如果变量要用来保存引用类型,可以在初始化时将其设置为null

   var hd = null;
   console.log(typeof hd);

严格模式

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

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

基本差异

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

        "use strict";
        url = "heishan";    //url is not defined

强制声明防止污染全局

        function run(){
            web = 'heishan';
        }
        run();
        console.log(web);   //web is not defined

关键词不允许做变量使用

        "use strict";
        var public = "heishan";     //Unexpected strict mode reserved word

变量参数不允许重复定义

        "use strict";
        function hd(name, name){}   // Duplicate parameter name not allowed in this context

单独为函数设置严格模式

        function strict(){
            "use strict";
            return "严格模式";
        }
        function notStrict(){
            return "正常模式";
        }

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

        (function (){
            "use strict";
            url = "xhspay.cn";
        })();

结构差异

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

        // "use strict";
        ({name,url} = {name: 'heishan',url: 'xhspay.cn'});
        console.log(name,url)

使用严格模式编码总是缓存的

本文产考后盾人

你可能感兴趣的:(基础知识)