文献

JS 基础知识

概论

  • JavaScript = ECMAScript (标准) + JavaScript 自己特有的东西(BOM+DOM)

  • JavaScript 是阻塞式的。

  • 注释:///* */

  • 变量:一小块存储数据的内存空间。JS 是弱类型语言,Java 是强类型语言

    • 强类型:在开辟变量存储空间时,定义了空间将来存储数据的数据类型。只能存储固定类型的数据。
    • 弱类型:在开辟变量存储空间时,不定义空间将来的存储数据类型,可以存放任意类型的数据。
    • 语法:var 变量名 = 初始值;
    • document.write(" " +"<br>"):输出变量到页面并换行
    • typeof(变量):返回变量的类型
  • 特殊语法:

    • 语句以; 结尾,如果一行只有一条语句则 ; 可以省略 (不建议)
    • 使用 var 关键字定义的变量是局部变量,不使用的为全局变量(不建议)
  • JS 中的 switch 可以接收任意类型。

运算符

  • 一元运算符:++、–、+(正号)、-(负号)

    • JS 中,如果运算数不是运算符所要求的类型,那么 js 引擎会自动的将运算数进行类型转换。
    • string 转 number :按照字面值转换。如果字面值不是数字,则转为 NaN(不是数字的数字),+"123" 会被转换为 123(number)
    • boolean 转 number :true 转为 1,false 转为 0
    • number 与 string 进行+ 运算,结果为 string 类型
  • 算数运算符:+、-、*、/、%

  • 赋值运算符:=、+=、-=

  • 比较运算符:>、<、>=、<=、=(全等于)

    • 字符串按照字典顺序比较。按位逐一比较,直到得出大小为止。
    • 类型不同的时候会先进行类型转换,再比较,字符串和数字比较会把字符串转换为数字,"123"==123,结果为 true
    • == 会进行 类型转换再比较,=== 则比较严格,类型不等返回 false
  • 逻辑运算符:&&、||、!,具有短路效果

    • 其他类型转 boolean
      • number:0 或 NaN 为假,其他为真
      • string:除了空字符串(“”),其他都为真
      • null 和 undefined:都是假
      • 对象:都为 true
    • undefined && false 结果为 undefined,能转换为 boolean,但不能进行运算。
  • 三元运算符:和 Java 一样,表达式? 值1:值2;,判断表达式的值,如果是 true 则取值 1,如果是 false 则取值 2。

JS 字符串方法

  • length 属性返回字符串的长度。

    var txt = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    var sln = txt.length;
    
    • indexOf() 方法返回字符串中指定文本首次出现的索引(位置)
    • lastIndexOf() 方法返回指定文本在字符串中最后一次出现的索引
    • 都可接受第二个参数作为检索起始位置
    • 未找到均返回 -1
  • search() 方法搜索特定值的字符串,并返回匹配的位置,无法设置第二个参数

  • slice() 提取字符串的某个部分并在新字符串中返回被提取的部分。

    • 该方法设置两个参数:起始索引(开始位置),终止索引(结束位置)。
    • 如果某个参数为负,则从字符串的结尾开始计数。
    • 如果省略第二个参数,则该方法将裁剪字符串的剩余部分
  • substring() 类似于 slice(),不同之处在于 substring() 无法接受负的索引。

  • substr() 类似于 slice()

    • 不同之处在于第二个参数规定被提取部分的长度。
    • 如果省略第二个参数,则该 substr() 将裁剪字符串的剩余部分。
    • 如果首个参数为负,则从字符串的结尾计算位置。
  • replace() 方法用另一个值替换在字符串中指定的值

    • replace() 方法不会改变调用它的字符串。它返回的是新字符串。

    • 默认地,replace() 只替换首个匹配。

    • 默认地,replace() 对大小写敏感。

    • 如需执行大小写不敏感的替换,请使用正则表达式 /i(大小写不敏感):

      str = "Please visit Microsoft!";
      var n = str.replace(/MICROSOFT/i, "W3School");
      
    • 如需替换所有匹配,请使用正则表达式的 g 标志(用于全局搜索):

      str = "Please visit Microsoft and Microsoft!";
      var n = str.replace(/Microsoft/g, "W3School");
      
  • 通过 toUpperCase() 把字符串转换为大写

  • 通过 toLowerCase() 把字符串转换为小写

  • concat() 连接两个或多个字符串

  • trim() 方法删除字符串两端的空白符

  • charAt() 方法返回字符串中指定下标(位置)的字符串

  • charCodeAt() 方法返回字符串中指定索引的字符 unicode 编码

  • 属性访问[]

    var str = "HELLO WORLD";
    str[0];       // 返回 H
    
    • 如果找不到字符,[ ] 返回 undefined,而charAt() 返回空字符串。
    • 它是只读的。str[0] = “A” 不会产生错误(但也不会工作!)
  • split() 将字符串转换为数组

JS 数字

  • Infinity (或 -Infinity)是 JavaScript 在计算数时超出最大可能数范围时返回的值
    • 除以 0(零)也会生成 Infinity
    • Infinity 是数:typeOf Infinity 返回 number
  • JavaScript 会把前缀为 0x 的数值常量解释为十六进制。
  • Javascript 把数显示为十进制小数,但是能够使用toString(base) 方法把数输出为十六进制、八进制或二进制。

