本文目录
  1. p46-p50 对象的简介
    1. js的数据类型
    2. 对象的简介
    3. 对象的创建
    4. 对象的属性的基本操作
    5. 属性名和属性值
      1. 属性名
      2. 属性值
      3. in运算符
    6. 基本数据类型和引用数据类型
    7. 对象字面量
  2. p51-p65 函数
    1. 创建和调用函数
    2. 函数的参数
    3. 函数的返回值
    4. 函数的实参
    5. 函数内部嵌套函数
    6. 立即执行函数
    7. 方法(了解)
    8. 枚举对象属性
    9. 全局作用域
    10. 声明提前
    11. 函数作用域
    12. debug
    13. this
    14. 使用工厂函数创建对象
    15. 构造函数
  3. p66-p67原型
  4. p68 toString
  5. p69 垃圾回收(了解)
  6. p70-78 数组
    1. 数组的创建、取值、赋值
    2. 数组的长度
    3. 数组的方法
      1. push
      2. pop
      3. unshift
      4. shift
      5. slice
      6. splice
      7. concat
      8. join
      9. reverse
      10. sort
    4. 数组的遍历
  7. p79 call和apply
  8. p80 arguments
  9. p81 Date对象
  10. p82 Math
  11. p83 包装类
  12. p84 String类
  13. p85-p90 正则
  14. p91-140
    1. dom
      1. dom查询
    2. bom
      1. navigator
      2. history
      3. location
    3. 事件
    4. json

分类: web前端 | 标签: js

js基础-笔记

发表于: 2022-06-17 17:20:28 | 字数统计: 13.4k | 阅读时长预计: 67分钟

b站js基础视频教程: 尚硅谷JavaScript基础

课程相关资料: 链接:https://pan.baidu.com/s/15e8Ebq1P3D1ZsfSOsj4rSw 提取码:abtf

p46-p50 对象的简介

js的数据类型

String 字符串
Number 数值
Boolean 布尔值
Null 空值
Undefined 未定义

以上这五种类型属于基本数据类型,以后我们看到的值只要不是上边的5种,全都是对象 Object 对象

对象的简介

基本数据类型都是单一的值eg:”hello” 123 true。值和值之间没有任何的联系。对象属于一种复合的数据类型,在对象中可以保存多个不同数据类型的属性。

对象的分类:
*     1.内建对象
*          由ES标准中定义的对象,在任何的ES的实现中都可以使用
*          比如:Math String Number Boolean Function Object....
* 
*     2.宿主对象
*          由JS的运行环境提供的对象,目前来讲主要指由浏览器提供的对象
*          比如 BOM DOM
* 
*     3.自定义对象
*          由开发人员自己创建的对象

对象的创建

使用new关键字调用的函数,是构造函数constructor

构造函数是专门用来创建对象的函数

使用typeof检查一个对象时,会返回object

var obj = new Object()
console.log(typeof obj) //object

对象的属性的基本操作

在对象中保存的值称为属性

  • 添加或修改属性:
语法:对象.属性名 = 属性值
  • 读取属性
语法:对象.属性名

注意:如果读取对象中没有的属性,不会报错而是会返回undefined

  • 删除属性
语法:delete 对象.属性名

【对象案例】

//创建对象
var obj = new Object()
//添加属性
obj.name = 'tom'
obj.age = 18
//obj.name = 'jerry' //修改属性
//删除属性
//delete obj.name
//console.log(typeof obj) //object
console.log(obj.name)

属性名和属性值

属性名

  • 对象的属性名不强制要求遵守标识符的规范(什么乱七八糟的名字都可以使用).尽量按照标识符的规范去做

  • 特殊的属性名要用[]。在[]中可以直接传递一个变量,这样变量值是多少就会读取那个属性

语法:对象["属性名"] = 属性值

【demo】

var obj = new Object()
//属性名可以随意
obj.val = 123
console.log(obj.val) 
//特殊的属性名要用[]
//obj.123 = 123 // Uncaught SyntaxError: Unexpected number
obj['123'] = 123
console.log(obj['123'])
var nihao = 'nihao'
obj[nihao] = '你好'
console.log(obj[nihao])

属性值

JS对象的属性值,可以是任意的数据类型,甚至也可以是一个对象和函数

//属性值
var obj = new Object()
obj.test = null
obj.test = undefined
obj.test = true
obj.test = function(){}
obj.test = new Object()

in运算符

通过该运算符可以检查一个对象中是否含有指定的属性,如果有则返回true,没有则返回false

语法:"属性名" in 对象
var obj = new Object()
obj.name = 'tom'
console.log("name" in obj) //true
console.log("age" in obj) //false

基本数据类型和引用数据类型

基本数据类型:String Number Boolean Null Undefined

引用数据类型:Object

* JS中的变量都是保存到栈内存中的,
*         基本数据类型的值直接在栈内存中存储,
*         值与值之间是独立存在,修改一个变量不会影响其他的变量
* 
*         对象是保存到堆内存中的,每创建一个新的对象,就会在堆内存中开辟出一个新的空间,
*         而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,
*         当一个通过一个变量修改属性时,另一个也会受到影响

当比较两个基本数据类型的值时,就是比较值。
             而比较两个引用数据类型时,它是比较的对象的内存地址,【引用类型demo3】
             如果两个对象是一摸一样的,但是地址不同,它也会返回false

【基本数据类型demo】

var a = 123;
var b = a;
a++;

image-20220614110432444

【引用类型demo1】

var obj = new Object()
obj.name = 'swk'
var obj2 = obj
obj2.name = 'zbj'
console.log(obj) //zbj
console.log(obj2) //zbj

image-20220614110552104

【引用类型demo2】 通过null切断引用

var obj = new Object()
obj.name = 'swk'
var obj2 = obj
obj2.name = 'zbj'
obj2 = null
console.log(obj) //zbj
console.log(obj2) //null

image-20220614110748416

【引用类型demo3】

var obj3 = new Object();
var obj4 = new Object();
obj3.name = "shs";
obj4.name = "shs";
console.log(obj3 == obj4) //false

image-20220614110839196

对象字面量

就是 { } 来创建对象,有点像json

