JavaScript学习笔记03

JavaScript笔记03

流程控制

if 判断

  • 和 Java 中if语句的使用方法相同。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let score = 90;

        if (score === 100) { // 第一个判断
            alert("great");
        } else if (score >= 60 && score < 100) { // 第二个判断
            alert("pass");
        } else { // 否则...
            alert("fail");
        }
    script>
head>
<body>

body>
html>
  • 查看浏览器弹窗:

JavaScript学习笔记03_第1张图片

while 循环

  • 和 Java 中while循环语句的使用方法相同。
  • 注意:避免使用死循环。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let age = 0;

        while (age < 100) {
            age = age + 1;
            console.log(age);
        }
    script>
head>
<body>

body>
html>
  • 查看浏览器控制台:

JavaScript学习笔记03_第2张图片

  • 补充:do...while...循环
"use strict";
let age = 0;

do {
    age = age + 1;
    console.log(age);
} while (age < 100);

for 循环

  • 和 Java 中for循环语句的使用方法相同。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        for (let i = 0; i < 100; i++) {
            console.log(i);
        }
    script>
head>
<body>

body>
html>
  • 查看浏览器控制台:

JavaScript学习笔记03_第3张图片

forEach 循环

  • forEach()的使用方法参考:JavaScript Array forEach() 方法

  • 在 JavaScript 中,我们可以使用forEach()函数循环遍历数组中的元素。(ES 5.1)

  • 例:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let fruits = ["apple", "banana", "watermelon", "pear", "strawberry"];

        fruits.forEach(function (value) {
            console.log(value);
        });
    script>
head>
<body>

body>
html>
  • 查看浏览器控制台:

JavaScript学习笔记03_第4张图片

for…in 循环

  • for...in的使用方法参考:JavaScript For In
  • 除了forEach()方法,在 JavaScript 中,我们还可以使用for...in语句来循环遍历数组中的元素。
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let fruits = ["apple", "banana", "watermelon", "pear", "strawberry"];

        for (let index in fruits) {
            console.log(fruits[index])
        }
    script>
head>
<body>

body>
html>
  • 查看浏览器控制台:

JavaScript学习笔记03_第5张图片

  • 我们也可以使用for...in语句来循环遍历对象的属性。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let person = {
            name: "张三",
            age: 18,
            gender: "男",
            hobby: "打篮球"
        }

        for (let key in person) {
            console.log(person[key])
        }
        
    script>
head>
<body>

body>
html>
  • 查看浏览器控制台:

JavaScript学习笔记03_第6张图片

for…of 循环

  • for...of语句也能遍历数组。使用方法参考:JavaScript For Of

  • 例:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let fruits = ["apple", "banana", "watermelon", "pear", "strawberry"];

        for (let fruit of fruits) {
            console.log(fruit)
        }
    script>
head>
<body>

body>
html>
  • 查看浏览器控制台:

JavaScript学习笔记03_第7张图片

集合 - Map 和 Set

  • ES6 的新特性~

Map

  • Map对象是键值对的集合。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        // Map和Set   ES6+
        // 学生的名字,学生的成绩
        // let names = ["Tom", "Jerry", "Spike"];
        // let score = [100,90,80];

        // 创建Map对象 - 保存键值对,并且能够记住键的原始插入顺序
        let map = new Map([["Tom", 100], ["Jerry", 90], ["Spike", 80]]);

        // get() - 通过key获得value
        let score1 = map.get("Tom");
        console.log(score1);

        // set() - 为Map对象添加或修改一个键值对
        map.set("Tuffy", 60); // 添加
        console.log(map);

        map.set("Jerry", 95); // 修改
        console.log(map);
        
        // delete() - 删除键值对
        map.delete("Spike");
        console.log(map);
    script>
head>
<body>

body>
html>
  • 查看浏览器控制台:

JavaScript学习笔记03_第8张图片