JS 数值方法

  • toString() 以字符串返回数值,可以由参数决定返回什么进制

  • toExponential() 返回字符串值,它包含已被四舍五入并使用指数计数法的数字。

  • toFixed() 返回字符串值,它包含了指定位数小数的数字

  • toPrecision() 返回字符串值,它包含了指定长度的数字

    var x = 9.656;
    x.toPrecision();        // 返回 9.656
    x.toPrecision(2);       // 返回 9.7
    x.toPrecision(4);       // 返回 9.656
    x.toPrecision(6);       // 返回 9.65600
    
  • valueOf() 以数值返回数值,所有 JavaScript 数据类型都有 valueOf()toString() 方法。

  • Number() 可用于把 JavaScript 变量转换为数值,如果无法转换数字,则返回 NaN。还可以把日期转换为数字

  • parseInt() 解析一段字符串并返回数值。允许空格。只返回首个数字。全局方法

  • parseFloat() 解析一段字符串并返回数值。允许空格。只返回首个数字。全局方法

  • 数值属性

    属性 描述
    MAX_VALUE 返回 JavaScript 中可能的最大数。
    MIN_VALUE 返回 JavaScript 中可能的最小数。
    NEGATIVE_INFINITY 表示负的无穷大(溢出返回)。
    NaN 表示非数字值(“Not-a-Number”)。
    POSITIVE_INFINITY 表示无穷大(溢出返回)。
    var x = Number.MAX_VALUE;
    

JS 数组

  • length 属性返回数组的长度(数组元素的数目)。
  • sort() 数组排序
  • push() 添加数组元素
  • 判断是否是数组
    • Array.isArray()
    • fruits instanceof Array

数组方法

  • toString() 把数组转换为数组值(逗号分隔)的字符串。

  • join() 方法也可将所有数组元素结合为一个字符串。它的行为类似 toString(),但是您还可以规定分隔符

  • pop() 方法从数组中删除最后一个元素,返回“被弹出”的值

  • push() 方法(在数组结尾处)向数组添加一个新的元素,返回新数组的长度

  • shift() 方法会删除首个数组元素,并把所有其他元素“位移”到更低的索引。返回被“位移出”的元素

  • unshift() 方法(在开头)向数组添加新元素,并“反向位移”旧元素,返回新数组的长度

  • delete 运算符删除元素

    var fruits = ["Banana", "Orange", "Apple", "Mango"];
    delete fruits[0];           // 把 fruits 中的首个元素改为 undefined
    
    • 使用 delete 会在数组留下未定义的空洞。
  • splice(index,length) 可以用来删除元素,并且不留黑洞

  • splice() 方法可用于向数组添加新项

    var fruits = ["Banana", "Orange", "Apple", "Mango"];
    fruits.splice(2, 0, "Lemon", "Kiwi");
    
    • 第一个参数(2)定义了应添加新元素的位置(拼接)。
    • 第二个参数(0)定义应删除多少元素。
    • 其余参数(“Lemon”,“Kiwi”)定义要添加的新元素。
    • splice() 方法返回一个包含已删除项的数组
  • concat() 方法通过合并(连接)现有数组来创建一个新数组

    • 不会更改现有数组。它总是返回一个新数组
  • slice() 方法用数组的某个片段切出新数组,它不会从源数组中删除任何元素

    • 可接受两个参数,该方法会从开始参数选取元素,直到结束参数(不包括)为止。
  • reverse() 方法反转数组中的元素。

  • 数字排序,默认地,sort() 函数按照字符串顺序对值进行排序。正因如此,sort() 方法在对数值排序时会产生不正确的结果。通过如下方式来解决

    var points = [40, 100, 1, 5, 25, 10];
    points.sort(function(a, b){return a - b});
    
  • 寻找数组中最大最小值

    Math.max.apply(null, arr);
    Math.min.apply(null, arr);
    
  • forEach() 方法为每个数组元素调用一次函数(回调函数)。该函数接受 3 个参数,项目值、项目索引、数组本身

  • map()

    • map() 方法通过对每个数组元素执行函数来创建新数组。
    • map() 方法不会对没有值的数组元素执行函数。
    • map() 方法不会更改原始数组。
    • 该函数接受 3 个参数,项目值、项目索引、数组本身
  • filter() 方法创建一个包含通过测试的数组元素的新数组。该函数接受 3 个参数,项目值、项目索引、数组本身

  • reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]) 在每个数组元素上运行函数,以生成(减少它)单个值。方法不会减少原始数组。

    • 请注意回调函数接受 4 个参数:总数(初始值/先前返回的值)、项目值、项目索引、数组本身
    • reduce() 方法能够接受一个初始值
    • 如果传入初始值 initialValue,则会以此为初始值循环,index 起始索引为 0
    • 如果不传入初始值,则会以第一个元素为初始值,index 起始索引为 1
  • reduceRight()reduce() 类似,方向相反

  • every() 方法检查所有数组值是否通过测试。

  • some() 方法检查某些数组值是否通过了测试。

  • find() 方法返回通过测试函数的第一个数组元素的值。

  • findIndex() 方法返回通过测试函数的第一个数组元素的索引。