使用对象字面量,可以在创建对象时,直接指定对象中的属性
             * 语法:{属性名:属性值,属性名:属性值....}
             *     对象字面量的属性名可以加引号也可以不加,建议不加,
             *     如果要使用一些特殊的名字,则必须加引号
             * 
             * 属性名和属性值是一组一组的名值对结构,
             *     名和值之间使用:连接,多个名值对之间使用,隔开
             *     如果一个属性之后没有其他的属性了,就不要写,

【对象字面量案例】

//使用对象字面量创建对象,属性为空
var obj = {}
obj.name = 'jerry'//赋值和前面的一样
console.log(obj) //{name: 'jerry'}
console.log(typeof obj)//object
//使用对象字面量创建对象并初始化属性值
var obj2 = {
    name: 'tom',
    age: 18,
    gender: '男',
    dog: {name: '旺财',age: 3}
}
console.log(obj2)

p51-p65 函数

创建和调用函数

  • 函数创建的三种方式

第一种:使用构造函数创建(不推荐)

var func = new Function('语句...')

第二种:使用 函数声明 来创建一个函数

语法:
         function 函数名([形参1,形参2...形参N]){
             语句...
         }

第三种:函数表达式创建函数

var 函数名  = function([形参1,形参2...形参N]){
                   语句....
             }
  • 函数的调用
封装到函数中的代码不会立即执行
函数中的代码会在函数调用的时候执行
调用函数 语法:函数对象()
当调用函数时,函数中封装的代码会按照顺序执行

【函数的创建和调用案例】

//1.通过构造函数创建函数对象(不常用)
var func = new Function('console.log("通过构造函数创建函数对象")')
func() //调用函数
console.log(typeof func) //function
//2.通过函数声明来创建函数
function func2(){
    console.log("通过函数声明创建函数对象")
}
func2() //调用函数
//3.通过函数表达式创建函数对象
var func3 = function(){
    console.log("通过函数表达式创建函数对象")
}
func3() //调用函数

函数的参数

函数的参数可以是任意类型,声明的时候不需要写类型。

函数调用时,解析器不会去检查参数的类型和数量,多余实参不会被赋值,

如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined。

【函数的参数案例】

function sum(a,b){
    console.log(a+b)
}
//参数类型任意
sum(1,2) //3
sum(1,"2") //12
sum(true,false) //1  true为1 false为0
sum(true,1) //2
//参数个数任意
sum(1) //NaN
sum(1,2,3) //3  自动忽略第三个参数

函数的返回值

可以使用 return 来设置函数的返回值

*     语法:
*         return 值
* 
*     return后的值将会会作为函数的执行结果返回,
*         可以定义一个变量,来接收该结果
* 
*  在函数中return后的语句都不会执行
* 
*     如果return语句后不跟任何值就相当于返回一个undefined,
*     如果函数中不写return,则也会返回undefined
* 
*     return后可以跟任意类型的值

【返回值案例】

function sum(a,b){
    //可以返回任意类型
    //return //不写变量或者不写return返回的是undefined
    //return a + b
    return {
        name: 'tom',
        age : 18
    }
    //console.log('我不会执行')
}
var rs = sum(1,2) //定义变量接收返回值
console.log(rs)

函数的实参

实参可以是任意的数据类型,也可以是一个对象

当我们的参数过多时,可以将参数封装到一个对象中,然后通过对象传递

function sayHello(o){
    console.log("我是"+o.name+","+o.age+"岁了,"+""+o.gender+"人"+",我在"+o.address);
    return o
}
var obj = {
    name:"孙悟空",
    age:18,
    address:"花果山",
    gender:"男"
}
sayHello(obj)
//注意下面的区别
function fun(a){
    console.log(a)
}
fun(1)
fun(sayHello)
fun(sayHello(obj))
* sayHello(obj)
*     调用函数
*     相当于使用的函数的返回值
* 
* sayHello
*     函数对象
*     相当于直接使用函数对象

函数内部嵌套函数

函数内部可以声明函数,可以无限嵌套

function fun1(){
    function fun2(){
        console.log('我是 fun2')
    }
    return fun2
}
var a = fun1()
//console.log(a)
//a()
fun1()() //注意一下这种写法

立即执行函数

页面加载后会立即执行.用一个括号把匿名函数包起来,然后再像函数调用那样加个括号运行。

里面定义的变量是局部变量,不会影响全局的作用域

//立即执行函数-不带参数
(function(){
    console.log('立即运行')
})();

//立即执行函数-带参数
(function(a,b){
    console.log(a+b)
})(123,456)

方法(了解)

函数也可以称为对象的属性,如果一个函数作为一个对象的属性保存,那么我们称这个函数时这个对象的方法.调用这个函数就说调用对象的方法(method) 但是它只是名称上的区别没有其他的区别

var obj = {
    name: '孙悟空',
    age: 18,
    sayName: function(){
        console.log(obj.name)
    }
}
function fun(){
    console.log('func')
}
fun() //调函数
obj.sayName() //调方法

枚举对象属性

把对象中所有的属性和值取出来

枚举对象中的属性
使用for ... in 语句

* 语法:
*     for(var 变量 in 对象){
*     
*  }

for...in语句 对象中有几个属性,循环体就会执行几次
每次执行时,会将对象中的一个属性的名字赋值给变量

【枚举对象属性案例】

var obj = {
    name: 'swk',
    age: 18,
    sayName: function(){
        console.log(obj.name)
    }
}
for(var key in obj){
    console.log(key,":",obj[key])
}

全局作用域

作用域指一个变量的作用的范围

全局作用域
*              【直接编写在script标签中的JS代码,都在全局作用域】
*              全局作用域在页面打开时创建,在页面关闭时销毁
*              在全局作用域中有一个全局对象【window】,
*                 它代表的是一个浏览器的窗口,它由浏览器创建我们可以直接使用
*              在全局作用域中:
*                 【创建的变量都会作为window对象的属性保存】
*                 【创建的函数都会作为window对象的方法保存】
*              全局作用域中的变量都是全局变量,
*                 【在页面的任意的部分都可以访问的到】

【案例】

<script>
    var c = 345
</script>
<script>
    var a = 123
    function fun(){
        console.log('func')
    }
    console.log(window.a)
    window.fun()
    window.alert('xxx')
    console.log(c)
</script>

声明提前

