JavaScript 学习归纳

2021-04-12  本文已影响0人  想聽丿伱說衹愛我

一、简介

参考JavaScript 教程JavaScript 参考手册,对里面内容进行了优化与总结。
JS 代码需要写在<script></script>之中,<script></script>可放在<head></head><body></body>中,或同时存在这两者中。当存在于多处时,将按顺序执行JS代码。
可从外部引入 JS,如<script src="xxx.js"></script>,但 xxx.js 中不使用<script></script>标签,而是直接写 JS 代码。
JS 对大小写是敏感的。

二、调试

  1. 警告框 alert()
    使用window.alert()弹出警告框,可简写成alert(),括号中为警告内容,如window.alert("弹框测试")

  2. 写入文档 write()
    使用document.write()将内容写入文档中。内容也可传入 html 语句,如document.write("<h1>1号标题</h1>")。可传入多个参数,用逗号隔开。
    要注意的是,若在文档加载完成后再使用该方法,内容会直接覆盖整个文档。

  3. 输出信息 log()
    使用console.log()将内容输出在控制台上,如console.log("打印在控制台")
    使用console.info()将内容输出在控制台上。
    使用console.warn()将警告输出在控制台上,警告前有个黄色三角。
    使用console.error()将错误输出在控制台上,错误前有一个红色的X。

    更多属性和方法详见 JavaScript 参考手册 -- DOM Console 对象

  4. 获取元素 getElementById()
    使用document.getElementById()通过传入的元素id来获取元素。使用元素的innerHTML属性来获取元素的内容,即<div>123</div>中的123,也可修改内容,如document.getElementById("id").innerHTML = "修改内容"

<body>
        <div id="div1">div1</div>
        <script>
            window.alert("弹框测试")
            document.write("<div>该div会插入到div1和div2之前,因为是按顺序的</div>")
            // 控制台会打印日期
            console.log(Date())
            
            // 获取id为div1的元素
            var ele = document.getElementById("div1")
            // 修改元素的内容为h1标题
            ele.innerHTML = "<h1>标题div1</h1>"
        </script>
        <div>div2</div>
    </body>
  1. 断点
    在要添加断点的代码处输入debugger。运行后,会在这个位置停止运行。
    在浏览器中按 F12 并选择 Sources 可以看到断点时的变量的值。

  2. 异常处理
    try 放入可能有异常的代码。
    catch 捕获并处理异常。
    finally 无论有无异常都会执行。
    throw 在try中使用,手动抛出异常,再由catch捕获处理。

try {
                throw "test_error"
            } catch(error) {
                document.write(error, "<br>")
            } finally {
                document.write("try catch end")
            }

若error为 Error 对象,则可使用namemessage属性,表示错误名与错误信息。
错误名有以下几种:
RangeError 数值超出规定的范围。
ReferenceError 非法引用,比如使用未定义的变量。
SyntaxError 语法错误。
TypeError 类型错误,比如number类型的变量使用string类型的方法。
URIError 执行函数encodeURI()产生的错误。

三、变量与常量

  1. 字面量
    在 JS 中,固定值一般称为字面量,字面量用来赋值给变量或常量。
            // 字符串换行
            document.write("hello \
world")

此时相当于document.write("hello world")

  1. 类型判断
            document.write(typeof(1))          //number
            document.write(typeof("1"))        //string
            document.write(typeof [1, 2])     //object
            document.write(typeof {a: 1})     //object
            document.write(typeof(function a() {}))//function
            // 正则
            document.write(typeof(/\d+/g))     //object
            // 判断是否支持isArray方法
            if (Array.isArray) {
                document.write(Array.isArray([1, 2]))//true
                document.write(Array.isArray({a: 1}))//false
            }
document.write([1, 2] instanceof Array)//true
            document.write({a: 1} instanceof Array)//false
            
            document.write([1, 2] instanceof Object)//true