Set

  • Set对象是值的集合。Set集合中的元素只会出现一次,即集合中的元素是唯一的(可以去重~)。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        // 创建Set对象 - 保存值,并且集合中的元素不重复,有序
        let set = new Set([1, 1, 1, 1, 3, 4, 4, 4]);
        console.log(set);

        // add() - 添加元素
        set.add(2);
        console.log(set);

        // delete() - 删除元素
        set.delete(1);
        console.log(set);

        // has() - 判断Set对象是否包含某个元素
        console.log(set.has(3));
    script>
head>
<body>

body>
html>
  • 查看浏览器控制台:

JavaScript学习笔记03_第9张图片

iterator

  • 使用for...of语句来遍历MapSet集合对象。(ES 6+)

遍历Map对象

  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let map = new Map([["Tom", 100], ["Jerry", 90], ["Spike", 80]]);

        for (let student of map) {
            console.log(student);
        }
    script>
head>
<body>

body>
html>
  • 查看浏览器控制台:

JavaScript学习笔记03_第10张图片

遍历Set对象

  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let set = new Set([1, 1, 1, 1, 3, 4, 4, 4]);

        for (let num of set) {
            console.log(num);
        }
    script>
head>
<body>

body>
html>
  • 查看浏览器控制台:

JavaScript学习笔记03_第11张图片

函数

  • 函数是 JavaScript 中的基本组件之一,它是一组可以随时随地运行的语句。 当一个函数是一个对象的属性时,称之为方法

定义函数

  • 使用function关键字来定义函数。

定义方式一

  • 定义一个取绝对值函数:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        function abs(x) {
            if (x >= 0) {
                return x;
            } else {
                return -x;
            }
        }
    script>
head>
<body>

body>
html>
  • 一旦执行到retrun,函数就将停止执行,返回结果。
  • 打开浏览器控制台,使用我们刚才定义的取绝对值函数abs(),分别传入一个正数和一个负数,查看结果:

JavaScript学习笔记03_第12张图片

  • 补充:如果函数无明确的返回值,或调用了没有参数的return语句, 那么它的返回值为:undefined

定义方式二

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        // 匿名函数 - 没有函数名。
        // 将结果赋值给变量abs,通过abs就可以调用该匿名函数!
        let abs = function (x) {
            if (x >= 0) {
                return x;
            } else {
                return -x;
            }
        }
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,向函数abs()中分别传入一个正数和一个负数,查看结果:

JavaScript学习笔记03_第13张图片

  • 可以发现使用这两种方式来定义函数的效果是一样的。

参数问题

  • 参数问题:JavaScript 可以传任意个参数,也可以不传递参数~
  • 例:
    • 我们打开浏览器控制台,向之前定义的取绝对值函数abs()中分别传入多个参数和不传递参数,查看结果:

JavaScript学习笔记03_第14张图片

  • 可以看到程序依旧成功执行了,且并没有报错或提示出现异常。规避参数不存在的问题

规避参数不存在的问题

  • 我们可以通过手动判断并抛出异常的方式来规避参数不存在的问题。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let abs = function (x) {
            // 手动抛出异常
            if (typeof x != "number") { // typeof - 返回一个字符串,表示操作数的类型
                throw "Not a Number";
            }
            if (x >= 0) {
                return x;
            } else {
                return -x;
            }
        }
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,不向函数abs()中传递任何参数,查看结果:

JavaScript学习笔记03_第15张图片

  • 可以看到程序提示了我们手动定义的异常Not a Number

arguments

  • arguments是一个对应于传递给函数的参数的类数组对象。它代表传递进函数的所有参数,是一个数组。参考:Arguments 对象 - JavaScript
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let abs = function (x) {
            console.log("x=>"+x);

            for (let i = 0; i < arguments.length; i++) {
                console.log(arguments[i]);
            }
            
            if (x >= 0) {
                return x;
            } else {
                return -x;
            }
        }
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,给abs()函数传入多个参数,查看结果:

JavaScript学习笔记03_第16张图片

剩余参数 - rest

  • 剩余参数语法允许我们将一个不定数量的参数表示为一个数组。 (ES 6+)
  • 剩余参数只能写在所有参数的最后面,用...标识。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        let aaa = function (x, y, ...rest) {
            console.log("x=>" + x);
            console.log("y=>" + y);
            console.log("rest=>" + rest);
        }
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,给aaa()函数传入分别传入一个,两个以及多个参数,查看结果:

JavaScript学习笔记03_第17张图片

变量的作用域

  • 在 JavaScript 中,var定义的变量实际是有作用域的。

局部变量

  • 语句块中声明的变量将成为语句块所在函数的局部变量。
  • 假设在函数体中声明,则在函数体外不可以使用 ~( 如果非要在函数体外引用的话,需要使用 闭包
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        function abc() {
            var x = 1;
            x = x + 1;
        }

        x = x + 2; // Uncaught ReferenceError: x is not defined
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,发现程序报错:Uncaught ReferenceError: x is not defined

JavaScript学习笔记03_第18张图片

  • 如果两个函数使用了相同的变量名,只要都在函数内,就不冲突。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        function abc() {
            var x = 1;
            x = x + 1;
        }

        function xyz() {
            var x = 10086;
            x = x + 1;
        }
    script>
head>
<body>

body>
html>
  • 函数abc()和函数xyz()都使用了x作为变量名,但都在函数体内,所以两者的变量名不会发生冲突,程序能够正常运行,不会报错。
  • 内部函数可以访问外部函数的成员,反之则不行。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        function abc() {
            var x = 1;

            function xyz() {
                var y = x + 1; // 2
            }

            var z = y + 1; // Uncaught ReferenceError: z is not defined
        }
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,输入console.log(z);,查看结果:

JavaScript学习笔记03_第19张图片

  • 假设内部函数和外部函数的变量重名。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        function abc() {
            var x = 1;

            function xyz() {
                var x = "A";
                console.log("inner => " + x);
            }
            console.log("outer => " + x);
            xyz(); // inner => A
        }
        abc(); // outer => 1
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,查看结果:

JavaScript学习笔记03_第20张图片

  • 在 JavaScript 中,函数会从自身开始,由内向外查找变量,假设外部存在这个同名的函数变量,则内部函数会屏蔽外部函数的变量(双亲委派机制)。

提示变量的作用域

  • 我们先来看以下代码:
    • 我们将需要调用变量y的语句写在变量y的声明与赋值语句之前:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        function abc() {
            var x = "x" + y;
            console.log(x);
            var y = "y";
        }
        abc(); // xundefined
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,查看结果:

JavaScript学习笔记03_第21张图片

  • 原因:JavaScript 的执行引擎自动提升了变量y的声明,但却不会提升变量y的赋值。这是在 JavaScript 建立之初就存在的特性。
  • 由于 JavaScript 存在以上的特性,所以我们在编码过程中要规范书写顺序,用到的变量必须是前面定义过的,不要乱放,以便代码维护。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        function xyz() {
            var x = 10,
                y = 3,
                z,i; // undefined

            z = x + y;
            i = x - y;
            console.log(z);
            console.log(i);
        }
        xyz();
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,查看结果:

JavaScript学习笔记03_第22张图片

全局变量

  • 在函数之外声明的变量,叫做全局变量,它可被当前文档中的任何其他代码所访问。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        var x = 1;
        function f() {
            console.log(x);

        }
        f();
        console.log(x);
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,查看结果:

JavaScript学习笔记03_第23张图片

全局对象 - window

  • window对象表示一个浏览器窗口或一个框架。在 JavaScript 中,window对象是全局对象,所有的表达式都在当前的环境中计算。 也就是说在 JavaScript 中,默认所有的全局变量都会自动绑定在window对象下。(函数本身也可以是变量)
  • 例如:我们常用的弹窗函数alert()就可以写成window.alert();同样的,我们定义的全局变量x也可以写作window.x
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        var x = 1;
        // 以下三种写法的表示的效果是相同的
        alert(x);
        window.alert(x);
        window.alert(window.x);
    script>
head>
<body>

body>
html>
  • 这三种写法的表示的效果是相同的:

JavaScript学习笔记03_第24张图片

  • 大胆尝试:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        "use strict";
        var x = "xxx";

        window.alert(x);

        var old_alert = window.alert;

        // old_alert(x);

        window.alert = function () {

        };

        // 发现alert()失效了
        window.alert(123);

        // 恢复
        window.alert = window.old_alert;
        window.alert(456);
    script>
head>
<body>

body>
html>
  • 以上尝试说明了 JavaScript 实际上只有一个全局作用域(window),任何变量(函数本身也可以作为变量),假设在函数作用范围内没有找到,就会向外查找。如果在全局作用域(window)中都没有找到,那么就会报错:ReferenceError(引用异常)
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        window.alert(x);
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,查看结果:

JavaScript学习笔记03_第25张图片

规范

  • 由于在 JavaScript 中,我们所有的全局变量都会绑定到window对象上。所以如果我们的项目中同时存在多个 js 文件,且它们之中使用了同名的全局变量,就会产生冲突。那么,我们应该如何减少这样的冲突呢?
  • 我们可以自己定义一个唯一全局变量来代替window对象,把自己的代码全部放进自己定义的唯一的空间名字中,通过这种方式来减少全局命名冲突的问题( jQuery 就是使用的这种方式 )。例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        // 唯一全局变量
        var MyApp = {};

        // 定义全局变量
        MyApp.name = "clown";
        MyApp.add = function (a, b) {
            return a + b;
        }
    script>
head>
<body>

body>
html>

局部作用域 - let

  • 我们先来看一个例子 - 在for循环体中使用var定义变量,然后我们再在循环体外调用这个变量:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        function aaa() {
            for (var i = 0; i < 100; i++) {
                console.log(i);
            }
            console.log(i + 1);
        }
        aaa();
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,查看结果:

JavaScript学习笔记03_第26张图片

  • 我们发现,使用var定义变量时,即使除了循环体,我们也能调用到在循环体中定于的变量。这就说明发生了作用域冲突问题。
  • 为了解决作用域冲突这一问题,于是在 ES 6 就新推出了一个关键字:let。通过它,就能解决作用域冲突问题。它和var的区别在于:var定义的变量在其所在的整个函数体内都是可以被调用的,而let定义的变量只在其所在的语句块里可以被调用。
  • 下面我们把上面代码中的var改为let
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        function aaa() {
            for (let i = 0; i < 100; i++) {
                console.log(i);
            }
            console.log(i + 1); // Uncaught ReferenceError: i is not defined
        }
        aaa();
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,查看结果:

JavaScript学习笔记03_第27张图片

  • 我们发现:在使用let定义循环体中的变量之后,循环体外的语句便不能再调用它了,作用域冲突问题得到了解决。
  • 所以,建议在编程过程中都使用let来定义局部作用域中的变量。

常量 - const

  • let一样,const也是 ES 6 推出的新特性。
  • 在 ES 6 推出之前,常量的定义方式:变量名的字母全部为大写字母的变量就代表常量(通过这种方法定义的 “常量” 本质上还是一个变量,它的值是可以被修改的)。所以如果我们在工作过程中见到了这样的变量名全部定义为大写的变量,建议不要去随意修改它的值,因为很可能它表示的是一个常量。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        // 在 ES6 推出之前,约定俗成,名字全部用大写字母表示的变量,就代表它为常量
        var PI = 3.14;
        PI = 2;
        console.log(PI); // 这样定义的常量的值其实是可以被改变的
    script>
head>
<body>

body>
html>
  • 打开浏览器控制台,查看结果:

JavaScript学习笔记03_第28张图片

  • 所以,为了解决上述问题,规范编码,在 ES 6 中就推出了关键字 - const,用来定义常量(只读变量)。
  • 例:
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
    <script>
        // 在 ES6 推出了 const 关键字,用来定义只读变量(常量)
        const PI = 3.14;
        PI = 2; // Uncaught TypeError: Assignment to constant variable.
        console.log(PI);
    script>
head>
<body>

body>
html>
  • 我们可以发现 IDEA 会报错并提示我们该变量值是只读的,不允许修改:

JavaScript学习笔记03_第29张图片

  • 运行:发现程序报错:Uncaught TypeError: Assignment to constant variable.

JavaScript学习笔记03_第30张图片

你可能感兴趣的:(javascript,学习,笔记)