JS 日期

  • Date() 对象的构造方法

    • new Date()

    • new Date(year, month, day, hours, minutes, seconds, milliseconds)

    • new Date(milliseconds)

    • new Date(date string)

      var d = new Date("2018-02-19");
      var d = new Date("2018/02/19");
      
  • 日期获取方法

    方法 描述
    getDate() 以数值返回天(1-31)
    getDay() 以数值获取周名(0-6)
    getFullYear() 获取四位的年(yyyy)
    getHours() 获取小时(0-23)
    getMilliseconds() 获取毫秒(0-999)
    getMinutes() 获取分(0-59)
    getMonth() 获取月(0-11)
    getSeconds() 获取秒(0-59)
    getTime() 获取时间,毫秒(从 1970 年 1 月 1 日至今)
  • 可以通过 set 开设置日期,比如 setDay()

Math 对象

  • Math.PI
  • 方法 描述
    abs(x) 返回 x 的绝对值
    acos(x) 返回 x 的反余弦值,以弧度计
    asin(x) 返回 x 的反正弦值,以弧度计
    atan(x) 以介于 -PI/2 与 PI/2 弧度之间的数值来返回 x 的反正切值。
    atan2(y,x) 返回从 x 轴到点 (x,y) 的角度
    ceil(x) 对 x 进行上舍入
    cos(x) 返回 x 的余弦
    exp(x) 返回 Ex 的值
    floor(x) 对 x 进行下舍入
    log(x) 返回 x 的自然对数(底为e)
    max(x,y,z,…,n) 返回最高值
    min(x,y,z,…,n) 返回最低值
    pow(x,y) 返回 x 的 y 次幂
    random() 返回 0 ~ 1 之间的随机数
    round(x) 把 x 四舍五入为最接近的整数
    sin(x) 返回 x(x 以角度计)的正弦
    sqrt(x) 返回 x 的平方根
    tan(x) 返回角的正切

JS 逻辑

  • 所有不具有“真实”值的即为False
  • 0、-0、“”、undefined、null、false、NaN 都为false

JS switch

  • JS 的 Switch 使用 === 严格比较

JS 类型

JavaScript 中有五种可包含值的数据类型:

  • 字符串(string)
  • 数字(number)
  • 布尔(boolean)
  • 对象(object)
  • 函数(function)

有三种对象类型:

  • 对象(Object)
  • 日期(Date)
  • 数组(Array)

同时有两种不能包含值的数据类型:

  • null
  • undefined

JS 类型转换

  • constructor 属性返回所有 JavaScript 变量的构造器函数。

    • 可以通过检查 constructor 属性来确定某个对象是否为数组(包含单词 “Array”)

      function isArray(myArray) {
          return myArray.constructor.toString().indexOf("Array") > -1;
      }
      
    • 或者更简单,您可以检查对象是否是数组函数:

      function isArray(myArray) {
          return myArray.constructor === Array;
      }
      
  • 转换为字符串

    • String()
    • toString()
  • 字符串转换为数值

    • Number()
    • parseInt() 全局方法
    • parseFloat() 全局方法
  • JS 类型转换表

    原始值 转换为数字 转换为字符串 转换为逻辑
    false 0 “false” false
    true 1 “true” true
    0 0 “0” false
    1 1 “1” true
    “0” 0 “0” true
    “000” 0 “000” true
    “1” 1 “1” true
    NaN NaN “NaN” false
    Infinity Infinity “Infinity” true
    -Infinity -Infinity “-Infinity” true
    “” 0 “” false
    “20” 20 “20” true
    “twenty” NaN “twenty” true
    [ ] 0 “” true
    [20] 20 “20” true
    [10,20] NaN “10,20” true
    [“twenty”] NaN “twenty” true
    [“ten”,“twenty”] NaN “ten,twenty” true
    function(){} NaN “function(){}” true
    NaN “[object Object]” true
    null 0 “null” false
    undefined NaN “undefined” false

JS 正则表达式

  • 语法

    /pattern/modifiers;
    // 实例
    var patt = /w3school/i;
    
    • /w3school/i 是一个正则表达式。
    • w3school 是模式(pattern)(在搜索中使用)。
    • i 是修饰符(把搜索修改为大小写不敏感)。
  • 在 JavaScript 中,正则表达式常用于两个字符串方法:search() 和 replace()。

  • 修饰符 描述
    i 执行对大小写不敏感的匹配。
    g 执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
    m 执行多行匹配。
  • test() 是一个正则表达式方法。它通过模式来搜索字符串,然后根据结果返回 true 或 false。

  • exec() 方法是一个正则表达式方法。它通过指定的模式(pattern)搜索字符串,并返回已找到的文本。如果未找到匹配,则返回 null。

JS this

  • this 关键词指的是它所属的对象
  • 在方法中,this 指的是所有者对象。
  • 单独的情况下,this 指的是全局对象。
  • 在函数中,this 指的是全局对象。
  • 在函数中,严格模式下,this 是 undefined。
  • 在事件中,this 指的是接收事件的元素。