function type(obj) {
                return obj.constructor
            }
            document.write(type(1), "</br>")//function Number() { [native code] }
            document.write(type("1"), "</br>")//function String() { [native code] }
            document.write(type([1, 2]), "</br>")//function Array() { [native code] }
            document.write(type({a: 1}), "</br>")//function Object() { [native code] }
            document.write(type(function a() {}), "</br>")//function Function() { [native code] }
            document.write(type(/\d+/g), "</br>")//function RegExp() { [native code] }
  1. 变量
    变量命名可使用小驼峰firstName、大驼峰FirstName、下划线法first_name,建议使用小驼峰。
    变量通常以字母开头,且对大小写敏感。
    document.write(a, "<br>")//undefined
            {
                var a = 1
            }
            document.write(a, "<br>")//1
            document.write(b, "<br>")//error  b is not defined
            {
                let b = 2
            }
            document.write(b, "<br>")//error  b is not defined

根据上面,let只在{ }内有效,所以不会影响括号外的同名变量。

var c = 3
            document.write(c, "<br>")//3
            {
                let c = 4
                document.write(c, "<br>")//4
            }
            document.write(c, "<br>")//3 若let改成var 这里输出4

但实际上,最好变量不要同名,就不会产生误导。

  1. 全局变量
    <script></script>内函数外直接声明的叫全局变量,可以在该脚本中任意地方使用。
    在函数内声明的变量叫局部变量,只在函数内有效。局部变量中的let只在对应的{ }中有效,而var在整个函数内有效。
    使用var声明的全局变量属于 window 对象,可以调用window.name来获取。而let声明的全局变量则不属于 window 对象。
var d = 4
            let e = 5
            document.write(d, e)// 4 5
            document.write(window.d, window.e)//4 undefined

但全局变量与 window 对象的变量也有区别。
全局变量不能用delete删除,而 window 对象的变量则可以。

var d = 1
            window.e = 2
            delete d
            delete e
            document.write(d, "<br>")//1
            document.write(window.e, "<br>")//undefined
  1. 变量重新声明
    在同一级作用域中,只能使用var来重新声明同名var变量。
let f = 6
            let f = 66//error Identifier 'f' has already been declared
            
            let g = 7
            var g = 77//error Identifier 'g' has already been declared
            
            var h = 9
            let h = 99//error Identifier 'h' has already been declared
            
            var i = 10
            var i = 100//success
  1. 声明提升
    在 JS 中,函数声明和var变量声明都将被提升到最顶部;若在函数内,则提升到函数最顶部。且函数比变量更优先提升。
    若变量声明并赋值,如var a = 1,只会声明提升,赋值还是在原来位置,即在赋值前使用变量,不会报错,但会返回undefined
    var声明的变量会声明提升,所以可以先使用再声明;而let声明的变量不能声明提升,必须先声明再使用。
            m = 5;n = 6;
            document.write(m, n)//5 6 声明提升 
            var n;var m;
            
            var o = 7
            document.write(o, p)//7 undefined 若直接声明并赋值,声明会提升,赋值还在原先位置。
            var p = 8
            
            
            q = 9
            document.write(q)//UncaughtReferenceError: q is not defined let变量不能声明提升
            let q

若存在同名var变量和函数,函数会先提升,var变量再提升,所以实际上var变量会覆盖同名函数。
建议:
函数与变量不应该同名,var变量、let变量与常量也不应该同名。
使用函数与变量时,都应该先声明再使用,这样不会产生隐性问题。声明也应该放在代码最上面。

  1. const
    const声明一个或多个常量,声明时必须进行赋值,且值不可再修改和重新声明。
    但当常量是一个数组或对象时,是可以修改里面元素的值的。
const l = { name: "zhangsan" }
            l.name = "lisi"//能修改不报错 
            l = { name: "lisi" }//UncaughtTypeError: Assignment to constant variable.

可以使用Object.freeze()来冻结对象,使之不能删除、添加、修改对象的元素。

四、数据类型

JS 是动态的数据类型,会根据后面值的类型判断现在的变量类型。

var a//此时是Undefined
            a = 1//Number
            a = "2"//String
            a = [3]//Array
            a = { key: 4 }//Object

数据类型可分为值类型与引用类型。

var a = 5
            var b = a
            a = 6
            document.write(a, b)//6 5