* 变量的声明提前
*     使用【var关键字声明的变量】,会在所有的代码执行之前被声明(但是不会赋值),
*         但是如果声明变量时不是用var关键字,则变量不会被声明提前
* 
* 函数的声明提前
*     使用【函数声明形式】创建的函数 function 函数(){}
*         它会在所有的代码执行之前就被创建,所以我们可以在函数声明前来调用函数
*        使用函数表达式创建的函数,不会被声明提前,所以不能在声明前调用    

【声明提前案例如下】

//--------1.var声明的变量提前 相当于把var a 提取到代码最前面
console.log(a) //undefined
var a = 123
//--------2.没用var声明的变量不提前,所以报错------------------
//console.log(b) //报错 Uncaught ReferenceError: b is not defined
//b = 456
//--------3.函数声明提前-----------
fun() //fun
function fun(){
    console.log('fun')
}
//-------4.函数表达式,不会被提前创建
//fun1() //Uncaught TypeError: fun1 is not a function
var fun1 = function(){
    console.log('fun1')
}

函数作用域

* 函数作用域    
*      调用函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
*      每调用一次函数就会创建一个新的函数作用域,他们之间是【互相独立】的
*      在函数作用域中可以访问到全局作用域的变量
*         在全局作用域中无法访问到函数作用域的变量
*      【当在函数作用域操作一个变量时,它会先在自身作用域中寻找,如果有就直接使用
*         如果没有则向上一级作用域中寻找,直到找到全局作用域,
*         如果全局作用域中依然没有找到,则会报错ReferenceError】
*      【在函数中要访问全局变量可以使用window对象】
【在函数作用域也有声明提前的特性】
【定义形参就相当于在函数作用域中声明了变量】
【在函数中,不用var声明的变量都会成为全局变量】

【函数作用域案例】

//1.函数作用域入门
var a = 123
function fun1(){
    var a = 456
    console.log(a) //456
    console.log(window.a) //123 通过window可以找全局的
}
fun1()
//2.一层层往上找,全局还找不到就报错
var b = 'b'
function fun2(){
    var b = 'b2'
    function fun3(){
        //var b = 'b3'
        console.log(b)
    }
    return fun3
}
fun2()()
//3.函数作用域内部方法声明提前
function fun3(){
    //内部方法声明提前
    fun4()
    function fun4(){
        console.log('fun4')
    }
}
fun3()
//4.函数内部变量声明提前
function fun5(){
    console.log(c) //undefined
    var c = 10
    d = 100 //函数内部不用var声明的变量将放入到全局作用域
}
fun5()
console.log(d) //100
//5.定义形参就相当于定义了变量(注意这个很容易出错)
var e= 'eee'
function fun6(e){
    console.log(e) //undefined
}
fun6()

debug

谷歌浏览器为例,其它类似 首先用f12打开调试模式

image-20220614150539324

给某个变量加上监听,右键变量 add selected text to watches

image-20220614150645658

this

* 解析器在调用函数每次都会向函数内部传递进一个隐含的参数,
*     这个隐含的参数就是this,this指向的是一个对象,
*     这个对象我们称为函数执行的 上下文对象,
*     根据函数的调用方式的不同,this会指向不同的对象
*         【1.以函数的形式调用时,this永远都是window】
*         【2.以方法的形式调用时,this就是调用方法的那个对象】

【this案例】

var name ='全局的name'
function fun(){
    console.log(this)
    console.log(this.name)
}
//fun() //以函数的形式调用 this是window

var obj = {
name: 'tom',
sayName: fun
}
obj.sayName() //以方法的形式调用 this是调用方法的对象

console.log(obj.sayName == fun) //true

使用工厂函数创建对象

创建工厂函数,函数中new Object并给属性赋值.

//创建对象的的工厂方法
function createPeople(name,age,gender){
    var obj = new Object()
    obj.name = name
    obj.age = age
    obj.gender = gender
    return obj
}
var luban = createPeople('鲁班',6,'男')
console.log(typeof luban,luban)
var aql = createPeople('安其拉',8,'女')
console.log(typeof aql,aql)
//存在缺陷,类型都是object的,后面的构造函数可以解决这个问题

构造函数

*     构造函数就是一个普通的函数,创建方式和普通函数没有区别,
*     不同的是构造函数习惯上【首字母大写】
* 
* 构造函数和普通函数的区别就是调用方式的不同
*     普通函数是直接调用,而构造函数需要使用【new关键字来调用】
* 
* 构造函数的执行流程:
*     1.立刻创建一个新的对象
*     【2.将新建的对象设置为函数中this,在构造函数中可以使用this来引用新建的对象】
*     3.逐行执行函数中的代码
*     4.将新建的对象作为返回值返回
* 
* 使用同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类。
*     我们将通过一个构造函数创建的对象,称为是该类的实例
* 
* this的情况:
*     1.当以函数的形式调用时,this是window
*     2.当以方法的形式调用时,谁调用方法this就是谁
*     3.当以构造函数的形式调用时,this就是新创建的那个对象

 * 使用【instanceof】可以检查一个对象是否是一个类的实例
                  语法:对象 instanceof 构造函数
                如果是,则返回true,否则返回false

【构造函数案例】

function Person(name,age){
    console.log('构造方法执行了')
    this.name = name
    this.age = age
    this.sayName = function(){
        console.log(this.name)
    }
}
//console.log(Person())//undefined
console.log(new Person('嫦娥',18))
console.log(new Person('猪八戒',18))

function Dog(name,age){
    this.name = name
    this.age = age
    this.sayName = function(){
        console.log(this.name)
    }
}
console.log(new Dog('旺财',18))
//可以看到打印的类型不同:  一个是Person一个Dog
//使用【instanceof】可以检查一个对象是否是一个类的实例
console.log(new Dog('旺财',18) instanceof Dog) //true
console.log(new Person('猪八戒',18) instanceof Dog)// false
console.log(new Person('猪八戒',18) instanceof Object)// true  Object是所有类的父类

【构造函数优化】

/*
*   将函数定义在全局作用域,污染了全局作用域的命名空间
*     而且定义在全局作用域中也很不安全
*/
function fun(){
    console.log(this.name)
}
function Person(name,age){
    console.log('构造方法执行了')
    this.name = name
    this.age = age
    //改成引用的方式,提高性能,但是fun声明在全局中,也不是特别合适,后面可以声明到原型中
    this.sayName = fun 
}
var per = new Person('tom',18)
per.sayName()