JS 函数

  • 函数自调用

    • 自调用表达式是自动被调用(开始)的,在不进行调用的情况下。
    • 函数表达式会自动执行,假如表达式后面跟着 ()。
    • 您需要在函数周围添加括号,以指示它是一个函数表达式
    (function () {
        var x = "Hello!!";      //我会调用我自己
    })();
    
  • 函数默认值

    ES6 允许函数参数具有默认值:

    function myFunction(x, y = 10) {
      // y is 10 if not passed or undefined
      return x + y;
    }
    myFunction(5); // 将返回 15
    
  • call() 方法可以改变函数的 this 指向,也可以携带参数

    var person = {
      fullName: function(city, country) {
        return this.firstName + " " + this.lastName + "," + city + "," + country;
      }
    }
    var person1 = {
      firstName:"Bill",
      lastName: "Gates"
    }
    person.fullName.call(person1, "Seattle", "USA");
    
    // 结果为 Bill Gates,Seattle,USA
    
  • apply() 方法与 call() 方法非常相似,不同之处是

    • call() 方法分别接受参数。
    • apply() 方法接受数组形式的参数。
    • 如果要使用数组而不是参数列表,则apply() 方法非常方便。
    // call
    var person = {
      fullName: function(city, country) {
        return this.firstName + " " + this.lastName + "," + city + "," + country;
      }
    }
    var person1 = {
      firstName:"John",
      lastName: "Doe"
    }
    person.fullName.call(person1, "Oslo", "Norway");
    // apply
    var person = {
      fullName: function(city, country) {
        return this.firstName + " " + this.lastName + "," + city + "," + country;
      }
    }
    var person1 = {
      firstName:"John",
      lastName: "Doe"
    }
    person.fullName.apply(person1, ["Oslo", "Norway"]);
    
  • bind() 改变 this 指向,但不立马执行,返回一个函数

JS 闭包

参考:JavaScript 闭包

  • 闭包使函数拥有“私有”变量成为可能。

  • 闭包指的是有权访问父作用域的函数,即使在父函数关闭之后。

  • 计数器例子

    var add = (function () {
        var counter = 0;
        return function () {return counter += 1;}
    })();
    
    add();
    add();
    add();
    
    // 计数器目前是 3
    

变量作用域

ES5 之前,只有全局作用域和函数作用域,ES5 引入了 let 和 const,提供了块作用域。

块作用域解释:

{ 
  var x = 10; 
}
// 此处可以使用 x

{ 
  let x = 10;
}
// 此处不可以使用 x
var x = 10;
// 此处 x 为 10
{ 
  var x = 6;
  // 此处 x 为 6
}
// 此处 x 为 6

var x = 10;
// 此处 x 为 10
{ 
  let x = 6;
  // 此处 x 为 6
}
// 此处 x 为 10

注意点:

  • 使用 JavaScript 的情况下,全局作用域是 JavaScript 环境。
  • 在 HTML 中,全局作用域是 window 对象。
  • 通过 var 关键词定义的全局变量属于 window 对象
  • 通过 let 关键词定义的全局变量不属于 window 对象
<!DOCTYPE html>
<html>
<body>
    <h1>JavaScript 全局变量</h1>
    <p id="demo"></p>
    <script>
        var carName = "Audi";
        // 此处的代码能够使用 window.carName
        document.getElementById("demo").innerHTML = "我可以显示 " + window.carName;
    </script>
</body>
</html>

//我可以显示 Audi
<!DOCTYPE html>
<html>
<body>
    <h1>JavaScript 全局变量</h1>
    <p id="demo"></p>
    <script>
        let carName = "Audi";
        // 此处的代码能够使用 window.carName
        document.getElementById("demo").innerHTML = "我不能显示 " + window.carName;
    </script>
</body>
</html>

//我不能显示 undefined
  • const 和 let 类似,但不能重新赋值
  • const 必须在定义的时候赋值
  • const 是对象的话,对象的属性可以更改,但对象不能更改