var c = { name: "zhangsan" }
            var d = c
            c.name = "lisi"//修改c.name会影响d.name的值,因为指向同一个地址
            c = {name: "wangwu"}//为c重新赋值,与之前的值再无关系
            document.write(c.name, d.name)//wangwu lisi
  1. String 字符串

更多属性和方法详见 JavaScript 参考手册 -- String 对象

  1. Number 数字

更多属性和方法详见 JavaScript 参考手册 -- Number 对象

  1. Boolean 布尔

更多属性和方法详见 JavaScript 参考手册 -- Boolean 对象

  1. Null 空
    空值,表示一个空对象引用,数据类型为object。
    给一个变量赋值null将会清空变量,通常将数组或对象赋值null以释放内存。

  2. Undefined 未定义
    所有未赋值变量的默认值,在变量声明后变量的值就是undefined
    为一个变量赋值undefined后,数据类型为undefined。
    注:null == undefined null !== undefined

  3. Symbol 独一无二的值

            let sym = Symbol.for("b");
            document.write(Symbol.keyFor(sym))//b
let sym = Symbol.for('b');
            var a = {
                [sym]: "1",
                c: "2"
            }
            for (key in a) {
                document.write(key, "<br>")//c 
            }

可以使用Object.getOwnPropertySymbols()获取对象中Symbol类型的key(但实测返回[null],不知为何)。
详见Symbol

  1. Object 对象
    JS 中的所有事物都是对象,数字、日期、字符串、布尔等都是对象。
    对象是带有属性和方法的特殊数据类型,属性通过objectName.propertyName来使用,方法通过objectName.methodName()来使用。如message.lengthmessage.toUpperCase()
function Person() {
                this.name = arguments[0]
                this.age = arguments[1]
                this.adress = arguments[2]
            }
            var p = new Person("zhangsan", 20, "chengdu")
            document.write(typeof p)//object
var e = { name: 'zhangsan' }//用字面量初始化并赋值
            var e = new Object()//构造函数初始化
            e.name = "zhangsan"//赋值
            e.adress = "cd"
            e.full = function() {
                return e.name+"_"+this.adress//this表示对象本身
            }
            document.write(e.name)//zhangsan
            //访问元素 通过. 或 []
            //元素值是一个函数时,需要加()执行函数,并显示返回值
            //不加(),则会返回函数的代码
            document.write(e.full(), " ", e['full'])//zhangsan_cd function () { return e.name+"_"+this.adress }
            
            var f = {"a b":"aa"}
            document.write(f['a b'])//aa
            // 给Number添加新属性newAttr,值为newAttrValue
            Number.prototype.newAttr = 'newAttrValue'
            // 给Number添加新方法
            Number.prototype.newFunc = function() {
                document.write("newFunc")
            }
            var a = 10
            document.write(a)//10
            document.write(a.newAttr)//newAttrValue
            a.newFunc()//newFunc
  1. Array 数组

更多属性和方法详见 JavaScript 参考手册 -- Array 对象

  1. 函数(Function)
(function functionName(para) {
                document.write(para, "<br>")
            })("hello")//hello

上面函数会自调用,输出hello。
但只能调用一次,不能通过functionName()再次调用。
所以函数名可以省略,即写成(function(para) { document.write(para, "<br>") })("hello")
箭头函数自调用(() => {})()

            function c () {
                d = "hello"
            }
            document.write(d)//UncaughtReferenceError: d is not defined 因为c()前变量d还未创建
            c()//执行函数时会调用d = "hello",此时会发生变量提升,var d会自动放在脚本顶部,成为一个全局变量。
            document.write(d)//hello c()后d会变成一个全局变量
function functionName() {
                for (let i = 0; i < arguments.length; i++) {
                    document.write(arguments[i])//123
                }
            }
            funName(1, 2, 3)
function fun1() {
                //声明一个函数内的变量
                var x = 10
                //返回一个函数
                return function() {
                    return x += arguments[0]
                }
            }
            var y = fun1()
            document.write(y, "<br>")//function () { return x += arguments[0] } 
            document.write(typeof y, "<br>")//function y是一个函数
            
            var outX = y(20)//这里就使用了函数里的变量与20相加 实现了在函数外使用函数内的变量这个功能
            document.write(outX, "<br>")//30

