JavaScript 学习归纳

一、简介

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

二、调试

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

  2. 写入文档 write()
    使用document.write()将内容写入文档中。内容也可传入 html 语句,如document.write("

    1号标题

    ")。可传入多个参数,用逗号隔开。
    要注意的是,若在文档加载完成后再使用该方法,内容会直接覆盖整个文档。

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

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

  4. 获取元素 getElementById()
    使用document.getElementById()通过传入的元素id来获取元素。使用元素的innerHTML属性来获取元素的内容,即

    123
    中的123,也可修改内容,如document.getElementById("id").innerHTML = "修改内容"


        
div1
div2
JavaScript 学习归纳_第1张图片
  1. 断点
    在要添加断点的代码处输入debugger。运行后,会在这个位置停止运行。
    在浏览器中按 F12 并选择 Sources 可以看到断点时的变量的值。

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

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

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

三、变量与常量

  1. 字面量
    在 JS 中,固定值一般称为字面量,字面量用来赋值给变量或常量。
  • 数字(Number)
    可为整数1、小数1.1、科学计数1e2
  • 字符串(String)
    字符串可使用双引号"string"或单引号'string'
    字符串里也可以有引号,但不能和外层引号相同。如"hello 'world'"'hello "world"'
    若需要里面引号与外层引号相同,要使用转义符\,如"hello \"world\""
    字符串可以用\换行,但代码不美观,如
            // 字符串换行
            document.write("hello \
world")

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

  • 表达式字面量
    1 + 2 "1" + "2"
  • 数组(Array)
    用中括号包裹,里面可为数字、字符串、数组、对象、函数。如[1, "string", {key: "value"}]
  • 对象(Object)
    用大括号包裹,为key-value对,key为字符串,value可为数字、字符串、数组、对象、函数。如{a: 1, b: "b", c: [1, 2]}
    若key中有空格,需要使用引号,如{"aa bb": 20}
  • 函数(Function)
    function(a, b) { return a * b; }
  1. 类型判断
  • 使用typeOf判断类型。
    但不能判断数组、正则和对象,返回的都是object。
    可以写成typeof(1),也可以写成typeof 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()判断是否为数组
            // 判断是否支持isArray方法
            if (Array.isArray) {
                document.write(Array.isArray([1, 2]))//true
                document.write(Array.isArray({a: 1}))//false
            }
  • 使用Instanceof判断类型
    不能用于判断对象,因为数组、正则和对象调用instanceof Object都会返回true。
document.write([1, 2] instanceof Array)//true
            document.write({a: 1} instanceof Array)//false
            
            document.write([1, 2] instanceof Object)//true
  • 使用constructor属性判断类型
    该属性会返回构造函数。
function type(obj) {
                return obj.constructor
            }
            document.write(type(1), "
")//function Number() { [native code] } document.write(type("1"), "
")//function String() { [native code] } document.write(type([1, 2]), "
")//function Array() { [native code] } document.write(type({a: 1}), "
")//function Object() { [native code] } document.write(type(function a() {}), "
")//function Function() { [native code] } document.write(type(/\d+/g), "
")//function RegExp() { [native code] }
  1. 变量
    变量命名可使用小驼峰firstName、大驼峰FirstName、下划线法first_name,建议使用小驼峰。
    变量通常以字母开头,且对大小写敏感。
  • var
    声明变量var a
    声明多个变量var a, b
    变量未赋值时默认为undefined
    声明变量并赋值var a = 1
    声明多个变量并赋值var a = 1, b = 2
    变量是可变的,可在声明变量后改变变量的值。如var a = 1;a = 10;
    重新声明变量后,变量值不会清空。如var a = 1;var a;,此时a还是为1。
    未声明直接赋值时,如a = 1,相当于var a;a = 1
    注:语句后面可不加分号,但多条语句在同一行时,则必须添加分号。如如var a = 1;a = 10;

  • let
    let也是一个变量,声明方式与var一致,但let只在包含它的{ }里(当前块作用域)有效,而var在{ }外(上级块作用域)也生效。for循环( )中声明的let变量也只在循环体内有效。

    document.write(a, "
")//undefined { var a = 1 } document.write(a, "
")//1 document.write(b, "
")//error b is not defined { let b = 2 } document.write(b, "
")//error b is not defined

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

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

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

  1. 全局变量
    内函数外直接声明的叫全局变量,可以在该脚本中任意地方使用。
    在函数内声明的变量叫局部变量,只在函数内有效。局部变量中的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, "
")//1 document.write(window.e, "
")//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变量与常量也不应该同名。
使用函数与变量时,都应该先声明再使用,这样不会产生隐性问题。声明也应该放在代码最上面。

  • 严格模式
    可以在脚本的开头添加"use strict"来使用严格模式。也可以在函数的开头添加,使严格模式只有该函数内生效。
    严格模式下必须先声明才能使用变量和函数,更多限制查看严格模式。
    使用严格模式可以保证代码运行的安全;提高编译器效率,增加运行速度;
    注:"use strict"的上面不能有代码(可以有注释),否则严格模式无效。
  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

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

  • 值类型
    值类型分为字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、独一无二的值(Symbol)。
    值类型是存放在栈内存(Stack)里的,两变量相等时,修改一个变量的值不会影响另一个变量。
var a = 5
            var b = a
            a = 6
            document.write(a, b)//6 5
  • 引用类型
    引用类型分为对象(Object)、数组(Array)、函数(Function)。
    引用类型的值保存在堆内存(Heap)中的,栈内存中只存放值在堆内存中的指针地址。
    当修改元素的值,修改的是堆内存中的值,所有指向该对象的变量的值都会改变。
    为变量赋另一个值时,变量失去之前值的指针,与之前值再无关系。
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 字符串
  • 初始化
    使用字面量:var a = "hello 'world'"
    使用构造函数:var a = new String("hello 'world'")。但此时typeof a == object
  • 访问字符
    使用[]来访问每个字符,如a[3],表示获取索引为3的字符,索引有效值为0到length-1。length表示字符串的长度。
    或使用charAt()访问每个字符,a[3]相当于a.charAt(3)
  • 转换成字符串
    String(exp) 将表达式转换成字符串。表达式可以是一个变量或常量。
    exp.toString() 将表达式转换成字符串。
    string.toUpperCase() 将字符串转换成大写字符串。
    string.toLowerCase() 将字符串转换成小写字符串。
  • 运算字符串
    使用+来拼接字符串,如"a" + "b" == "ab",相当于"a".concat("b")

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

  1. Number 数字
  • 初始化
    使用字面量:var a = 1.1。可为整数1、小数1.1、科学计数1e2
    使用构造函数:var a = new Number(123),但此时typeof a == object
    整数前加0,表示使用八进制;前面加0x,表示使用十六进制。
    使用toString()可进制转换,如(10).toString(2) == 1010,不加括号时会报错,因为解析器会把10.看成10,但可以使用10..toString(2)
    注:在 JS 中,整数实际上是浮点类型。
  • 精度
    整数最多为15位。如2222222222222222(16个2),打印出来是1000000000000000(15个0)
    小数的小数部分最多为17位。如0.1 + 0.2 == 0.30000000000000004(小数部分共17位),所以0.1 + 0.2 != 0.3
    可以通过(0.1*10 + 0.2*10)/10 == 0.3来比较。只要整数部分不为0,就能正常比较,如1.1 + 0.2 == 1.3
  • 特殊值
    infinity 无穷大,一个数字除以0结果为infinity。
    infinity与任何值加减乘除都是infinity,即infinity + 1 == infinity
    正负无穷不相等,即infinity != -infinity
    NaN 非数值(Not a Number)。一个表达式不能转换成数字就会返回NaN,即Number("abc") == NaN
    非数值与任何值都不相等,包括本身,即NaN != NaN
    使用Number.isNaN()用于判断是否为NaN,如Number.isNaN(Number("a")) == true
  • 转换成数字
    Number(exp) 将表达式转换成数字。表达式可以是一个变量或常量。
    +exp 将表达式转换成数字,如+"50" == 50
    parseFloat(exp) 将表达式转换成浮点。
    parseInt(exp) 将表达式转换成整数。
    注:若不能转换成数字,则会返回NaN。

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

  1. Boolean 布尔
  • 初始化
    使用字面量:var a = true
    使用构造函数:var a = new Boolean(true),但此时typeof a == object
    若无初始值或者其值为0、-0、null、""、false、undefined、NaN,布尔值为false。
  • 转换成布尔
    Boolean(exp) 将表达式转换成布尔。表达式可以是一个变量或常量。
    !!exp 将表达式转换成布尔。
    注:0、-0、null、""、false、undefined、NaN会转换成false,其余全部都会转换成true。

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

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

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

  3. Symbol 独一无二的值

  • 初始化
    语法:var a = Symbol()。
    symbol是唯一的,即使里面的值相等symbol也不相等,如Symbol("123") != Symbol("123")
    若想获取同一个symbol,可使用Symbol.for(),如Symbol.for("123") === Symbol.for("123")
    若想获取symbol的值,可使用Symbol.keyFor()
            let sym = Symbol.for("b");
            document.write(Symbol.keyFor(sym))//b
  • 用法
    symbol被用作对象的key。但symbol拥有隐藏性,所以不能通过for···in等常规遍历方式获取key。
let sym = Symbol.for('b');
            var a = {
                [sym]: "1",
                c: "2"
            }
            for (key in a) {
                document.write(key, "
")//c }

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

  1. Object 对象
    JS 中的所有事物都是对象,数字、日期、字符串、布尔等都是对象。
    对象是带有属性和方法的特殊数据类型,属性通过objectName.propertyName来使用,方法通过objectName.methodName()来使用。如message.lengthmessage.toUpperCase()
  • 字面量初始化
    var a = { a: 1, b: 2 }
    键值对的键为字符串,使用时不必加引号,若字符串中有空格,则必须加引号,如var a = { "a b": 1 }
    键值对的值为包括null和undefined在内的数据类型。
    若键是一个变量,需要在变量两头加上[],如var a = "name"; var b = { [a]: "zhangsan" }
    注:对象最后的元素后不能加逗号。
  • 构造函数初始化
    var a = new Object({ a: 1, b: 2 })
    另外,new Object(true)new Boolean(true)完全相同,类型都为object。
    通常使用var a = new Object();e.name = "zhangsan";这种方式来创建键值对的对象。
  • 函数初始化
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
  • 访问元素
    使用.来访问元素,如e.name
    或使用[]来访问元素,如e["name"]。当键为带空格的字符串时,必须使用[],如e["a b"]
    若元素值是一个函数,加()时执行函数,则返回函数的返回值;不加()则返回函数的代码。
    对象的函数中,this指的是对象本身。
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
  • 原型对象
    所有的 JS 对象都会从一个 prototype(原型对象)中继承属性和方法。
    Date 对象从Date.prototype继承,Array 对象从Array.prototype继承,String 对象从String.prototype继承,而它们都是Object,所以它们都继承于Object.prototype
    当访问一个对象的属性或方法时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾(Object.prototype)。
    可以通过原型对象prototype给对象添加新的属性或方法。
            // 给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 数组
  • 初始化
    使用字面量:var a = [1, 2, 3],最后的元素后不能加逗号。
    使用构造函数:var a = new Array(1, 2, 3)

  • 访问元素
    使用[]访问数组的元素,如a[1]。 索引范围为0到length-1,length为数组元素的数量。
    也可以通过[]来修改元素的值,如a[1] = 11

  • 数组运算
    使用concat()拼接数组,如[1, 2, 3].concat([4, 5]) == [1, 2, 3, 4, 5]
    使用+,但与concat()有差别,如[1, 2, 3] + [4, 5] == "1, 2, 34, 5",最终变成了字符串。

  • 数组修改
    使用push()在末尾新增一个或多个元素,如[1, 2, 3].push(4)后原数组变为 [1, 2, 3, 4]。
    使用pop()删除末尾的元素,如[1, 2, 3].pop()后原数组变为 [1, 2]。
    使用unshift()在开头新增一个或多个元素,如[1, 2, 3].unshift(4)后原数组变为 [4, 1, 2, 3]。
    使用shift()删除开头的元素,如[1, 2, 3].shift()后原数组变为 [2, 3]。
    使用splice()删除并添加元素,如[1, 2, 3, 4].splice(1, 2, 10, 11, 12)后原数组变为 [1, 10, 11, 12, 4]。前两个参数表示在索引1处删除2个元素,后面的参数表示在索引1处新增元素10、11、12。

  • 数组遍历
    使用for循环,详见 八、条件语句 -- 3. for
    使用forEach(function(currentValue,index,arr), thisValue)

    • 回调函数为必须值,每个元素都会调用该函数。
      • currentValue 元素值,必须。
      • index 元素的索引。
      • arr 遍历的数组。
    • thisValue 函数中this的值。

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

  1. 函数(Function)
  • 函数声明
    语法:function functionName(var1, var2) { return true }

    • functionName 函数名,可任意大小写。
    • var1, var1 参数,可有0个或多个参数,用逗号隔开。
    • return 返回值,给执行函数返回一个值,也可以不返回。return后立即退出函数,后面的代码无效。
  • 调用函数
    语法:var result = functionName("value1", "value2")

    • var result 若函数有返回值,则获取返回值。若函数无返回值,var result可省略。
    • functionName("value1", "value2") 调用函数,若函数无参数,则使用functionName()
    • "value1", "value2" 函数传入的参数。

    在函数中,this指向函数的所属者,即 window 对象。所以functionName()window.functionName()相同。

  • 使用call和apply调用函数
    语法: functionName.apply(para1, para2)functionName.call(para1, para2, para3...)

    • functionName 声明的函数名。
    • para1 函数中this的值。若传入null或undefined,this则会变为 window 对象。
    • para2 在apply方法中是一个数组,数组的元素值为要调用函数的参数。
      在call方法中是要调用函数的第一个参数,para3则是第二个参数,以至类推。
  • 自调用函数
    将一个函数前后加上(),再在后面添加(),就可以函数自调用。

(function functionName(para) {
                document.write(para, "
") })("hello")//hello

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

箭头函数自调用(() => {})()

  • 特殊函数声明
    匿名函数 const functionName = function (var1, var2) { return true }
    箭头函数 const functionName = (var1, var2) => { return true }
    若只有一个参数,可以省略()。若只有一句表达式,可以省略{},如const functionName = var1 => return true
    构造函数 const functionName = new Function("var1", "var2", "return true"),尽量少用。
    这几种函数的调用方式与普通的相同。
  • 函数声明提升
    函数也能够声明提升,而且比变量优先提升,所以同名变量会覆盖同名函数。
    但上面三种特殊函数声明就不能提升,因为它实际在是一个常量,当然,即使改成var也不能提升。
    函数中的声明的变量只作用于函数,在函数执行时创建,并在函数结束后删除。
    若在函数内使用未声明的变量,则函数会将该变量变为全局变量。
            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会变成一个全局变量
  • 函数参数
    若传入的参数比需要的多,则忽略多余的入参;若传入的参数比需要的少,则未传的会用undefined代替。
    函数可以给入参设置默认值,如function functionName(x, y = 1) { }
    函数里可使用一个对象arguments,它是所有入参值的数组。可通过arguments[index]获取入参的值。
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, "
")//function () { return x += arguments[0] } document.write(typeof y, "
")//function y是一个函数 var outX = y(20)//这里就使用了函数里的变量与20相加 实现了在函数外使用函数内的变量这个功能 document.write(outX, "
")//30

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

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

            //自调用
            var y = (function() {
                var x = 10
                return function() { return x += arguments[0] }
            })()
            var outX = y(20)//30
  • 全局函数与属性
    JS 已创建好的能直接使用的属性与函数。
    详见全局属性/函数。

五、其他数据类型

  1. 日期 Date
  • 初始化
    当前日期:var a = new Date()
    传入时间戳:var a = new Date(1000*3600*24*365*10)
    传入日期字符串:var a = new Date("2021-02-01 10:20:30")
    传入年月日时分秒毫秒:var a = new Date(2021, 5, 1, 12, 13, 14, 0),前两个参数必传,因为只传一个参数的时候是时间戳。

  • 修改日期
    使用setHours()来修改小时数,如a.setHours(a.getHours() + 5)表示增加5小时。
    同样的,修改年setFullYear()、月setMonth()、日setDate()、时setHours()、分setMinutes()、秒setSeconds()、毫秒setMilliseconds()、时间戳setTime()
    使用setTime()时需要时间戳,可以通过Date.parse()获取,如a.setTime(Date.parse(a.toString()) + 1000*3600*24*1)表示增加一天。

  • 比较日期
    可通过>、>=、<、<=来比较日期。

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

  1. Math 数学
    Math主要是用于执行科学计算。
  • 算术值
    Math.E 自然对数的底数e(约为2.718)。
    LN10 10的自然对数(约为2.302)。
    Math.PI 圆周率π(约为3.14)。
    Math.SQRT2 2的平方根(约为1.414)。
  • 算数方法
    Math.sin()、Math.cos()、Math.tan()为正弦、余弦、正切,参数为弧度。
    Math.abs() 绝对值。
    Math.ceil()、Math.floor()、Math.round()为上舍入、下舍入、四舍五入,即ceil(1.3) == 2、floor(1.6) == 1、round(1.5) == 2
    Math.min(x, y...)、Math.max(x, y...)为最小值、最大值。
    Math.random() 0~1之间的随机数。使用Math.floor(Math.round()*100)获取<100的随机数;使用Math.floor(Math.round()*(100-50))+50获取>=50并且<100的随机数。

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

  1. RegExp 正则表达式
    正则表达式(Regular Expression,简写为regex、regexp或RE)使用单个字符串来描述、匹配一系列符合某个句法规则的字符串搜索模式。正则表达式是匹配字符串的条件。
  • 初始化
    使用字面量:var a = /world/i
    使用构造函数:var a = new RegExp("world", "i")
    第一个参数是表达式的模式,若模式中要使用\字符,则需要使用转义符,如var a = /w\\orld/i
    第二个参数为修饰符。

  • 修饰符
    修饰符是可选的,并且不区分大小写。
    修饰符有igm三种,并且可同时使用多种,如/a/gi
    i 大小写不敏感。/A/i能匹配abcd中的a。
    g 全局匹配。/a/g匹配abacad时,能匹配到3个a,默认时只能匹配第一个a。
    m 多行匹配。???

  • 匹配
    使用test()测试是否能匹配成功字符串,如/wor/i.test("hello world") == true
    使用exec()获取匹配成功的字符串,如/w[opq]r/i.exec("hello world") == "wor"
    当存在g修饰符时,可连续调用test()exec()来进行匹配,lastIndex属性指示下次匹配的起始位置。

var b = /bc/g
            var c = "abcdefgbcba"
            document.write(b.test(c), b.lastIndex, "
")//true3 document.write(b.test(c), b.lastIndex, "
")//true9 document.write(b.test(c), b.lastIndex, "
")//false0 未匹配到时lastIndex会重置为0
  • 表达式模式
    条件:
    []匹配中括号中的任意字符,如"abdc".match(/[bc]/g) == ['b', 'c']
    [^]匹配不在中括号中的字符,如"abdc".match(/[^bc]/g) == ['a', 'd']
    里面可以使用连接符,0-9表示任何0到9的数字,A-Z、a-z、A-z表示任何大写字母、小写字母、字母。
    (x|y|z) 匹配|左边条件或右边条件,如"abcdefg".match(/(bc|ce|ef)/g) == ["bc", "ef"]
    字符:
    . 匹配所有字符(除了换行符与行结束符)。
    \w 匹配数字、字母、下划线,相当于[0-9A-z_]
    \W 匹配非数字、字母、下划线,相当于[^0-9A-z_]
    \d 匹配数字,相当于[0-9]
    \D 匹配非数字,相当于[^0-9]
    \s 查找空白字符,相当于[ ]
    \b 匹配单词边界,如"aabc abcd".search(/\babc/g) == 5,会匹配第二个abc。测试出只对单词开头有效,结尾无效。
    \B 匹配非单词边界。
    量词:
    表示匹配多少个字符。
    n+ 至少有一个n,即数量>1。
    n* 任意数量的n,即数量>=0。
    n? 至多有一个n,即数量<=1 。
    n{3} 有三个n,即数量=3。
    n{3,} 有至少三个n,即数量>=3
    n{1, 3} 有一到三个n,即数量>=1并且<=3。
    特殊:
    ^n 以n开始。
    n$ 以n结束。
    ?=n 匹配后接n的字符串,如"aabcde".match(/ab(?=c)/g) == ["ab"]
    ?!n 匹配不后接n的字符串。

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

六、事件触发

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

  1. 标签中绑定事件
    语法:

关于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 事件对象

  • void
    void是 JS 中非常重要的关键字,它表示 运行一个表达式但是不返回值。
    语法:void expjavascript:void expvoid(exp)javascript:void(exp)
    exp 一个表达式,可以是普通语句void(this.innerHTML = 'hello')或一个函数void(alert('warn!'))
    使用javascript:void(0)不会产生任何变化,常用于死链接。
// 阻止链接跳转,URL不会有任何变化
点击此处
// 虽然阻止了链接跳转,但URL尾部会多个#,改变了当前URL。(# 主要用于配合 location.hash)
点击此处
// 同理,# 可以的话,? 也能达到阻止页面跳转的效果,但也相同的改变了URL。(? 主要用于配合 location.search)
点击此处
  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则为捕获。

事件传递定义了元素事件触发的顺序。 如果你将

元素插入到

元素中,用户点击

元素, 哪个元素的 click 事件先被触发呢?
在冒泡中,内部元素的事件会先被触发,然后再触发外部元素,即:

元素的点击事件先触发,然后会触发

元素的点击事件。
在捕获中则相反。

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

  • 移除监听
    如果要移除事件句柄,执行函数必须使用外部函数,如上面的第一个例子。
    匿名函数,类似document.getElementById("id").addEventListener("click", function() { })是无法移除的。
    语法: element.removeEventListener(event, function, useCapture)
    参数同addEventListener()

七、运算符

  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
            }
  • for in
    用来遍历数组或对象,也可以遍历字符串。
    语法: for (index in data) { repeatCode }

    • data 数据。可为数组、对象、字符串。
    • index 索引。
      当data为数组或字符串时,索引范围从0到length-1,使用data[index]来获取元素或字符。
      当data为对象时,索引为对象的键key,使用data[index]来获取对应的值value

    注:for in的小括号不能删除(有些语言不使用小括号)。
    当数组中有元素值为undefined时,for in循环会跳过这些元素,而for循环则会全部元素依次遍历。

  • for of
    用来遍历数组和字符串。
    语法: for (let ele of data) { repeatCode }
    for in用法类似,但ele返回的是数组的元素或字符串的字符。
    let表示变量ele只能在repeatCode中使用;使用var表示变量ele能用在循环外,且ele的值为最后一次遍历时ele的值。
    注:for of的小括号不能删除。

  1. while
    条件为真则一直循环代码。
    语法: while (condition) { repeatCode }
    • condition 条件。可以设置为true,但repeatCode中必须要有break以结束循环。
    • repeatCode 循环代码。需要在代码中改变某值以使condition不能一直为true。
  • do while
    语法:do { repeatCode } while (condition)
    while用法大致相同,不同之处是 会先执行一次repeatCode 再判断condition。
  1. 影响循环
  • break
    switch中,表示结束switch的比较。
    for、while循环中,表示结束循环。
  • continue
    for、while循环中,表示直接结束这次遍历,开始下一次的遍历。
    这会使continue后面的代码在这次遍历中不会执行,但前面的代码不会受影响。

九、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之间相互转换。

  • 转换成Object
    使用JSON.parse(josn, transform)将JSON转换成对象Object。
    • json 要传入的json字符串。
    • transform 可选参数,它是一个函数,会为对象的每个键值对调用此函数。
      该函数有两个参数,分别为键值对的键与值,函数返回值会替换原键值对的值。
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, "
")//10
  • 转换成JSON
    使用JSON.stringify(value, replacer, space)将对象转换成JSON。
    • value 对象或数组。
    • replacer 可选参数。
      • 它可以是一个函数,会为对象的每个键值对调用此函数。该函数有两个参数,分别为键值对的键与值,函数返回值会替换原键值对的值。若返回undefined,则会排除该键值对。
      • 也可以是一个数组,仅转换该数组中具有键值的成员。成员的转换顺序与键在数组中的顺序一样。
    • space 可选参数,文本添加缩进、空格和换行符。
      • 若是一个数字,则返回值文本在每个级别缩进指定数目的空格;若大于 10,则文本缩进10个空格。
      • 也可以使用非数字,如\t
var b = {a: 1, b: 2, c: 3, d: 4}
            var json = JSON.stringify(b)
            document.write(json, "
")//{"a":1,"b":2,"c":3,"d":4} var json = JSON.stringify(b, null, 1) document.write(json, "
")//{ "a": 1, "b": 2, "c": 3, "d": 4 } json = JSON.stringify(b, ["b", "c"]) document.write(json, "
")//{"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, "
")//{"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()配置请求的参数。

  • 参数1表示请求类型,常使用GET、POST
  • 参数2表示请求的文件地址,可以是本地的txt、也可以是服务器上的php、asp等。
  • 参数3表示异步还是同步,为true表示异步。

使用send()发送请求。

  • POST类型时需要传入参数,参数值为请求的参数,如send("name=zhangsan&age=18")
  • GET类型时,请求的参数拼接在open()的参数2上,如open("GET", "./response.php?name=zhangsan&age=20", ture)

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

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

  • readyState
    0: 请求未初始化
    1: 服务器连接已建立
    2: 请求已接收
    3: 请求处理中
    4: 请求已完成,且响应已就绪
    new XMLHttpRequest()之后,readyState变为0,open()后readyState变为1,send()后变为2。
  • status
    详见HTTP状态码,200表示成功。
  • onreadystatechange
    通常在回调中通过readyState == 4&&status == 200判断请求完成,此时使用responseText属性获取String类型的数据,使用responseXML属性获取xml类型的数据。
  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() {
                
            })
  • 创建 Promise 对象
    使用var promise = new Promise(function(resolve, reject) { })创建一个 Promise 对象。

    • 需要传入一个函数,该函数有两个参数resolve、reject,两参数都是回调函数。
      异步操作写在该函数内,操作完成后,调用resolve()reject()将 Promise 对象变为fulfilledrejected状态。

    Promise 对象默认是pending状态,若转变为fulfilled,对象就会继续执行then()方法;若转变为rejected,对象就会继续执行catch()方法。

  • then
    只有fulfilled状态的 Promise 对象才会执行该方法。

    • 需要传入一个函数,函数有一个参数value,值与resolve()传入的参数相同。
      value通常是请求网络接口后返回的数据,一般在函数里处理数据。
    • 函数需要返回一个 Promise 对象,若状态为fulfilled,就会继续执行下一个then()方法;若状态为rejected,就会跳过后面的then()直接执行catch()方法;若状态为pending,就会一直等待 Promise 对象转换状态。
    • 也可以返回一个基础类型(String、Array等)的值。相当于返回了一个 Promise 对象,该对象回调了resolve(),且传入的参数为基础类型的值。
    • 也可以不返回,相当于resolve()传入的参数是undefined。
  • catch
    只有rejected状态的 Promise 对象才会执行该方法。

    • 需要传入一个函数,函数有一个参数error,值与reject()传入的参数相同。
      通常是 Error 对象,详见 二、调试 -- 6. 异常处理
      error通常是请求网络接口后返回的错误信息,一般在函数里弹出提示信息。
  • finally
    fulfilledrejected状态的Promise对象都能执行该方法。

    • 需要传入一个函数。可以在函数里执行一些公共操作,如隐藏加载的菊花。

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: 当你又需要调用一个异步任务的时候。

  • all
    语法: var promise = Promise.all([promise1, promise2])

    • 需要传入一个数组,数组元素是 Promise 对象。
    • 会返回一个 Promise 对象。
      • 若数组所有元素的状态都是fulfilled,返回的对象的状态就是fulfilled,且回调值value是数组元素的回调值value组成的数组;
      • 若数组有一个元素的状态为rejected,返回的对象的状态就是rejected,且回调值error为该元素的回调值error。

    通常用该方法来同时调用多个网络接口,都成功后就显示界面,有一个失败就显示错误信息。

  • race
    语法: var promise = Promise.race([promise1, promise2])

    • 需要传入一个数组,数组元素是 Promise 对象。
    • 会返回一个 Promise 对象,对象的状态是数组中最先转变状态的 Promise 对象的状态。
  • resolve
    语法: var promise = Promise.resolve()

    • 需要传入基础类型(String、Array等)的值,返回一个状态为fulfilled的 Promise 对象。
      var promise = new Promise(function(resolve, reject) { resolve() })作用相同。
    • 也可以传入 Promise 对象,该对象会原封不动的返回。
  • reject
    语法: var promise = Promise.reject()

    • 需要传入基础类型(String、Array等)的值或 Error 对象,返回一个状态为rejected的 Promise 对象。
      var promise = new Promise(function(resolve, reject) { reject() })作用相同。

十一、DOM

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

JavaScript 学习归纳_第2张图片

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

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

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

  1. 查找元素element
  • 通过id
    语法:document.getElementById()

    • 需要传入一个参数,即
      中id的值。
    • 返回元素对象,若没有找到,则返回null。

    元素对象的属性和方法详见 JavaScript 参考手册 -- DOM 元素对象

  • 通过标签名
    语法:document.getElementsByTagName()element.getElementsByTagName()

    • 需要传入一个参数,即
      中的div。
    • 返回 HTMLCollection 对象,相当于数组。
  • 通过类名
    语法:document.getElementsByClassName()element.getElementsByClassName()

    • 需要传入一个参数,即
      中class的值。
      多个类名使用空格分隔,如document.getElementsByClassName("test1 test2")
    • 返回 HTMLCollection 对象,相当于数组。
  • 通过名称
    语法:document.getElementsByName()

    • 需要传入一个参数,即
      中name的值。
    • 返回 NodeList 对象,相当于数组。
  • 通过CSS选择器
    语法:document.querySelectorAll()element.querySelectorAll()

    • 需要传入一个参数,为CSS选择器。即

      中的p、#id、.class,多个选择器用逗号隔开。

    • 返回 NodeList 对象,相当于数组。

    document.querySelector()querySelectorAll()用法相同,但只返回 NodeList 对象的第一个元素。

  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即为
      中的id或name的值,有一个相同即可。
  2. NodeList对象
    NodeList 是一个文档节点的集合,包含属性节点和文本节点,是一个伪数组,不能使用数组的某些方法。
    和 HTMLCollection 对象一样,可以使用call、apply、bind转换成数组。

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

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

  1. 修改元素
  • 修改内容
    语法:element.innerHTML = 新内容
    innerHTML是元素的一个属性,即

    hello

    中的

    hello


    可修改该属性来改变 HTML 元素的内容,如 document.getElementById("id").innerHTML = "hello"

  • 修改元素属性值
    语法:element.attributeName = 新属性值
    attributeName是标签的各种属性名,如中的id、src、class。
    通过该方法可改变元素的各种标签属性值,如document.getElementById("id").src= "./demo.png"

  • 修改样式
    语法: element.style.CSSName=" "
    CSSName是CSS的属性名,如backgroundColor、font
    通过该方法可改变元素的CSS样式,如document.getElementById("id").style.color= "red"

    style属于样式声明对象(CSSStyleDeclaration),属性和方法详见 JavaScript 参考手册 -- CSSStyleDeclaration 对象

  1. 操作元素
  • 创建元素节点
    HTML 元素通常是由元素节点和文本节点组成。
    语法:document.createElement(nodename)
    nodename 节点名称,如div、p等。

  • 创建文本节点
    语法:document.createTextNode(text)

  • 创建注释节点
    因为注释是不可见的,所有页面上无变化。
    语法:document.createComment(text)

  • 添加子节点。
    可为元素添加子节点,子节点可为元素节点、文本节点、注释节点。
    语法:element.appendChild(node)
    若 document 中已存在该元素节点,会先将节点从文档中删除,再插入到元素的子节点列表末尾。
    若 document 中不存在该元素节点,则会直接插入到元素的子节点列表末尾。

    • 可使用element.childNodes获取元素的子节点列表,包含元素节点、文本节点、注释节点。
    • 可使用element.children获取元素的子元素节点列表。
    • 可使用element.removeChild(node)删除子节点。
      若想将自己从父元素中删除,可使用element.parentNode.removeChild(element)
  • 插入子节点
    将子节点插入到另一个子节点前面。
    语法:element.insertBefore(newnode, existingnode)

    • newnode 要插入的元素节点。
    • existingnode 已存在的子节点

    appendChild()类似,若元素节点已存在于 document 中,会先删除原节点再插入。

  • 替换子节点
    语法:element.replaceChild(newnode,oldnode)

    • newnode 元素节点
    • oldnode 被替换的元素节点
  • 创建属性节点
    语法:document.createAttribute(attributename)
    attributename 属性名,如class、style、onclick等。

    • 创建成功后,可使用属性name获取属性节点的名称,使用属性value来设置或获取属性节点的值。
    • 可使用element.attributes获取元素的所有属性节点。

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

  • 设置属性节点
    为元素设置一个属性节点。
    语法:element.setAttributeNode(attributenode)
    使用element.setAttribute(attributename,attributevalue)直接为元素设置属性并指定值。

  • 获取属性节点
    语法:element.getAttributeNode(attributename)
    使用element.getAttribute(attributename)直接获取元素的属性值。

  • 删除属性节点
    语法:element.removeAttributeNode(attributenode)
    使用element.removeAttribute(attributename)直接为元素删除指定的属性。

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的有效时间为当前窗口关闭之时,并且是存储在内存中。

  • 新增
    document.cookie = "username=zhangsan; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/"
    表示创建一个cookie,内容为username=zhangsan,过期时间为2043年,路径为当前页面。
  • 删除
    只需将过期时间设为以前的时间。如document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"
  1. storage
    storage分为window.sessionStorage(会话存储)和window.localStorage(本地存储),它们都可以对网页的数据进行增删查改,保存的数据是键值对,它们都是只读的。
    localStorage用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去除。
    sessionStorage用于临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。
  • localStorage
    localStorage.setItem("key", "value") 新增(修改)数据,key和value都是字符串,其他类型需要先进行转换。
    var lastname = localStorage.getItem("key") 查询数据。
    localStorage.removeItem("key") 删除数据。
    localStorage.clear() 删除所有数据。
    localStorage.length 返回共有多少条数据。
    localStorage.key(index) 返回对应索引的key。

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

  • sessionStorage
    与localStorage使用方式完全相同。
  1. 其他
  • 属性
    window.opener 返回创建此窗口的窗口。谁open我。
    window.parent 返回父窗口。若自己是一个iframe或frame,谁持有我。
    window.top 返回最顶层窗口。相当于最顶层的父窗口。
    window.self 返回自身。即window.self == self == self.window == self.self
  • 方法
    window.blur() 窗口失去焦点。
    window.focus() 窗口获取焦点。
    window.open() 打开或查找窗口。
    window.close() 关闭窗口。
    window.matchMedia() 响应式设计,与CSS中@media作用相同。
    window.getComputedStyle() 获取样式。
    • document.getElementById("").style的异同
      style获取的是内联样式,而getComputedStyle()是内联、嵌入和外部样式混合后的最终样式。
      style可读写,而getComputedStyle()只读。通常是先使用getComputedStyle()获取样式,再使用style修改样式。
      它们都返回 样式声明对象(CSSStyleDeclaration),属性和方法详见 JavaScript 参考手册 -- CSSStyleDeclaration 对象
      注:因为 CSS 属性中float在 JS 中是关键字,所以要用cssFloat替换,如document.getElementById("").style.cssFloat = "left"

你可能感兴趣的:(JavaScript 学习归纳)