p66-p67原型

* 原型 prototype
* 
*     【创建的每一个函数,解析器都会向函数中添加一个属性prototype】
*         这个属性对应着一个对象,这个对象就是所谓的原型对象
*     如果函数作为普通函数调用prototype没有任何作用
*     当函数以构造函数的形式调用时,它所创建的对象中都会有一个隐含的属性,
*         指向该构造函数的原型对象,我们可以【通过__proto__来访问该属性】
* 
*     【原型对象就相当于一个公共的区域,所有同一个类的实例都可以访问到这个原型对象,
*         我们可以将对象中共有的内容,统一设置到原型对象中。】
* 
* 【当我们访问对象的一个属性或方法时,它会先在对象自身中寻找,如果有则直接使用,
*     如果没有则会去原型对象中寻找,如果找到则直接使用】
* 
* 以后我们创建构造函数时,可以将这些对象共有的属性和方法,统一添加到构造函数的原型对象中,
*     这样不用分别为每一个对象添加,也不会影响到全局作用域,就可以使每个对象都具有这些属性和方法了

【原型案例1】

function Person(){
                
}
//console.log(Person.prototype)
var per = new Person()
var per2 = new Person()
console.log(Person.prototype == per.__proto__) //true
console.log(Person.prototype == per2.__proto__) //true
console.log(per.__proto__ == per2.__proto__) //true

//向原型中加入属性
per.__proto__.a = 'aa'
Person.prototype.b = 'bb'
console.log(Person.prototype.a,Person.prototype.b) //aa bb
console.log(per.a,per.b) //aa bb
//向原型中加入方法
Person.prototype.sayHello = function(){
    console.log('hello')
}
per.sayHello()
//给per添加属性a
per.a = 'per中的a'
console.log(per.a) //先到自己中找,没有再到原型中找

【原型案例2:通过原型来优化之前的构造函数问题】

//之前将方法放在全局中不优化,现在通过原型来优化构造函数中的方法
Person.prototype.sayName = function fun(){
    console.log('大家好,我是',this.name)
}
function Person(name,age){
    //console.log('构造方法执行了')
    this.name = name
    this.age = age
}
var per1 = new Person('tom',18)
var per2 = new Person('jerry',18)
per1.sayName()
per2.sayName()

【原型案例3:原型的其它方法和特性】

var name = '全局的name'
function MyClass(){

}
MyClass.prototype.name = name
var m1 = new MyClass()
//m1.name = 'tom'
//1.使用in检查对象中是否含有某个属性时,如果对象中没有但是原型中有,也会返回true
console.log('name' in m1) 

//2.【可以使用对象的hasOwnProperty()来检查对象自身中是否含有该属性】
//使用该方法只有当对象自身中含有属性时,才会返回true
console.log(m1.hasOwnProperty('name'))

/*
* 3.原型对象也是对象,所以它也有原型,
*     当我们使用一个对象的属性或方法时,会现在自身中寻找,
*         自身中如果有,则直接使用,
*         如果没有则去原型对象中寻找,如果原型对象中有,则使用,
*         如果没有则去原型的原型中寻找,直到找到Object对象的原型,
*         Object对象的原型没有原型,如果在Object原型中依然没有找到,则返回undefined
*/
console.log(m1.hasOwnProperty('hasOwnProperty')) //false
console.log(m1.__proto__.hasOwnProperty('hasOwnProperty')) //false
console.log(m1.__proto__.__proto__.hasOwnProperty('hasOwnProperty'))//true
console.log(m1.__proto__.__proto__)

p68 toString

直接在页面中打印一个对象时,事实上是输出的对象的toString()方法的返回值

如果我们希望在输出对象时不输出[object Object],可以为对象添加一个toString()方法

function Person(name,age){
    this.name = name
    this.age = age
}
//修改Person原型的toString
Person.prototype.toString = function(){
    return "Person[name="+this.name+",age="+this.age+"]";
};
var per = new Person('tom',18)
console.log(per.toString())

p69 垃圾回收(了解)

*    当一个对象没有任何的变量或属性对它进行引用,此时我们将永远无法操作该对象,
*         此时这种对象就是一个垃圾,这种对象过多会占用大量的内存空间,导致程序运行变慢,
*         所以这种垃圾必须进行清理。
*      在JS中拥有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,
*         我们不需要也不能进行垃圾回收的操作
*      我们需要做的只是要【将不再使用的对象设置null即可】

p70-78 数组

* 数组(Array)
*      数组也是一个对象
*      它和我们普通对象功能类似,也是用来存储一些值的
*      不同的是普通对象是使用字符串作为属性名的,
*         而【数组使用数字来作为索引操作元素】
*      索引:
*         从0开始的整数就是索引
*      【数组的存储性能比普通对象要好,在开发中我们经常使用数组来存储一些数据】

数组的创建、取值、赋值

创建方式:通过new Array或者 字面量[]创建

var arr1 = new Array() //创建长度为0的数组
console.log(arr1)
var arr2 = new Array(1,2,3) //创建数组并放入三个元素
console.log(arr2)
var arr3 = new Array(10) //创建长度为10的数组,注意当长度为1时不是加入元素,而是初始化长度
console.log(arr3)
var arr4 = [1,2,3] //通过字面量创建数组
console.log(arr4)

修改或添加的语法:数组[索引] = 值

取值:数组[索引] 如果读取不存在的索引,他不会报错而是返回undefined

注意: 数组中的元素可以是任意的数据类型

数组的长度

* 可以使用length属性来获取数组的长度(元素的个数)
* 语法:数组.length
* 
* 对于连续的数组,使用length可以获取到数组的长度(元素的个数)
* 对于非连续的数组,使用length会获取到数组的最大的索引+1
*         尽量不要创建非连续的数组

* 修改length
*     如果修改的length大于原长度,则多出部分会空出来
*   如果修改的length小于原长度,则多出的元素会被删除

* 向数组的最后一个位置添加元素
* 语法:数组[数组.length] = 值;

【数组demo】