一般来说,函数调用完成后,函数内的变量就会被释放。根据上面,变量x被返回的函数持有,而返回的子函数被变量y持有,相当于y持有x,所以x不会被释放。
所以闭包就是 使用了父函数的变量并且可以被外部调用的 子函数。

也可以使用自调用的方式实现闭包,更精简。

            //自调用
            var y = (function() {
                var x = 10
                return function() { return x += arguments[0] }
            })()
            var outX = y(20)//30

五、其他数据类型

  1. 日期 Date

更多属性和方法详见 JavaScript 参考手册 -- Date 对象

  1. Math 数学
    Math主要是用于执行科学计算。

更多属性和方法详见 JavaScript 参考手册 -- Math 对象

  1. RegExp 正则表达式
    正则表达式(Regular Expression,简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。正则表达式是匹配字符串的条件。
var b = /bc/g
            var c = "abcdefgbcba"
            document.write(b.test(c), b.lastIndex, "<br>")//true3
            document.write(b.test(c), b.lastIndex, "<br>")//true9
            document.write(b.test(c), b.lastIndex, "<br>")//false0 未匹配到时lastIndex会重置为0

更多属性和方法详见 JavaScript 参考手册 -- RegExp 对象

六、事件触发

事件可以是浏览器行为,如页面加载完成;也可以是用户行为,如点击标签。

  1. 标签中绑定事件
    语法:<element-name event-name="表达式">
    • element-name 元素名,如<div>、<a>
    • event-name 事件名称。如onclick 点击标签、onload页面加载完成。
    • "表达式" 可以是单引号,也可以是双引号。当为单引号时,里面可以用双引号来使用字符串;为双引号时用单引号来使用字符串。
      表达式可以是一个函数调用,如<div onclick="tapAction()">hello</div>
      可以是一句实现某功能的 JS 语句,如<div onclick="this.innerHTML = 'hello world'">hello</div>
      表达式中使用this时,表示的是元素本身。

关于this:
1、在对象函数(对象中某键的值为函数)中, this指向对象本身。
2、脚本中直接使用,this指向全局(Global)对象,即 window 对象。
3、在函数中使用,this指向函数的所属者,即 window 对象。
4、严格模式下函数没有所属者,所以this是undefined。
5、在HTML事件句柄中,this指向接收事件的HTML元素,即上面的例子。
6、apply()call()允许切换函数执行的上下文环境(context),所以this可以指向任何对象。可在 四、数据类型 -- 9. 函数(Function) -- 使用call和apply调用函数 中查看。

更多事件方法详见 JavaScript 参考手册 -- DOM 事件对象

// 阻止链接跳转,URL不会有任何变化
<a href="javascript:void(0)" rel="nofollow ugc">点击此处</a>
// 虽然阻止了链接跳转,但URL尾部会多个#,改变了当前URL。(# 主要用于配合 location.hash)
<a href="#" rel="nofollow ugc">点击此处</a>
// 同理,# 可以的话,? 也能达到阻止页面跳转的效果,但也相同的改变了URL。(? 主要用于配合 location.search)
<a href="?" rel="nofollow ugc">点击此处</a>
  1. DOM分配事件
    除了像上面一样在标签中绑定事件外,还可以使用 DOM 来给元素分配事件。
    语法: element.event-name = function
    function 是一个函数,如document.getElementById("id").onclick = function() { tapAction() };

  2. 事件监听
    语法: element.addEventListener(event, function, useCapture)
    该方法可向DOM 对象添加事件句柄。DOM 对象有 HTML 元素(element)、HTML 文档(document)、window 对象(window)。
    可添加多个事件句柄,如 click、mouseover、mouseout
    可添加多个相同的事件句柄,如两个click。

    • event 事件名,不要使用on前缀。使用 "click"而不是使用 "onclick"
    • function 事件触发后要调用的函数。
    • useCapture 布尔值,冒泡还是捕获。可选值。
      默认值为false, 即冒泡,true则为捕获。

事件传递定义了元素事件触发的顺序。 如果你将 <p> 元素插入到 <div> 元素中,用户点击 <p> 元素, 哪个元素的 click 事件先被触发呢?
在冒泡中,内部元素的事件会先被触发,然后再触发外部元素,即: <p> 元素的点击事件先触发,然后会触发 <div> 元素的点击事件。
在捕获中则相反。

例:
document.getElementById("id").addEventListener("click", clickAction),函数名后不用加()
document.getElementById("id").addEventListener("click", function() { })
若要传递参数,可使用 document.getElementById("id").addEventListener("click", function() { clickAction(a, b, c) })

七、运算符

  1. 算术运算符
    + 加,除了数字相加外,
    可以字符串相加,如"hello" + " " + "world" == "hello world"
    字符串与数字相加,则将数字当成字符串使用,如"cc" + 5 + 6 == "cc56"
    字符串与布尔值相加,truefalse都当成字符串。
    数字与字符串相加,则先将字符串前面的数字先相加,和则当成字符串,如5 + 6 + "dd" + 5 + 6 == "11dd56"
    数字与布尔值相加,true当成1,false当成0。
    - 减。
    * 乘。
    / 除。
    % 取模(余数) ,如13%5 == 3
    模的正负与被取模数的正负相同,如-13%5 = -3
    ++ 自增。
    a=4,若b=a++,运算后b=4,a=5;若b=++a,运算后b=5,a=5。
    -- 自减。
    a=4,若b=a--,运算后b=4,a=3;若b=--a,运算后b=3,a=3。

  2. 赋值运算符
    = 赋值。
    += 加等,a += b相当于a = a + b。也可用于字符串、数字相加。
    -= 减等,a -= b相当于a = a - b
    *= 乘等,a *= b相当于a = a*b
    /= 除等,a /= b相当于a = a/b
    %= 取模等,a %= b相当于a = a%b

  3. 比较运算符
    == 值等于。
    != 值不等于。
    === 绝对等于,值和类型都相等。
    !== 不绝对等于 ,值和类型至少有一个不相等。
    < 小于。
    <= 小于或等于
    > 大于。
    >= 大于或等于。

    • string、number 等基础数据类型
      不同类型间比较,==先将其转换成同一类型后再比较 值 是否相等,===如果类型不同,结果就不相等。
      同类型比较,直接比较 值 是否相等,=====无区别。
    • Array、Object 等引用类型
      =====则无区别,都是比较 指针地址 是否一致。
  4. 逻辑运算符
    && 与,左右条件都为true,该语句则为true。
    || 或,左右条件有一个为true,该语句则为true。
    ! 非,右边条件为flase,该语句则为true。
    注:0、-0、null、""、false、undefined、NaN 为条件时会转换为false,其他转化为true。

  5. 条件运算符
    语法: (condition) ? value1 : value2
    若condition为true,则返回value1;否则返回value2.

  6. 位运算符
    先将数字转化为32位二进制,再进行运算。
    & 与,2&1相当于10&01,结果为00。
    | 或,10|01结果为11。
    ~ 取反,~01结果为11..110,总共有31个1。
    ^ 异或,10^01结果为11
    >> 右移,10>>1结果为01。
    << 左移,10<<1,结果为100。

八、条件语句

  1. if else
    语法:if (condition1) { code1 } else if (condition2) { code2 } else { code3 }
    若条件condition1为true,执行代码code1;否则若condition2为true,执行代码code2;否则执行代码code3。
    注:
    if else都必须用小写,条件必须用小括号包裹(有些语言中小括号可省略)。
    若code只有一句代码,可以省略大括号,如if (a == 1) b = 2

  2. switch
    语法:

            switch(value) {
                case 1:
                    code1
                    break;
                case 2:
                case 3:
                    code3
                    break;
                default:
                    code4
            }

value是一个表达式(通常是一个变量),将value的值与每个case后的值做比较,若相等则执行后面的代码code。
若不加break,在前面的代码code执行后会继续比较下一个case后的值。
若所有case值与表达式的值都不相等,则会执行default后面的代码code。
case 2后面没有写代码,表示当value=2或3时都会执行code3。
注:switch是使用===作比较的,case后的值可以是String 、Number、Boolean、char、null、undefined。

  1. for
    用来多次执行重复的代码。
    语法:for (code1; code2; code3) { repeatCode }

    • code1 会在循环开始前执行,常用来初始化一个变量。
    • code2 定义循环的条件。
    • code3 每循环一次后执行。

    for (let i = 1; i < 10; i++) { }
    code1中的let,表示变量只能在循环中使用。若改为var,变量则能在循环外且函数内使用。
    code1可以省略,但code1后面的分号不能删除,如let i = 1;for (; i < 10; i++) { }
    code1中也可以初始化多个变量,用逗号分隔,如for (let i = 1, number = 10; i < number; i++) { }
    code2也可以省略,后面的分号不能删除。但repeatCode里面必须要使用break以结束循环。
    code3也可能省略,但应该在repeatCode中添加变量变化的语句。
    3者都省略,如下

            let i = 1
            for (;;) {
                if (i >= 10) {
                    break
                }
                i += 2
            }
  1. while
    条件为真则一直循环代码。
    语法: while (condition) { repeatCode }
    • condition 条件。可以设置为true,但repeatCode中必须要有break以结束循环。
    • repeatCode 循环代码。需要在代码中改变某值以使condition不能一直为true。
  1. 影响循环

九、JSON

JSON(JavaScript Object Notation)是存储和传输数据的格式,通常用于服务端向网页传递数据。
JSON 的数据为键值对,数据之间通过逗号隔开,大括号保存对象,中括号保存数组,数组中有多个对象。
键值对的键是字符串,两端必须加上引号;值可为字符串、数字、布尔值、null。

            {
                "key1":"value1",
                "key2":[
                    {"key2_1": "value2_1"},
                    {"key2_2": "value2_2"}
                ],
                "key3": {
                    "key3_1": "value3_1"
                }
            }

JSON与对象(Object)的结构相同,可以在JSON和Object之间相互转换。

var a = JSON.parse('{"p": {"q": 5}}', function(k, v) {
                //v为对象时返回原值
                if (typeof v == "object") return v;
                return v * 2;               
            });
            document.write(a.p.q, "<br>")//10
var b = {a: 1, b: 2, c: 3, d: 4}
            var json = JSON.stringify(b)
            document.write(json, "<br>")//{"a":1,"b":2,"c":3,"d":4}
            var json = JSON.stringify(b, null, 1)
            document.write(json, "<br>")//{ "a": 1, "b": 2, "c": 3, "d": 4 }
            json = JSON.stringify(b, ["b", "c"])
            document.write(json, "<br>")//{"b":2,"c":3}
            json = JSON.stringify(b, function(k, v) {
                if (typeof v == "object") return v
                if (k == "b") return undefined//返回undefined时排除该键值对
                return v*2
            })
            document.write(json, "<br>")//{"a":2,"c":6,"d":8}

十、异步执行

  1. 延迟操作
    延迟一段时间后执行操作。
    语法: window.setTimeout(code, milliseconds, param1, param2, ...)
    使用时window可以省略。

    • code 必须值,要调用的表达式,如setTimeout("alert('hello')", 1000)
      可以是一个函数,如setTimeout(timeAction, 1000),函数名后不用加()
    • milliseconds 要延迟的时间,单位为毫秒,默认为0。
    • param1, param2 要传给code函数的参数。

    返回值是一个ID(数字),可使用window.clearTimeout()取消延迟操作。

var a = setTimeout(function(x, y) {
                document.write(x, " ", y)//hello world
            }, 1000, "hello", "world")
            clearTimeout(a)//取消延迟操作
  1. 定时操作
    每间隔一段时间执行一次操作。
    语法: window.setInterval(code, milliseconds, param1, param2, ...);
    参数与setTimeout()相同。
    返回值是一个ID(数字),可以使用window.clearTimeout()window.clearInterval取消定时操作。

  2. AJAX
    AJAX(Asynchronous JavaScript and XML) 异步的 JavaScript 和 XML。
    AJAX 是一种用于创建快速动态网页的技术,通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。

var http;
                //创建请求对象
                if (window.XMLHttpRequest) {
                    http = new XMLHttpRequest()
                } else {
                    //适配IE5 6
                    http = new ActiveXObject("Microsoft.XMLHTTP")
                }
                //使用回调函数
                http.onreadystatechange = function() {
                    if (http.readyState == 4&&http.status == 200) {
                        document.write(http.responseText)//使用String类型数据
                        // document.write(http.responseXML)//使用XML类型数据
                    }
                }
                //GET时配置请求参数
                http.open("GET", "./response.php?name=zhangsan&age=18", true);
                //发送请求
                http.send();
                
                // //Post时配置请求参数
                // http.open("POST", "./response.php", true)
                // //设置http头
                // http.setRequestHeader("Content-type","application/x-www-form-urlencoded")
                // //发送请求
                // http.send("name=zhangsan&age=18")
            }

