分类: 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 中国大陆许可协议进行许可。