JavaScript 对象

  • Function:函数对象

    • 在 JS 中,一个函数就是一个对象。

    • 创建:

      • var fun = new Function(形式参数列表,方法体) (了解即可,从不使用)
      • function 方法名称(a,b) {
            方法体;
        }
        
      • var 方法名 = function(形式参数列表) {
            方法体;
        }
        
    • 方法:

    • 属性:

      • length:代表形参的个数
    • 特点:

      • 方法定义时,形参的类型不需要写
      • 方法是一个对象,如果定义名称相同的方法,方法会被覆盖
      • 在 JS 中,方法的调用之和方法名称有关,和参数的个数无关,会按所传参数的顺序就行接收,没有接收到值的参数为 undefined,传的值多的话,被内置对象 argument 接收。
      • 在方法声明中有一个隐藏的内置对象 arguments (数组) 封装所有的实际参数
        function add() {
            var sum = 0;
            for (var i = 0; i < arguments.length; i++) {
                sum += arguments[i];
            }
            return sum;
        

      }

      var ans = add(1, 2, 3);
      document.write(ans);

      * 方法可以有返回值,返回值类型为 var ,因此不声明
      
    • 调用:

      • 方法名称(实际参数列表);
  • Array:数组对象

    • 创建

      • var arr = new Array(元素列表)
      • var arr = new Array(默认长度),参数为 1 个的时候,代表的是长度,而不是列表,参数为空的话,代表空数组。
      • var arr = [元素列表]
    • 方法

      • join(参数):将数组中的元素按照指定的分隔符拼接为字符串
      • push(参数):向数组的末尾添加一个或更多元素,并返回新的长度。
    • 属性

      • length:数组的长度
    • 特点

      • JS 中,数组元素的 类型是可变的
      • 数组的长度是可变的,访问超出数组范围时,数组会扩容至访问的长度,没有元素的位置为 undefined。
  • Boolean 对象

    • 创建
      • new Boolean(value);:构造参数
      • Boolean(value); :转换函数
  • Date :日期对象

    • 创建:var date = nwe Date();
      • toLocaleString():返回当前 date 对象对应的时间本地字符串格式
      • getTime():获取毫秒值
  • Math :数学对象

    • 创建:无需创建,直接使用,Math.方法名();

    • 方法

      • random():返回 0 ~ 1 之间的随机数。 含 0 不含 1
      • ceil(x):对数进行上舍入
      • floor(x):对数进行下舍入。
      • round(x):把数四舍五入为最接近的整数。
    • 属性

      • PI
  • Number 对象

  • String 对象

  • RegExp:正则表达式对象

    • 创建:

      • var reg = new RegExp("正则表达式");

        • ^n:匹配任何开头为 n 的字符串。
        • n$:匹配任何结尾为 n 的字符串。
      • var reg = /正则表达式/;

        • 这是方式正则中\ 不代表转义的意思,因为不是字符串,所以写一个\ 即可,例如/^\w{6,12}$/
    • 方法

      • test(参数):验证指定的字符串是否符合正则定义的规范
  • Global:全局对象

    • 特点:全局对象,这个 Global 中封装的方法不需要对象就可以直接调用。

    • 方法:

      • encodeURI():url 编码
      • decodeURI():url 解码
      • encodeURIComponent():url 编码,编码的字符更多,比如:/ 都会被编码
      • decodeURIComponent():url 解码
      • parseInt():逐一判断每一个字符是否是数字,直到不是数字为止,将前边数字部分转为 number,一位也没有的话就会转为 NaN。
      • isNaN():判断一个值是否是 NaN,NaN 通过 == 来判断永远为 false
      • eval():将 JavaScript 字符串,解析为代码并执行。
    • URL 编码

      • 传智播客 = %E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2,字节间以% 作为分隔,一个% 代表一个字节

对象原型

所有 JavaScript 对象都从原型继承属性和方法。

对象构造器:

function Person(first, last, age, eyecolor) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eyecolor;
}

我们无法为已有的对象构造器添加新属性,但我们可以通过原型属性(prototype)属性为对象构造器添加新属性和新方法

function Person(first, last, age, eyecolor) {
    this.firstName = first;
    this.lastName = last;
    this.age = age;
    this.eyeColor = eyecolor;
}
Person.prototype.nationality = "English";

setter 和 getter

ES5 允许使用类似于获取或设置属性的语法来定义对象方法

var person = {
    firstName: "Bill",
    lastName: "Gates",
    language: "NO",
    get lang() {
        return this.language;
    },
    set lang(value) {
        this.language = value.toUpperCase();
    }
};

// 使用 setter 设置对象属性:
person.lang = "en";
// 使用 getter 设置对象属性:
var ans = person.lang;

Browser 对象(BOM)

  • Browser Object Model 浏览器对象模型,将浏览器的各个组成部分封装成对象。

  • 组成

    • Window:窗口对象
    • Navigator:浏览器对象
    • Screen:显示器屏幕对象
    • History:历史记录对象
    • Location:地址栏对象
  • Window:窗口对象

    • 创建

    • 方法

      1. 与弹出框有关的方法:

        • alert(""):警告框。

        • confirm("message"):显示带有一段消息以及确认按钮和取消按钮的对话框。

          • 如果用户点击确定按钮,则方法返回 true
          • 点击取消,则方法返回 false
        • prompt():显示可以提示用户输入的输入对话框。

          • 返回值:获取用户输入的值
      2. 与打开关闭有关的方法:

        • close():关闭浏览器窗口。谁调用此函数 ,关闭谁
        • open():打开一个新的浏览器窗口,返回新的 Window 对象
      3. 与定时器有关的方法

        • setTimeout():在指定的毫秒数后调用函数或执行 js 代码。
          • 参数:第一个参数为 js 代码("fun();")或者方法对象(fun),第二个参数为毫秒值。
          • 返回值:唯一标识,用于取消定时器
        • clearTimeout():取消由setTimeout() 方法设置的定时器。
        • setInterval():按照指定的周期来调用函数或执行 js 代码,循环执行。
        • clearInterval():取消由 setInterval() 设置的定时器,参数为定时器的 ID。
      4. 其他方法

        • 滚动到页面指定坐标,scrollTo(0, 0); 滚动到页面顶部。
    • 属性

      • 获取其他 BOM 对象:history、location、Navigator、Screen
      • 获取 DOM 对象:document,window.document
    • 特点

      • Window 对象不需要创建可以直接使用 window 使用。 window.方法名();
      • window 引用可以省略。 方法名();
  • Location:地址栏对象

    • 创建(获取)

      • window.location
      • location
    • 方法

      • reload(),重新加载当前文档,刷新
    • 属性

      • href:设置或返回完整的 URL。
      • search:返回从 ?号开始的部分,包括 ?
  • History:历史记录对象

    • 创建(获取):

      • window.history
      • history
    • 方法:

      • back():加载 history 列表中的前一个 URL。
      • forward():加载 history 列表中的下一个 URL。
      • go(参数):加载 history 列表中的某个具体页面,参数为正,前进几个历史记录,参数为负,后退几个历史记录
    • 属性:

      • length:返回当前窗口历史列表中的 URL 数量。