使用new XMLHttpRequest()创建请求对象。
使用open()配置请求的参数。

使用send()发送请求。

使用setRequestHeader()传入HTTP头,POST类型时需要,如setRequestHeader("Content-type", "application/x-www-form-urlencoded")

XMLHttpRequest 对象有三个重要的属性。readyState表示 XMLHttpRequest 对象的状态,status表示http请求的状态,onreadystatechange为readyState改变时的回调函数。

  1. Promise
    可让异步操作以同步操作(链式)的流程形式表现出来,使控制异步操作更加容易且更美观。
    Promise有三种状态:
    • pending 初始状态,不是成功或失败状态。
    • fulfilled 成功状态。该状态下可以调用then()函数。
    • rejected 失败状态。该状态下可以调用catch()函数。
var promise = new Promise(function(resolve, reject) {
                //执行异步操作
                resolve()
            })
            promise.then(function(value) {
                retrun ""
            }).catch(function(error) {
                
            }).finally(function() {
                
            })

Q&A:
Q: then、catch 和 finally 序列能否顺序颠倒?
A: 可以,效果完全一样。但不建议这样做,最好按 then-catch-finally 的顺序编写程序。
Q: 除了 then 块以外,其它两种块能否多次使用?
A: 可以,finally 与 then 一样会按顺序执行,但是 catch 块只会执行第一个,除非 catch 块里有异常。所以最好只安排一个 catch 和 finally 块。
Q: then 块如何中断?
A: then 块默认会向下顺序执行,return 是不能中断的,可以通过 throw 来跳转至 catch 实现中断。
Q: 什么时候我们需要再写一个 then 而不是在当前的 then 接着编程?
A: 当你又需要调用一个异步任务的时候。