//创建数组
var arr = new Array()
console.log(typeof arr) //object
console.log(Array.isArray(arr)) //true
//往数组中加元素
arr[0] = 1
arr[1] = 2
arr[2] = 1
console.log(arr)
//获取数组的值
console.log(arr[0])  //1
console.log(arr[3]) //undefined
//获取数组的长度
console.log(arr.length)
//修改lengh
//arr.length = 10
//向数组最后位置添加元素
arr[arr.length] = 3
arr[arr.length] = 4
arr[arr.length] = 5
console.log(arr,arr.length)

数组的方法

push

*      该方法可以向数组的末尾添加一个或多个元素,并[返回数组的新的长度]
*      可以将要添加的元素作为方法的参数传递,这样这些元素将会自动添加到数组的末尾
*      该方法会将数组新的长度作为返回值返回

【案例】

var arr = [1,2,3]
var rs = arr.push(4,5,6)
console.log(arr) //[1,2,3,4,5,6]
console.log(rs) //6

pop

该方法可以删除数组的最后一个元素,并将被删除的元素作为返回值返回

var arr = [1,2,3]
var rs = arr.pop()
console.log(arr) //[1,2]
console.log(rs) //3

unshift

*     向数组开头添加一个或多个元素,并返回新的数组长度
*     向前边插入元素以后,其他的元素索引会依次调整

【案例】

var arr = [1,2,3]
var rs = arr.unshift('a')
console.log(arr)// ['a', 1, 2, 3]
console.log(rs)//4

shift

删除数组的第一个元素,并将被删除的元素作为返回值返回

var arr = [1,2,3]
var rs = arr.shift()
console.log(arr)// [ 2, 3]
console.log(rs)//1

slice

*      可以用来从数组提取指定元素
*      【该方法不会改变元素数组,而是将截取到的元素封装到一个新数组中返回】
*      参数:
*         1.截取开始的位置的索引,包含开始索引
*         2.截取结束的位置的索引,不包含结束索引
*              第二个参数可以省略不写,此时会截取从开始索引往后的所有元素
*          索引可以传递一个负值,如果传递一个负值,则从后往前计算
*             1 倒数第一个
*             2 倒数第二个

【案例】

var arr = [1,2,3,4,5,6]
//var rs = arr.slice(1,3)//[2,3]
//var rs = arr.slice(1)
var rs = arr.slice(1,-2) //1指的是索引为1的  -2代表倒数第二个 所以结果是2,3,4
console.log(arr) 
console.log(rs)

splice

*      可以用于删除数组中的指定元素
*      【使用splice()会影响到原数组,会将指定元素从原数组中删除】
*         并将被删除的元素作为返回值返回
*      参数:
*         第一个,表示开始位置的索引
*         第二个,表示删除的数量
*         第三个及以后。。
*             可以传递一些新的元素,这些元素将会自动插入到开始位置索引前边

【案例】

var arr = [1,2,3,4,5,6]
//var rs = arr.splice(0,3)
var rs = arr.splice(0,3,7,8,9)
console.log(arr)
console.log(rs)

concat

可以连接两个或多个数组,并将新的数组返回。该方法不会对原数组产生影响

参数:除了写数组也可以是元素

var arr = ["孙悟空","猪八戒","沙和尚"];
var arr2 = ["白骨精","玉兔精","蜘蛛精"];
var arr3 = ["二郎神","太上老君","玉皇大帝"];
var rs = arr.concat(arr2,arr3,'唐僧','哪吒')
console.log(arr)
console.log(rs)

join

*      该方法可以将数组转换为一个字符串
*      【该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回】
*      在join()中可以指定一个字符串作为参数,这个字符串将会成为数组中元素的连接符
*         如果不指定连接符,则默认使用,作为连接符

【案例】

var arr = ["孙悟空","猪八戒","沙和尚"];
//var rs = arr.join()
var rs = arr.join("-")
console.log(arr)
console.log(rs)

reverse

*      该方法用来反转数组(前边的去后边,后边的去前边),返回翻转之后的新数组
*      该方法会直接修改原数组

【案例】

var arr = ["孙悟空","猪八戒","沙和尚"];
var rs = arr.reverse()
console.log(arr == rs) //true
console.log(arr) //['沙和尚', '猪八戒', '孙悟空']

sort

*     可以用来对数组中的元素进行排序
*     也会影响原数组,默认会按照Unicode编码进行排序

* 即使对于纯数字的数组,使用sort()排序时,也会按照Unicode编码来排序,
*     所以对数字进排序时,可能会得到错误的结果。
* 
* 我们可以自己来指定排序的规则
*     我们可以在sort()添加一个回调函数,来指定排序规则,
*         回调函数中需要定义两个形参,
*         浏览器将会分别使用数组中的元素作为实参去调用回调函数
*         使用哪个元素调用不确定,但是肯定的是在数组中a一定在b前边
*     浏览器会根据回调函数的返回值来决定元素的顺序,
*         如果返回一个大于0的值,则元素会交换位置
*         如果返回一个小于0的值,则元素位置不变
*         如果返回一个0,则认为两个元素相等,也不交换位置
* 
*     如果需要升序排列,则返回 a-b
*         如果需要降序排列,则返回b-a

【案例】

var arr = [5,4,2,1,1,3,6,8,7];
//var rs = arr.sort() //升序
var rs = arr.sort(function(a,b){
    return b-a
}) //降序
console.log(arr == rs) //true
console.log(arr) 

数组的遍历

所谓的遍历数组,就是将数组中所有的元素都取出来

* 一般我们都是使用for循环去遍历数组,
*     JS中还为我们提供了一个方法,用来遍历数组
* forEach()
*          这个方法只支持IE8以上的浏览器
*             IE8及以下的浏览器均不支持该方法,所以如果需要兼容IE8,则不要使用forEach
*             还是使用for循环来遍历

* forEach()方法需要一个函数作为参数
*      像这种函数,由我们创建但是不由我们调用的,我们称为回调函数
*      数组中有几个元素函数就会执行几次,每次执行时,浏览器会将遍历到的元素
*         以实参的形式传递进来,我们可以来定义形参,来读取这些内容
*      浏览器会在回调函数中传递三个参数:
*         第一个参数,就是当前正在遍历的元素
*         第二个参数,就是当前正在遍历的元素的索引
*         第三个参数,就是正在遍历的数组

【例如】

var arr = [1,2,3,4,5]
for(var i=0;i<arr.length;i++){
    console.log(arr[i])
}
console.log('----------')
arr.forEach(function(v,i,arr){
    console.log(i,v,arr)
})

