JavaScript每日一学 —— 第八天

目录

一、JSON

二、XML(概述)

三、ES5的严格模式

四、this对象

五、 ES5数组方法

六、用filter去做数组去重

七、包装类


一、JSON

语言问题:

        前端语言有三个html、css、JavaScript

        后端语言有很多个java、php、python、go、c、c++、node.js等等

        前端和后端需要相互之间传递数据,前端有自己的规范,后端每一种语言都有自己的规范,那么进行数据交互的时候成本会非常高,也非常不利于开发,为了解决数据交互的问题,有人就提出了标准化数据格式也就是JSON,这种数据格式每一种语言都支持,可以解决成本和不便利的问题

JSON:

        json就是用于前后端数据交互的一种数据格式

        被绝大多数语言支持

        前端开发人员来学习json成本是非常低的,因为json数据格式使用的语法就是js对象

JSON语法格式:

        json要求所有的属性名都使用双引号

        在js对象的外层还需要加单引号,因此说json是一种特殊的字符串类型

JSON转换方法:

        把js对象转成json格式:JSON.stringify()

        把json格式转成js对象:JSON.parse()

//js对象
var obj = {a: 1}
//JSON对象
var arr = '[{"name" : "张三", "age" : 18, "sex" : "男"}, { "name" : "李思","age" : 20,"sex": "女"}]'
console.log(typeof arr) 

//把JSON对象转成js对象
console.log('JSON转js',JSON.parse(arr))

//把js对象转成JSON对象
console.log('js转JSON',JSON.stringify(obj))



 eval():用来执行一段字符串形式的JS代码,并将执行结果返回

var str = 'console.log("hello eval")'
eval(str) 

var obj = '{a: 1}'
var res = eval(obj)
console.log('res为',res)

var obj1 = '{a:1,b:2}'
console.log(eval(obj1))


 可以看到,当对象里面的属性不止一个的时候就会报错,这是因为当使用eval()执行的字符串中含有{}, 它会将{}当成代码块执行,如果不希望将其当成代码块解析,则需要在字符串前后各加一个()

我们将刚刚的代码改进一下

var obj1 = eval("("+'{a:1, b:2}'+")")
console.log(obj)

可以看到,当加了"("")" 之后就没问题了

二、XML(概述)

xml可扩展标记语言

        也是一种数据格式,和json的功能是一样的,但是没有json好用,现在基本上都是在使用json

        xml语法和html语法一样的

        xml数据结构采用的是html标记形式,只不过它的标记可以自定义,而html标记不能自定义,是规定好的

比如

<person>
    <name>蔡徐坤</name>
    <age>18</age>
    <sex>男</sex>
 </person>

XML和JSON区别

        json是轻量级

        xml使用起来相对比较麻烦

        json处理数据速度更快

XML与HTML的区别

        HTML 的主要目的是展示和呈现内容,它有固定的标记集和规范,并且可以通过 Web 浏览器直接处理和呈现。

        XML 的主要目的是存储和传输数据,它可以定义自定义的标记集和结构,并需要特殊的程序来解析和处理数据。

具体的可以参考这篇文章:XML与HTML的六大区别

三、ES5的严格模式

概念:除了正常运行模式,ECMAscript5添加了第二种运行模式:“严格模式”(strict mode)。顾名思义,这种模式是的Javascript在更严格的条件下运行。 

严格模式的作用:

        a.消除了JS语法的一些不合理、不严谨之处,减少一些怪异行为;

        b.消除代码运行的一些不安全之处,保证代码运行的安全;

        c.提高编译器效率,增加运行速度;

        d.为未来新版本的JS做好铺垫

注意点:同样的代码,在“严格模式”中,可能会有不一样的运行结果,一些在“正常模式”下可以正常运行的语句,在“严格模式”下将不能运行,掌握这些内容,有助于更细致深入的理解JS,让你变成一个更好的程序员。

进入严格模式的代码:'use strict'

全局严格模式:把进入严格模式的代码放在全局作用域的最顶端。如果这行语句不在第一行,则无效,整个脚本以“正常模式”运行。如果要把不同模式的代码文件合并成一个文件,这一点需要特别注意。

局部严格模式:把进入严格模式的代码放在函数里面。

脚本文件的变通写法:因为第一种调用方式不利于文件合并,所以更好的做法是,借用第二种方法,将整个脚本文件放在一个立即执行的匿名函数中