十一、DOM

DOM为Document Object Model(文档对象模型),用于操作 HTML 元素。


文档是一个文档节点,所有的 HTML 元素都是元素节点,所有 HTML 属性都是属性节点,文本插入到 HTML 元素是文本节点,注释是注释节点。
Document 对象是 HTML 文档的根节点。
Document 对象使我们可以从脚本中对 HTML 页面中的所有元素进行访问。
Document 对象是 Window 对象的一部分,可通过window.document属性对其进行访问,window可省略。
元素对象代表着一个 HTML 元素。
元素对象的子节点可以是元素节点、文本节点、注释节点。
元素对象有属性,属性属于属性节点。

节点树中的节点彼此拥有层级关系。
我们常用父(parent)、子(child)和同胞(sibling)等术语来描述这些关系。父节点拥有子节点。同级的子节点被称为同胞(兄弟或姐妹),同胞是拥有相同父节点的节点。
在节点树中,顶端节点被称为根(root)。
每个节点都有父节点、除了根(它没有父节点)。
一个节点可拥有任意数量的子节点。

DOM全部属性和方法详见DOM Document 对象

  1. 查找元素element
  1. HTMLCollection 对象
    HTMLCollection是 HTML 元素的集合,是一个伪数组,不能使用数组的某些方法。
    可以使用Array.prototype.slice.call(col)Array.prototype.slice.apply(col)Array.prototype.slice.bind(col)() 将 HTMLCollection 对象转换成一个数组,参数col为 HTMLCollection 对象。

    • 使用length获取元素的数量。
    • 使用item(index)[index]获取对应索引index的元素。
    • 使用namedItem(name)[name]获取对应name或id的元素。参数name即为<div id="" name=""></div>中的id或name的值,有一个相同即可。
  2. NodeList对象
    NodeList 是一个文档节点的集合,包含属性节点和文本节点,是一个伪数组,不能使用数组的某些方法。
    和 HTMLCollection 对象一样,可以使用call、apply、bind转换成数组。

    • 使用length获取元素的数量。
    • 使用item(index)[index]获取对应索引index的元素。