DOM 简介

  • Document Object Model 文档对象模型

  • 将标记语言文档的各个组成部分,封装为对象。可以使用这些对象,对标记语言文档进行 CRUD 的动态操作。

  • DOM 是 W3C 定义的标准,被分为 3 个部分

    • 核心 DOM:针对任何结构化文档的标准模型
      • Node:节点对象,其他 5 个的父对象,每个成分都是一个结点
      • Document:文档对象
      • Element:元素对象
      • Attribute:属性对象
      • Text:文本对象
      • Comment:注释对象
    • XML DOM:针对 XML 文档的标准模型
    • HTML DOM:针对 HTML 文档的标准模型
  • DOM 是这样规定的:

    • 整个文档是一个文档节点
    • 每个 HTML 标签是一个元素节点
    • 包含在 HTML 元素中的文本是文本节点
    • 每一个 HTML 属性是一个属性节点
    • 注释属于注释节点
  • HTML 文档中的所有节点组成了一个文档树(或节点树)

核心 DOM 模型

  • Document:文档对象

    • 创建,在 HTML dom 模型中可以使用 window 对象来获取, window.document 或者直接写document
    • 方法
      • 获取 Element 对象:

        1. getElementById():根据 id 属性值获取元素对象。id 属性值一般唯一
        2. getElementsByTagName():根据元素标签名称获取元素对象们。返回值是一个数组
        3. getElementsByClassName():根据 Class 属性值获取元素对象们。返回值是一个数组
        4. getElementsByName():根据 name 属性值获取元素对象们。返回值是一个数组
        5. 若想获取对象输入框的值,可以通过其 value 属性获取
      • 创建其它 DOM 对象:

        1. createAttribute(name)
        2. createComment()
        3. createElement():重点掌握
        4. createTextNode()
  • Element:元素对象

    • 创建:通过 document 对象获取 Element 元素对象的方法来获取
    • 方法:
      • removeAttribute():删除属性
      • setAttribute():设置属性
      • <body>
        <a>我可以点的</a>
        <script>
            var element_a = document.getElementsByTagName("a")[0];
            element_a.setAttribute("href", "https://www.baidu.com");
            // element_a.removeAttribute("href");
        </script>
        </body>
        
  • Node:节点对象,其他 5 个的父对象

    • 特点:

      • 所有 DOM 对象都可以被认为是一个节点
      • JS 中 this 代表本节点对象。
    • 方法:CRUD dom 树

      • appendChild(参数):向节点的子节点列表的结尾添加新的子节点。

        <!DOCTYPE html>
        <html lang="ch">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
            <style>
                #div3{
                    border: 1px solid red;
                    width: 100px;
                }
            </style>
        </head>
        <body>
        <div id="div1">
            <div id="div2">div2</div>
            div1
        </div>
        <script>
            var div3 = document.createElement("div");
            div3.setAttribute("id", "div3");
            div3.innerHTML = "div3";
            var div1 = document.getElementById("div1");
            div1.appendChild(div3);
        </script>
        </body>
        </html>
        
      • removeChild(参数):删除(并返回)当前节点的指定子节点。

        <body>
        <div id="div1">
            <div id="div2">div2</div>
            div1
        </div>
        <a href="javascript:void(0);">点击删除元素</a>
        <script>
            var a = document.getElementsByTagName("a")[0];
            a.onclick = function () {
                var div1 = document.getElementById("div1");
                var div2 = document.getElementById("div2");
                div1.removeChild(div2);
            }
        </script>
        </body>
        
      • replaceChild(参数,参数):用新节点替换一个子节点。

        <body>
        <div id="div1">
            <div id="div2">div2</div>
            div1
        </div>
        <script>
            var div3 = document.createElement("div");
            div3.innerHTML = "div3";
            var div1 = document.getElementById("div1");
            var div2 = document.getElementById("div2");
            div1.replaceChild(div3,div2);//第一个参数为新节点,第二个为旧结点
        </script>
        </body>
        
    • 属性:parentNode:返回节点的父节点。

