JavaScript每日一学 —— 第八天
目录
一、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()