与 HTMLCollection 对象的不同点
removeChild()删除一个节点后,之前 NodeList 对象的元素数量不会变化,而之前 HTMLCollection 对象的元素数量会减少。
即 HtmlCollection 是动态绑定的,对节点的增删是敏感的。

  1. 修改元素
  1. 操作元素
var ele = document.createElement("div")//创建元素节点
            var text = document.createTextNode("hello")//创建文本节点
            ele.appendChild(text)//ele将文本节点添加为子节点
            
            var att = document.createAttribute("style")//创建属性节点
            att.value = "color: red;"//设置属性节点的值
            ele.setAttributeNode(att)//ele添加属性节点att
                        
            var com = document.createComment("comments");//创建注释节点
            ele.appendChild(com);//ele添加注释节点 但注释不可见
            
            document.body.appendChild(ele)//body上添加子节点ele

十二、BOM

BOM 是浏览器对象模型(Browser Object Model),即 window。
window 表示浏览器窗口。全局变量是 window 对象的属性,全局函数是 window 对象的方法。
DOM 中的 document 也是 window 对象的属性,document 详见 十一、DOM
使用 window 对象的属性或方法时,可以省略window,即window.innerHeight可省略成innerHeigh
全部属性与方法详见Window 对象

  1. screen
    window.screen 对象包含有关用户屏幕的信息,有屏幕宽、高、色彩等属性。
    属性和方法详见 JavaScript 参考手册 -- Screen 对象

  2. location
    window.location 对象包含当前页面的 URL 信息,可使用location.assign()加载新页面。
    属性和方法详见 JavaScript 参考手册 -- Location 对象

  3. history
    window.history 对象包含浏览器的历史记录,可使用history.back()后退到上一个页面,history.forward()前进到下一个页面。
    属性和方法详见 JavaScript 参考手册 -- History 对象

  4. navigator
    window.navigator 对象包含有关当前浏览器的信息。
    属性和方法详见 JavaScript 参考手册 -- Navigator 对象
    注:
    来自 navigator 对象的信息具有误导性,不应该被用于检测浏览器版本,这是因为:
    navigator 数据可被浏览器使用者更改。
    一些浏览器对测试站点会识别错误。
    浏览器无法报告晚于浏览器发布的新操作系统。

  5. 弹框
    JS 中有三种消息框:警告框、确认框、提示框。
    弹框会阻止代码执行,只有点击了确定或取消后才会继续执行代码。
    window.alert() 警告框,只有消息和确定。
    window.confirm() 确认框,有消息、取消和确定。返回一个布尔,为true表示点击了确定。
    window.prompt() 输入框,有消息、输入框、取消和确定。点确定后会返回输入的值。

  6. cookie
    window.document.cookie用于存储页面的用户信息,是存在于本地的数据。
    cookie是通过键值对保存的,键值用=连接,如key=value
    有些key有默认的作用,expires表示过期时间,path表示cookie的路径。
    注:若不设置过期时间,那么cookie的有效时间为当前窗口关闭之时,并且是存储在内存中。

  1. storage
    storage分为window.sessionStorage(会话存储)和window.localStorage(本地存储),它们都可以对网页的数据进行增删查改,保存的数据是键值对,它们都是只读的。
    localStorage用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。
    sessionStorage用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。

localStorage 拓展了 cookie 的 4K 限制。
localStorage在浏览器的隐私模式下面是不可读取的。
localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡。
每个页面都有自己的localStorage,不同页面之间不能访问对方的localStorage。
而当前页面能访问其他页面的cookie,但设置 阻止第三方cookie 后,也不能访问其他页面cookie了。

  1. 其他
上一篇 下一篇

猜你喜欢

热点阅读