p79 call和apply

* call()和apply()
*      这两个方法都是函数对象的方法,需要通过函数对象来调用
*      当对函数调用call()和apply()都会调用函数执行
*      在调用call()和apply()可以将一个对象指定为第一个参数
*         此时这个对象将会成为函数执行时的this
*      call()方法可以将实参在对象之后依次传递
*      apply()方法需要将实参封装到一个数组中统一传递
* 
*      this的情况:
*         1.以函数形式调用时,this永远都是window
*         2.以方法的形式调用时,this是调用方法的对象
*         3.以构造函数的形式调用时,this是新创建的那个对象
*         4.使用call和apply调用时,this是指定的那个对象

【案例】

function fun(a,b) {
    console.log("a = "+a);
    console.log("b = "+b);
    console.log(this);
}

var obj = {
    name: "我是obj",
    sayName:function(){
        console.log(this.name);
    }
};
//fun() //以函数调用 this指window
//obj.sayName() //以方法调用this指调用方法的对象

//fun.call() //this指window
//fun.call(obj) //this指obj

//fun.apply()//this指window
//fun.apply(obj)//this指obj

//call和apply的不同点:  apply的参数需要放到数组中
//fun.call(obj,1,2) //1,2为参数
//fun.apply(obj,[3,4]) //3,4为参数

p80 arguments

* 在调用函数时,浏览器每次都会传递进两个隐含的参数:
*     1.函数的上下文对象 this
*     2.封装实参的对象 arguments
*          arguments是一个类数组对象,它也可以通过索引来操作数据,也可以获取长度
*          在调用函数时,我们所传递的实参都会在arguments中保存
*          arguments.length可以用来获取实参的长度
*          我们即使不定义形参,也可以通过arguments来使用实参,
*             只不过比较麻烦
*             arguments[0] 表示第一个实参
*             arguments[1] 表示第二个实参 。。。
*         它里边有一个属性叫做callee,
*             这个属性对应一个函数对象,就是当前正在指向的函数的对象

【案例】

function fun(){
    console.log(arguments.callee == fun) //true
    console.log(Array.isArray(arguments))//false
    console.log(arguments.length)//3
    console.log(arguments[1])//2
}
fun(1,2,3)

p81 Date对象

在JS中使用Date对象来表示一个时间

创建Date对象的方式

var d = new Date();//默认为当前时间
var d2 = new Date("2/18/2011 11:10:30"); //日期的格式  月份/日/年 时:分:秒
var d3 = new Date(1655436727888) //通过时间戳创建

Date对象的一些方法

* getFullYear()
*      获取当前日期对象的年份

* getMonth()
*  获取当前时间对象的月份
*      会返回一个0-11的值
*         0 表示1月
*         1 表示2月
*         11 表示12月

* getDate()
*      获取当前日期对象是几日

* getDay()
*      获取当前日期对象时周几
*      会返回一个0-6的值
*         0 表示周日
*         1表示周一
*         。。。

* getTime()
*      获取当前日期对象的时间戳
*      时间戳,指的是从格林威治标准时间的1970年1月1日,0时0分0秒
*         到当前日期所花费的毫秒数(1秒 = 1000毫秒)
*      计算机底层在保存时间时使用都是时间戳

【案例】

var d = new Date()
var year = d.getFullYear()
var month = d.getMonth()+1
var date = d.getDate()
var day = d.getDay()==0?'日':d.getDay()
var hours = d.getHours()
var minutes = d.getMinutes()
var seconds = d.getSeconds()
console.log(year+"-"+month+"-"+date+"-星期"+day+" "+hours+":"+minutes+":"+seconds)
//获取时间戳
var t = d.getTime()
console.log(t)
//获取当前时间的时间戳
console.log(Date.now())

p82 Math

 Math和其他的对象不同,它不是一个构造函数,
*     它属于一个工具类不用创建对象,它里边封装了数学运算相关的属性和方法
*      比如
*         Math.PI 表示的圆周率
* Math.abs()可以用来计算一个数的绝对值
* Math.ceil()
*      可以对一个数进行向上取整,小数位只有有值就自动进1
* Math.floor()
*      可以对一个数进行向下取整,小数部分会被舍掉
* Math.round()
*      可以对一个数进行四舍五入取整
* Math.random()
*      可以用来生成一个0-1之间的随机数
*    生成一个0-10的随机数
*      生成一个0-x之间的随机数
*         Math.round(Math.random()*x)
*      生成一个1-10  Math.round(Math.random()*9)+1
*      生成一个x-y之间的随机数
*         Math.round(Math.random()*(y-x)+x)
* Math.max() 可以获取多个数中的最大值
* Math.min() 可以获取多个数中的最小值
* Math.pow(x,y)
*     返回x的y次幂
* Math.sqrt()
*  用于对一个数进行开方运算

【案例】

console.log(Math.PI) //圆周率
console.log(Math.abs(-1))//绝对值
console.log(Math.ceil(1.2))//向上取整
console.log(Math.floor(1.2))//向下取整
console.log(Math.round(1.5))//四舍五入
console.log(Math.round(Math.random()*9+1)) //获取1-10的随机数
console.log(Math.max(10,45,30,100))//最大值
console.log(Math.min(10,45,30,100))//最小值

p83 包装类

* 基本数据类型
*     String Number Boolean Null Undefined
* 引用数据类型
*     Object
* 
* 在JS中为我们提供了三个包装类,通过这三个包装类可以将基本数据类型的数据转换为对象
*     String()
*         可以将基本数据类型字符串转换为String对象
*     Number()
*         可以将基本数据类型的数字转换为Number对象
*  Boolean()
*         可以将基本数据类型的布尔值转换为Boolean对象
*     但是注意:我们在【实际应用中不会使用基本数据类型的对象】,
*         如果使用基本数据类型的对象,在做一些比较时可能会带来一些不可预期的结果

方法和属性只能添加给对象,不能添加给基本数据类型
*     当我们对一些基本数据类型的值去调用属性和方法时,
*         浏览器会临时使用包装类将其转换为对象,然后在调用对象的属性和方法
*         调用完以后,在将其转换为基本数据类型

【案例】

var num = new Number(1)
console.log(num == 1) //true

var bool = new Boolean(false)
console.log(bool) //boolean对象
if(bool){//非空就是真,会运行
    console.log('我运行了')
}