进入严格模式的变化:

        1.全局变量声明时,必须加关键字(var)

正常模式:a = 10;    console.log(a)    //10
严格模式:a = 10;    console.log(a)    //a is not defined

        2.函数内不允许出现重名参数

正常模式:function fn( a,b,b ){ console.log(a,b) }
fn(1,2,3)        //1,3
严格模式:function fn( a,b,b ){ }
//报错:Duplicate parameter name not allowed in this context    在此上下文中不允许出现重复的参数名

        3.arguments对象不允许被动态改变

正常模式:
function fn(a){
    a=20;
    console.log(a);                //20
    console.log(arguments[0]);     //20
}
fn(10);

严格模式:
function fn(a){
    a=20;
    console.log(a);                //20
    console.log(arguments[0]);     //10
}
fn(10);

        4.不允许使用arguments.callee(注意点:arguments.callee()在ES5的版本中被废弃掉了)

        5.this无法指向全局对象

        6.新增的保留字:implements,interface,let,package,private,protected,public,static,yield

四、this对象

this对象:指的是函数执行上下文对象(上下文指的是代码的执行环境)

this是函数内部隐含的一个参数,它会根据函数的调用方式不同而指向不同的对象

也可以说,this会根据函数的执行环境不同而指向不同的对象

作用:最大的作用就是根据函数调用方式不同,指向的对象不同

规则:

        函数名称加括号调用函数时,this指向的是window。在ES5严格模式下,通过这种方式this是无法执行全局对象window的

        当通过对象调用函数的时候,里面的this指向的是当前的对象

        当通过事件调用函数的时候,里面的this指向的是当前事件的调用者

//函数名加括号调用函数
function fn(){
    console.log(this) // window
}
fn()
function fn1(){
    'use strict'
    console.log(this) // undefined
}
fn1()

//通过对象调用函数
var obj = {
    name:'蔡徐坤',
    age:18,
    saying(){
        console.log('你干嘛,哎哟!')
        console.log(this) //指向当前对象,也就是obj
    }
}
obj.saying()

//通过事件调用函数
// 通过标记名称获取元素,结果是一个伪数组
ar aBtn = document.getElementsByTagName('button')
需求:当点击那个元素的时候改变其背景颜色
注意点:在js里面使用css属性,只需要把属性连接的中划线修改为小驼峰命名即可
//通过遍历伪数组来快速绑定事件
for(var i=0; i<aBtn.length; i++){
    aBtn[i].onclick = function(){
        aBtn[i].style.backgroundColor = 'orange'
        console.log(aBtn[i]) // undefined
        console.log(i) // 5
    }
}
/*
    问题:在事件处理函数里面获取不到最新的i的值
    原因:事件是只有咱们触发了才会去调用事件处理函数,循环是不会等待事件触发后再去执行的,因此出现了,循环先执行完毕,后执行的事件,因此拿到不到i的值
    规则:当事件处理函数在循环里面的时候,会先执行完毕循环后,再去执行事件处理函数
    解决:用this
*/
for(var i=0; i<aBtn.length; i++){
    aBtn[i].onclick = function(){
        //排他思想:先清除所有的样式,再给自己设置
        for(var j=0; j<aBtn.length; j++){
            aBtn[j].style.backgroundColor = ''
         }
        this.style.backgroundColor = 'orange'
    }
}

五、 ES5数组方法

1.indexOf(data,start)接收两个参数:要查找的项和(可选的)表示查找起点位置的索引

注意点:进行查找的时候只能找到这个元素第一次在数组中出现的位置。如果没有找到那么返回-1

2.lastIndexOf() 从后面往前面进行查找

var arr = ['a', 'b', 'c', 'b', 'h', 's', 'b']
console.log(arr.indexOf('b', 4)) // 6
console.log(arr.lastIndexOf('l')) // -1
console.log(arr.lastIndexOf('b', 5)) // 3

3. findIndex()

查找数组元素的位置的,但是它里面可以写条件,参数是一个回调函数

回调函数参数

         参数1表示的是当前数组的元素

        参数2表示的是当前数组元素的下标

        参数3表示的是当前数组