HTML DOM

  • 功能:控制 HTML 文档的内容

  • 获取页面标签(元素)对象:Element

    • document.getElementById("id值"):通过元素的 id 获取元素对象
  • 操作 Element 对象:

    • 使用 HTML 元素对象的属性来获取和修改属性值:对象.属性 = "属性值"
    • 通过属性 innerHTML 来获取和修改标签体内容:对象.innerHTML = "修改后的内容"
  • 控制元素的样式:

    • 使用元素的 style 属性(所有标签都有此属性)来控制
      div1.style.border = "1px solid red";
      div1.style.width = "200px";
      //注意font-size--> fontSize
      div1.style.fontSize = "20px";
      
    • 提前使用 CSS 定义好样式,通过元素的 className 属性来设置其 class 属性值。例如:tr.className="out"

DOM Event 事件监听机制

  • 功能:某些组件被执行了某些操作后,触发某些代码的执行。

  • 事件:某些操作。如: 单击,双击,键盘按下了,鼠标移动了

  • 事件源:组件。如: 按钮 文本输入框…

  • 监听器:代码。

  • 注册监听:将事件,事件源,监听器结合在一起。 当事件源上发生了某个事件,则触发执行某个监听器代码。

  • 绑定事件

    1. 直接在 HTML 标签上,指定事件的属性(操作),属性值就是js 代码,例如:<div id = "div1" onclick="fun();"></div>
    2. 通过 js 获取元素对象,指定事件属性,设置 onclick 函数。
      <div id = "div1"></div>
      <script>
          function fun(){}
          var e = document.getElementById("div1");
          e.onclick = fun;
          //或者直接写
          e. e.onclick = fun(){}
      </script>
      
    3. 为什么第一种方式需要加括号,第二种不需要括号?
      答:第一种方式点击的时候,是吧 onclick 属性中的字符串(引号括起来的)当做 js 代码去执行,而第二种则是将 fun 函数的指针赋值给 onclick,两种方式内部执行方法不一样,第一种是在 onclick 函数中执行 fun 函数,第二种是直接把 onclick 指向 fun 函数,第一种若不加括号则不是调用函数,第二种若加上括号就是直接调用函数,不用点击,加载后就会直接运行函数,所以第一种需要加上括号,第二种不需要括号。
  • 常见的事件:

    • 点击事件:

      • onclick:单击事件
      • ondblclick:双击事件
    • 焦点事件

      • onblur:失去焦点,一般用于表单验证
      • onfocus:元素获得焦点。
    • 加载事件:

      • onload:一张页面或一幅图像完成加载。
        • window.onload = function(){},可以等界面加载完以后执行 JS 代码
    • 鼠标事件:

      • onmousedown:鼠标按钮被按下。
        • 可以通过 event 的 button 属性获取哪个键被点击了。
      • nmouseup:鼠标按键被松开。
      • onmousemove:鼠标被移动。
      • onmouseover:鼠标移到某元素之上。
      • onmouseout:鼠标从某元素移开。
    • 键盘事件:

      • onkeydown:某个键盘按键被按下。
        • 可以通过 event 的 keyCode 属性获取哪个键被按下了。回车的 ASCII 码为 13
      • onkeyup:某个键盘按键被松开。
      • onkeypress:某个键盘按键被按下并松开。
    • 选择和改变

      • onchange:域的内容被改变。
      • onselect:文本被选中。
    • 表单事件:

      • onsubmit:确认按钮被点击。
        • 可以阻止表单的提交,方法返回 false 则表单被阻止提交。
        • 如果在 HTML 标签中,用onsubmit="" 来阻止表单提交,则应该写成onsubmit = "return fun();" ,因为会把引号中的内容封装到系统方法中运行,封装为function systemFun() {return fun();} 来运行,在 script 标签中则会将 onsubmit 指向自定义的函数。
      • onreset:重置按钮被点击。
  • 关于 <a> 标签添加点击事件:
    超链接有两个功能:

    • 可以被点击(因为有 href)
    • 跳转到 href 指定 的 url

    当超链接中 href="" 的时候,虽然会执行点击事件,但是会立马刷新此界面,当 href="#" 的时候,会触发点击事件,并且返回到页面顶部,但不会刷新界面。
    可以通过 href="javascript:void(0);" 的方法来让 a 标签仅仅保留点击事件而不进行跳转。

    注意:form 中的 action=“#” 会刷新界面,会把数据提交到本页。

  • 可以通过 href="javascript:方法名();" ,来使点击 a 标签执行 JS 方法。

  • 当事件被触发时,系统会向事件触发的函数中传入事件 event。form.submit = function (ev) {};

  • 关于添加点击事件的时候,函数是放在 window.onload 内部还是外部的问题。

    • <script>
          window.onload=function (ev) {
              function fun() {
                  alert("123");
              }
          }
      </script>
      <a href="javascript:fun();">click</a>
      

      看上述代码:
      当页面加载完以后执行 onload 函数,onload 是一个函数,函数 fun 是定义在 onload 中的,其作用域也就是 onload 函数中,外部无法访问到这个函数,所以点击事件无效。

    • <script>
          window.onload=function (ev) {
              var a = document.getElementById("a");
              a.onclick=function (ev1) {
                  alert("123");
              }
          }
      </script>
      <a href="javascript:void(0);" id="a">click</a>
      

      这样写的话,就相当于把函数 fun 绑定在了 a 上面,就可以使用了。