var str = new String('abc')
str.hello = 'def'
console.log(str.hello)//def

var s = '123'
s.hello = '456'
console.log(s.hello) //undefined

p84 String类

* 在底层字符串是以字符数组的形式保存的
* length属性
*     可以用来获取字符串的长度
* charAt()
*     可以返回字符串中指定位置的字符
*     根据索引获取指定的字符    
* concat()
*     可以用来连接两个或多个字符串
*     作用和+一样
* indexof()
*     该方法可以检索一个字符串中是否含有指定内容
*     如果字符串中含有该内容,则会返回其第一次出现的索引
*         如果没有找到指定的内容,则返回-1
*     可以指定一个第二个参数,指定开始查找的位置
* 
* lastIndexOf();
*     该方法的用法和indexOf()一样,
*         不同的是indexOf是从前往后找,
*         而lastIndexOf是从后往前找
*     也可以指定开始查找的位置
* slice()
*     可以从字符串中截取指定的内容
*     【不会影响原字符串,而是将截取到内容返回】
*     参数:
*         第一个,开始位置的索引(包括开始位置)
*         第二个,结束位置的索引(不包括结束位置)
*             【如果省略第二个参数,则会截取到后边所有的】
*         也可以传递一个负数作为参数,负数的话将会从后边计算
* substring()
*     可以用来截取一个字符串,和数组的slice()类似
*     参数:
*         第一个:开始截取位置的索引(包括开始位置)
*         第二个:结束位置的索引(不包括结束位置)
*         不同的是这个方法不能接受负值作为参数,
*             如果传递了一个负值,则默认使用0
*         而且他还自动调整参数的位置,如果第二个参数小于第一个,则自动交换
* substr()
*     用来截取字符串,和数组的splice类似
*     参数:
*         1.截取开始位置的索引
*         2.截取的长度
* split()
*     可以将一个字符串拆分为一个数组
*     参数:
*         需要一个字符串作为参数,将会根据该字符串去拆分数组
*       【如果传递一个空串作为参数,则会将每个字符都拆分为数组中的一个元素】
* toUpperCase()
*     将一个字符串转换为大写并返回
* toLowerCase()
*     将一个字符串转换为小写并返回

【案例】

var str = 'a,b,c'
//var rs = str.concat('def','ghi')
//var rs = str.slice(0,2)
//var rs = str.substring(2,-1)
var rs = str.substr(0,3)
//var rs = str.split(",")
console.log(rs)

p85-p90 正则

了解一下,要用的时候再来看就行

*     正则表达式用于定义一些字符串的规则,
*         计算机可以根据正则表达式,来检查一个字符串是否符合规则,
*         获取将字符串中符合规则的内容提取出来

* 创建正则表达式的对象
* 语法:
*     var 变量 = new RegExp("正则表达式","匹配模式");
*  使用typeof检查正则对象,会返回object
*     var reg = new RegExp("a"); 这个正则表达式可以来检查一个字符串中是否含有a
*  在构造函数中可以传递一个匹配模式作为第二个参数,
*         可以是 
*             i 忽略大小写 
*             g 全局匹配模式

* 正则表达式的方法:
*     test()
*      使用这个方法可以用来检查一个字符串是否符合正则表达式的规则,
*         如果符合则返回true,否则返回false

* 使用字面量来创建正则表达式
*     语法:var 变量 = /正则表达式/匹配模式
* 使用字面量的方式创建更加简单
*     使用构造函数创建更加灵活
* 使用 | 表示或者的意思

* []里的内容也是或的关系
* [ab] == a|b
* [a-z] 任意小写字母
* [A-Z] 任意大写字母
* [A-z] 任意字母
* [0-9] 任意数字

* 量词
*     通过量词可以设置一个内容出现的次数
*     量词只对它前边的一个内容起作用
*     {n} 正好出现n次
*     {m,n} 出现m-n次
*     {m,} m次以上
*     + 至少一个,相当于{1,}
*     * 0个或多个,相当于{0,}
*     ? 0个或1个,相当于{0,1}

*     ^ 表示开头
*     $ 表示结尾
*   【如果在正则表达式中同时使用^ $则要求字符串必须完全符合正则表达式】

* 检查一个字符串中是否含有 .
* . 表示任意字符
* 在正则表达式中使用\作为转义字符
* \. 来表示.
* \\  表示\
* 
* 注意:使用构造函数时,由于它的参数是一个字符串,而\是字符串中转义字符,
*     如果要使用\则需要使用\\来代替
* \w
*     任意字母、数字、_  [A-z0-9_]
* \W
*     除了字母、数字、_  [^A-z0-9_]
* \d
*     任意的数字 [0-9]
* \D
*     除了数字 [^0-9]
* \s
*     空格
* \S
*     除了空格
* \b
*     单词边界
* \B
*     除了单词边界

* 字符串的split()
*     可以将一个字符串拆分为一个数组
*     方法中可以传递一个正则表达式作为参数,这样方法将会根据正则表达式去拆分字符串
*     这个方法即使不指定全局匹配,也会全都插分
* 字符串的search()
*     可以搜索字符串中是否含有指定内容
*     如果搜索到指定内容,则会返回第一次出现的索引,如果没有搜索到返回-1
*     它可以接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串
*     【search()只会查找第一个,即使设置全局匹配也没用】
* 字符串的match()
*     可以根据正则表达式,从一个字符串中将符合条件的内容提取出来
*     默认情况下我们的match只会找到第一个符合要求的内容,找到以后就停止检索
*         我们可以设置正则表达式为全局匹配模式,这样就会匹配到所有的内容
*         可以为一个正则表达式设置多个匹配模式,且顺序无所谓
*     match()会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果
* 字符串的replace()
*     可以将字符串中指定内容替换为新的内容
*  参数:
*         1.被替换的内容,可以接受一个正则表达式作为参数
*         2.新的内容
*  默认只会替换第一个

【入门案例】

//var reg = new RegExp('a')
//检查是否包含a,忽略大小写
//var reg = new RegExp('a','i')

//使用字面量来创建正则
//var reg = /a/i

//检查是否包含a或b,忽略大小写
//var reg = /a|b/i
// var reg = /[ab]/i
// console.log(reg.test('ac'))
//console.log(typeof reg)