var list = [
            {
                id: 1,
                title: 'Xiaomi 14 Pro',
                price: 4999,
                cart_num: 0
            },
            {
                id: 2,
                title: 'Xiaomi 14',
                price: 3999,
                cart_num: 0
            },
            {
                id: 3,
                title: 'Redmi Note 13 Pro',
                price: 1399,
                cart_num: 0
            }
        ]
var index = list.findIndex(function(item){
    return item.id == 2
})
console.log('index:',index)
list[index].cart_num = 1
console.log(list)

4.forEach():循环,对数组进行遍历循环,对数组中的每一项运行给定函数。这个方法没有返回值,参数是一个回调函数

回调函数参数

        参数1表示的是当前数组的元素

        参数2表示的是当前数组元素的下标

        参数3表示的是当前数组

var arr = [10, 30, 20]
var newArr = []
arr.forEach(function(item){
    item *= (1+0.3)
    //这个方法是没有返回值的,所有需要自己创建一个新数组来保存操作后的数据
    newArr.push(item)
})
console.log(newArr) // [13,39,26]

 5.map():会遍历当前数组,然后调用参数中的方法,返回当前方法的返回值

map可以改变当前循环的值,返回一个新的被改变过值之后的数组(map需return),一般用来处理需要修改某一个数组的值。映射

参数是一个回调函数,回调函数参数

        参数1表示的是当前数组的元素

        参数2表示的是当前数组元素的下标

        参数3表示的是当前数组

var arr = [10, 20, 30]
var res = arr.map(function(item){
    return item *= 1.3
})
console.log(res) // [13,26,39]

6.filter():遍历和过滤。返回符合条件的元素的数组。filter需要在循环的时候判断一下是true还是false,是true才会返回这个元素。参数是一个回调函数

回调函数参数

        参数1表示的是当前数组的元素

        参数2表示的是当前数组元素的下标

        参数3表示的是当前数组

var data = [
    {
        id:1,
        name:'泥甘哞',
        age:'18'
    },
    {
        id:2,
        name:'梅狸猫',
        age:'20'
    },
    {
        id:3,
        name:'蔡徐坤',
        age:'23'
    }
]
var res = data.filter(function(item){
    return item.age > 22
})
console.log(res) // [{id:3,name:'蔡徐坤',age:23}]

// 模糊搜索功能
var res1 = data.filter(function(item){
    return item.name.includes('猫')
}
console.log(res1) // [{id:2,name:'梅狸猫',age:20}]



补充:

includes() 字符串方法,查找到字符串里面是否有满足条件的,只有有就返回true

7.find():根据条件返回数组中满足条件的数组元素,但是返回是当前的数组元素,不会放在一个新数组里面,参数是一个回调函数

回调函数参数

        参数1表示的是当前数组的元素

        参数2表示的是当前数组元素的下标

        参数3表示的是当前数组

//find 方式
var res = data.find(function(item){
    return item.id == 2
})
console.log(res) // {id;2,name:'梅狸猫',age:20}

//filter方式
var res1 = data.filter(function(item){
    return item.id == 2
})
console.log(res1) // [{id;2,name:'梅狸猫',age:20}]

六、用filter去做数组去重

var arr = ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'f', 'd', 's', 'd', 's']
// indexOf()只会查找数组元素第一次在数组中出现的位置
var res = arr.filter(function(item, index){
     //'a' 0 == 0
    //'a' 0 == 1 不满足
    //'a' 0 == 2 不满足
    //'b' 3 == 3 满
    //'b' 3 == 4 不满足
    return arr.indexOf(item) == index
})

七、包装类

定义字符串除了字面量和构造函数,还有包装类的方法

//字面量
var str = 'hello'
// string ---- new String() --- string
// String() --- 帮助你把事情做了
// console.log(str.length) // 5
// console.log(str[1]) // e


//构造函数
var str = new String('hello')
console.log(typeof str) // object

//包装类
var str = String('hello')
console.log(typeof str) // string

js使用属性和方法规则:规定基本数据类型是无法使用属性和方法的,只有引用数据类型才能使用属性和方法

包装类类型:基本数据类型无法使用属性和方法的,但是有时候需要让基本数据类型使用属性和方法,但是又不能违法规则,因此提出了包装类

当基本数据类型在使用属性和方法的时候,会先把基本数据类型转成引用数据类型,当你使用完毕后再转成基本数据类型

String() 、Number()、Boolean()