补充

模板字符串

  • `` 是 es6 的新语法,用来表示字符串,和单引号双引号的区别是,这个新语法中的字符串可以换行,也可以直接取值
// es5 输出模板通常是如下格式,相当繁琐还不方便
var name="Bob",time="today";
var resultStr = "hello "+name+", how are you "+time+'?';  //hello Bob, how are you today?
// es6 模板字符串
console.log(`string text line 1
string text line 2`);
//string text line 1
//string text line 2

// 直接用${变量名}表示
`Hello ${name}, how are you ${time}?` // Hello Bob, how are you today?
// 使用表达式
var obj={a:1,b:2};
`${obj.a+obj.b}` // 3
// 使用函数
function fn() {
  return "Hello World";
}
`this is fn return str: ${fn()}` // this is fn return str: Hello World

for…in 和 for…of 的区别

  • for-in: 遍历对象的 key 或者数组的 index。

    let people = {
      name: '张三',
      age: 18
    };
    
    let peoples = [{
      name: '张三',
      age: 18
    }, {
      name: '李四',
      age: 19
    }];
    
    for (const key in people) {
      console.log(key); //name,age
    }
    
    for (const key in peoples) {
      console.log(key); //0,1
    }
    
  • for-of: 遍历数组的 value,遍历 new Map() 的 key 和 value, 不能遍历普通对象的 value。

    let peoples = [{
      name: '张三',
      age: 18
    }, {
      name: '李四',
      age: 19
    }];
    
    for (const iterator of peoples) {
      console.log(iterator);
      // { name: '张三', age: 18 }
      // { name: '李四', age: 19 }
    }
    
    var dogMap = new Map();
    dogMap.set('小白',20);
    dogMap.set('小黑',30);
    for(var [key,value] of dogMap){
        console.log(key + ' is ' + value +'years old.');
    }
    //小白 is 20years old.
    //小黑 is 30years old.
    

扩展运算符和剩余运算符

参考:总结 ES6 扩展运算符

都是 ...

扩展运算符将一个元素(对象或者数组)结构为多个元素

let obj1 = {
    a: 1,
    b: 2
}

let obj2 = {
    ...obj1
}

剩余运算符(rest 运算符),主要针对形参,将多个元素合并为一个

function test(...args) {
    console.log(args)
}

test(1, 2, 3)
// [ 1, 2, 3 ]

链判断运算符

要读取 message.body.user.firstName,安全的写法是写成下面这样。

// 错误的写法
const  firstName = message.body.user.firstName;

// 正确的写法
const firstName = (message
  && message.body
  && message.body.user
  && message.body.user.firstName) || 'default';

这样很麻烦,?. 运算符很简单

const firstName = message?.body?.user?.firstName || 'default';

直接在链式调用的时候判断,左侧的对象是否为 nullundefined。如果是的,就不再往下运算,而是返回 undefined

严格模式下函数中 this 指向

在 JavaScript 的严格模式(strict mode)下,函数中的 this 会被设置为 undefined,而不是默认的全局对象(在浏览器环境中通常是 window)。这是严格模式下的一个特性,旨在减少一些容易产生错误的行为,并提供更强的代码检查。

严格模式引入了一些额外的规则和限制,以帮助开发者编写更可靠、安全的代码。其中一个变化就是将全局函数中的 this 设置为 undefined,而不是默认的全局对象。这可以防止不小心在全局上下文中使用未定义的 this 导致意外的行为。

例如,在非严格模式下,如果您在全局环境中调用一个函数而忘记使用 new 关键字创建实例,函数中的 this 会指向全局对象。这可能导致在全局范围内创建或修改全局变量,从而产生不可预测的结果。严格模式下的 this 设置为 undefined 可以帮助避免这种问题。

要在函数中确保在严格模式下使用正确的 this,您可以通过以下几种方式之一:

  1. 使用箭头函数:箭头函数不会改变 this 的指向,它会继承外部作用域中的 this 值。
  2. 使用 .bind().call().apply() 方法显式绑定 this
  3. 在类方法中使用正常函数语法,并在构造函数内部绑定 this
// 示例 1:箭头函数
const myFunction = () => {
  console.log(this); // 这里的 this 是外部作用域的 this
};

// 示例 2:显式绑定
const myFunction = function() {
  console.log(this);
};
const boundFunction = myFunction.bind(someObject); // 绑定 this 到 someObject

// 示例 3:类方法中的绑定
class MyClass {
  constructor() {
    this.myMethod = this.myMethod.bind(this); // 绑定 this 到实例
  }

  myMethod() {
    console.log(this);
  }
}

总之,严格模式下将函数中的 this 设置为 undefined 是为了提高代码的安全性和可靠性,帮助开发者避免一些常见的错误。在编写代码时,您可以使用箭头函数、显式绑定和构造函数内的绑定来管理函数中的 this