//a{3}b
var reg = /^a{3}ab$/
console.log(reg.test('aaaab'))

p91-140

dom

DOM,全称Document Object Model文档对象模型。文档表示的就是整个的HTML网页文档

image-20220617162901955

image-20220617162930420

image-20220617163000808

dom查询

  • 获取整个文档: document
  • 获取body: document.body
  • 根据id获取节点: document.getElementById()
  • 根据标签名获取:document.getElementsByTagName
  • 根据类名获取: document.getElementsByClassName
  • 使用H5新增选择器查询,返回第一个:document.querySelector()
  • 使用H5新增选择器查询,返回所有结果:document.querySelectorAll()

bom

* BOM
*     浏览器对象模型
*     BOM可以使我们通过JS来操作浏览器
*     在BOM中为我们提供了一组对象,用来完成对浏览器的操作
*     BOM对象
*         Window
*             代表的是整个浏览器的窗口,同时window也是网页中的全局对象
*         Navigator
*             代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
*         Location
*             代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
*         History
*             代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录
*                 由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页
*                 而且该操作只在当次访问时有效
*         Screen
*             代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息
* 
* 
*         这些【BOM对象在浏览器中都是作为window对象的属性保存的】,
*             可以通过window对象来使用,也可以直接使用
* Navigator
*     代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
*     由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了
*     【一般我们只会使用userAgent来判断浏览器的信息】,
*         userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,
*         不同的浏览器会有不同的userAgent

例如:

var ua = navigator.userAgent;
console.log(ua);
if(/firefox/i.test(ua)){
    alert("你是火狐!!!");
}else if(/chrome/i.test(ua)){
    alert("你是Chrome");
}else if(/msie/i.test(ua)){
    alert("你是IE浏览器~~~");
}else if("ActiveXObject" in window){
    alert("你是IE11,枪毙了你~~~");
}

history

/*
* length
*     属性,可以获取到当成访问的链接数量
*/
//alert(history.length);

/*
* back()
*     可以用来回退到上一个页面,作用和浏览器的回退按钮一样
*/
//history.back();

/*
* forward()
*     可以跳转下一个页面,作用和浏览器的前进按钮一样
*/
//history.forward();

/*
* go()  推荐这个
*     可以用来跳转到指定的页面
*     它需要一个整数作为参数
*         1:表示向前跳转一个页面 相当于forward()
*         2:表示向前跳转两个页面
*         1:表示向后跳转一个页面
*         2:表示向后跳转两个页面
*/
history.go(-2);

location

该对象中封装了浏览器的地址栏的信息

//如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)
//alert(location);

/*
* 如果直接将location属性修改为一个完整的路径,或相对路径
*     则我们页面会自动跳转到该路径,并且会生成相应的历史记录
*/
//location = "http://www.baidu.com";
//location = "01.BOM.html";

/*
* assign()
*     用来跳转到其他的页面,作用和直接修改location一样
*/
//location.assign("http://www.baidu.com");

/*
* reload()
*     用于重新加载当前页面,作用和刷新按钮一样
*     如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面
*/
//location.reload(true);

/*
* replace()
*     可以使用一个新的页面替换当前页面,调用完毕也会跳转页面
*         不会生成历史记录,不能使用回退按钮回退
*/
location.replace("01.BOM.html");

事件

事件的冒泡

*     所谓的冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
*     在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡

事件的委派

* 我们希望,只绑定一次事件,即可应用到多个的元素上,即使元素是后添加的
* 我们可以尝试将其绑定给元素的共同的祖先元素
* 
* 事件的委派
*     指【将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素
*         从而通过祖先元素的响应函数来处理事件。】
*  事件委派是利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能

* target
*     event中的target表示的触发事件的对象,比如按钮或链接

事件的传播

* 事件的传播
*     关于事件的传播网景公司和微软公司有不同的理解
*     微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,
*         然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。
*  网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,
*         然后在向内传播给后代元素
*     W3C综合了两个公司的方案,将事件传播分成了三个阶段
*         1.捕获阶段
*             在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
*         2.目标阶段
*             事件捕获到目标元素,捕获结束开始在目标元素上触发事件
*         3.冒泡阶段
*             事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
* 
*         如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
*             一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
* 
*     IE8及以下的浏览器中没有捕获阶段

事件的绑定

* 使用 对象.事件 = 函数 的形式绑定响应函数,
*     它只能同时为一个元素的一个事件绑定一个响应函数,
*     不能绑定多个,如果绑定了多个,则后边会覆盖掉前边的

* addEventListener()
*     通过这个方法也可以为元素绑定响应函数
*  参数:
*         1.事件的字符串,不要on
*         2.回调函数,当事件触发时该函数会被调用
*         3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false
* 
* 使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,
*     这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
* 
* 这个方法不支持IE8及以下的浏览器

json

* JSON
*     JS中的对象只有JS自己认识,其他的语言都不认识
*     JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别,
*         并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互
*     JSON
*         JavaScript Object Notation JS对象表示法
*         JSON和JS对象的格式一样,只不过【JSON字符串中的属性名必须加双引号】
*             其他的和JS语法一致
*         JSON分类:
*             1.对象 {}
*             2.数组 []
* 
*         JSON中允许的值:
*             1.字符串
*             2.数值
*             3.布尔值
*             4.null
*             5.对象
*             6.数组

* 将JSON字符串转换为JS中的对象
*     在JS中,为我们提供了一个工具类,就叫JSON
*     这个对象可以帮助我们将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON
* json --> js对象
*      JSON.parse()
*         可以将以JSON字符串转换为js对象
*         它需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回
* JS对象 ---> JSON
*     JSON.stringify()
*         可以将一个JS对象转换为JSON字符串
*         需要一个js对象作为参数,会返回一个JSON字符串
* eval()
*     这个函数可以用来执行一段字符串形式的JS代码,并将执行结果返回
*     如果使用eval()执行的字符串中含有{},它会将{}当成是代码块
*         如果不希望将其当成代码块解析,则需要在字符串前后各加一个()
* 
*     eval()这个函数的功能很强大,可以直接执行一个字符串中的js代码,
*         但是在开发中尽量不要使用,首先它的执行性能比较差,然后它还具有安全隐患
------ 本文结束,感谢您的阅读 ------
本文作者: 程序员青阳
版权声明: 本文采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。