js部分新特性及其他操作

JS

使用use strict可以定义严格检查模式,检查当前声明后作用域及其子作用域

1、数据类型

如何判断数据类型
  1. typeof date
  2. date instance dateType 判断是否是有某一个构造函数创建出来的,原型链上是否有这个属性,无法比较基本数据类型(结果都为false),只能比较引用数据类类型
  3. Object.prototype.toString.call(date)
	let arr = []
	typeof arr 结果:Object
	arr instanceof Array 结果:true 
	1 instanceof Number 结果:false
	new Number(1) instanceof Number 结果:true
	Object.prototype,toString.call(arr) 结果:"[object Array]"
数据类型的种类
  • number

    • js不区分小数整数,NaN(Not a Number)不是一个数字,但它是数字类型,NaN 与任何都不相等包括自己,可以通过isNan或者Object.is(NaN,NaN)判断是否,
    • infinite代表无限大,数字类型,isFinite判断是否无穷,果参数是 NaN,正无穷大或者负无穷大,会返回 false,其他返回 true。
    • Number.isIntege(n)判断是否是整数
  • string:’’、"" ;任何数据类型与字符串相加都会转为字符串,准确来说是调用了对应的toString()方法

  • boolean:true、false

  • object: []、{}、null、class

  • function:function

  • undefined: undefined,为声明或赋值变量

2、变量var、let、const

  • 默认所有的全局变量(var)都会绑定在windows对象下,let和const不会

  • 函数中定义的变量仅本函数中有效,函数体外或其他函数不会冲突

  • 内部函数可以访问外部函数的变量,反之不行

  • 当内部函数和外部函数变量重名,采用就近原则,内部函数优先使用内部变量,由内向外查找,如果一直到windws下都找不到则会报ReferenceError错误

  • var定义的变量会进行作用域提升,即只要存在就优先声明但不会赋值,所以一般将使用到的变量在定义在最前面,尽管js会替我们做,但这样更符合规范,便于代码维护

  • 把自己的代码放到自己定义的唯一空间名字(对象)中,降低命名冲突

  • const解决常量问题,不可更改

  • let解决局部作用域冲突问题,通常用于for循环

  • let和const都不能重复声明且为块级作用域

3、ES6新特性Map和Set

将Map和Set转换为数组

var arr = [...set/map];
var arr = Array.from(set/map)

Map

key值可以为字符串、基本类型、对象、数组、函数变量等,甚至是NaN也可以,但只会出现一个NaN,包括(+0,-0),undefined ,null,‘’ 都是唯一的

## Map的构造中不仅能传二维数组,还可以直接传递Map对象
var map = new Map([['jack',10],['marry',88],
['tom',22]]) // 创建对象并初始化
let mapCopy = new Map(map)
// 使用...实现Map的合并操作
let mapMerge = new Map([...firstMap,...secondMap])
var map = new Map() // 仅创建对象
// 将对象转化为Map
var obj = { foo: "bar", baz: 42 }; 
var map = new Map(Object.entries(obj));
// 将map转换为对象
var obj = {}
map.forEach((val,key)=>{
    obj[key] = val
})
  • set(key,val) 设置map的一个键值对,返回map,同key会覆盖

  • get(key) 根据键获取值,不存在则返回undefind

  • has(key) 是否存在指定key在map中

  • delete(key) 根据key删除指定键值对,返回boolean

  • clear() 清除所有的键值对

  • size 获取map的键值对长度

  • keys():返回键名的遍历器

  • values():返回键值的遍历器

  • entries():返回键值对的遍历器

  • forEach():使用回调函数遍历每个成员

迭代器默认指向当前数据结构的起始位置,随后通过 next 方法进行向下迭代指向下一个位置, next 方法会返回当前位置的对象,对象包含了 value 和 done 两个属性, value 是当前属性的值, done 用于判断是否遍历结束,当 done 为 true 时则遍历结束

map的遍历
// 遍历所有的键
var map = new Map([['jack',10],['marry',88],['tom',22]])
for (let key of map.keys()) {
   console.log(key)
}
// 数组遍历每一个数组形式的键值对
for (let item of map.entries()) {
   console.log(item[0], item[1]);
}
// 遍历所有的值
for (let value of map.values()) {
   console.log(value)
}
// 使用解构遍历直接去的键值对
for (var [key, value] of map) {
 console.log(key ,value);
}
//返回键或值的数组
[...map.keys()] 
[...map.values()]
Array.from(map.keys())
// 迭代器
let iterator = map.keys() 结果:MapIterator {"jack", "marry", "tom"}
iterator.next() 结果:{value: "jack", done: false}
iterator.next() 结果: {value: "jack", done: false}
iterator.next() 结果: {value: "tom", done: false}
iterator.next() 结果:{value: undefined, done: true}
// foreach遍历,回调依次为值、键和map对象
map.forEach((val,key,map)=>{
   console.log(val)
   console.log(key)
   console.log(map)
})

Set

你可以把set当做键值一样(val==key)的map,同样可以使用keys()、values()、entries()
Set的特点就是不允许具有重复(值和类型都相同或引用地址相同)的元素,非常适合去重

var set = new Set() // 仅创建对象
var set = new Set([1,2,3]) // 创建对象并初始化
var newSet  = new Set(set) //使用已有对象创建
var newSet =  new Set([...a,4]) //创建并加新值
## 字符串的本质就是一个字符数组
var strSet = new Set('abcd') // {"a", "b", "c", "d"} 相当于  new Set(['a','b','c','d'])
  • add(item) 向set中添加一个item,返回set

  • has(item) 是否存在指定item在set中

  • delete(item) 删除item,返回boolean

  • clear() 清除所有的键值对

  • size 获取map的键值对长度

  • keys():返回item的遍历器

  • values():返回item的遍历器

  • entries():返回[item,item]的遍历器

  • forEach():使用回调函数遍历每个成员

// 其余遍历同上
// 数组遍历每一个值,相当于for (let value of set.values())
for (let value of set) {
    console.log(value)
}
//foreach遍历,回调依次为值、键和map对象
set.forEach((val,key,set)=>{
    console.log(val)
    console.log(key)
    console.log(set)
})
// 数组去重
[...new Set([1,24,2,2,38,2,342,24])]; 结果:[1, 24, 2, 38, 342]
// 字符串去重
[...new Set('12323134')].join("") 结果:"1234
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
// 数组的并集,交集,差差
new Set([...a, ...b]); // {1, 2, 3, 4}
new Set([...a].filter(x => b.has(x))); // {2, 3}
new Set([...a].filter(x => !b.has(x))); // {1}

JS技巧

谨慎使用下列代码,将会降低代码可读性,使用必须加注释

0,false,undefine,NaN,null,’’ 由于这个几个值转为Boolean时皆为false,我将其称为false值,0,false,null,’’ ,’ '转为number为0,NaN,undefine转为number为NaN

  • 可以使用<<来快速开出2次方,代表将左边的二进制向左移动右数字位数
1<<2  //4
1<<10 //1024
  • JS中的||符号:前值false,返回后值,前值true,返回前值 --真前假后,常用于默认值

  • JS中的&&符号:前值false,返回前值,前值true,返回后值 – 假前真后,常用于某种操作

is(flag){
	fn()
} 
flag && fn() // 等价上述于
flag && (name = 'js')  // 等价于if(flag){name = 'js')
let name = null || 'obj' //赋默认值
  • 使用^异或(相异为1)可以切换变量0或1,还可以利用此特判断两个数字是否相等
let toggle=1
toggle^=1 //当为1时为0,1时为0,等价于toggle = toggle ? 0:1
  • JS中的&与(同为1才为1)符号:可用于校验奇偶性,奇数&1=1,偶数&1=0

  • 使用!!可以快速将数字等类型转为boolean,测试仅false值为false

 !!false => false
 !!1 => true 
  • 使用+字符串可以快速将字符串转为数字
let a='666'
+a 结果 666
+a+1 结果 667,等价于1+(+a)
  • 使用~~,>>,<<,|可以对小数进行取整,因为浮点数是无法进行位运算的,所以浮点运算时会丢弃小数部分,所以浮点数进行位运算是会自动向下取整,相当于Math.floor()

    ~~11.47
    11.47>>0
    11.47<<0 
    11.47|0 //上述结果皆为17
    
  • 使用当前时间创建一个随机数

    Number(new Date())%100 //两位随机数,其余同理
    
  • 使用1/0和-1/0可以快速创建Infinity和-Infinity

  • 使用arr.slice(-1)[0]等级于arr[arr.length-1]截取最后一项

杂项

arguments

arguments 是一个对应于传递给函数的参数的类数组对象。你可通过arguments[0]直接取值或for遍历输出,0你可以把它看为属性,尽管在此他和下标没有什么区别,并且它具有数组的length属性。所以它同时具有数组和对象的部分特性,使用…可以达到类似效果,并且可以用数组方法等,不过更建议使用展开语法

fun(1, 2, 3, 4, 5, 6);
以上arguments为 Object { 0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6 }
[...arguments]将arguments转为数组

this

  • this的指向在函数创建的时候是决定不了的,在调用的时候才能决定, 如果使用对象调用方法则this指向调用对象,否则直接调用指向window(如果是严格模式,为undefined)对象,总之:谁调用的就指向谁
  • 当有多级对象调用时,如window.obj.method(),this指向的也只是它上一级的对象,即obj
  • 使用new关键字将函数作为构造函数调用时,构造函数内this指向新创建的对象
  • 如果构造函数返回值是一个对象,那么this指向的就是那个返回的对象(对象,数组,函数等),如果返回值不是一个对象那么this还是指向函数的实例,
  • 对于函数内的函数的this与外部函数不适应同一个this,默认为window(如果是严格模式,为undefined)
  • 箭头函数在自己的作用域内没有自己的 this,如果要使用 this ,就会指向定义时所在的作用域的 this 值(如果上一级也是箭头函数,继续向上寻找),如果箭头函数直接定义在一个对象/函数中,那么箭头函数的this就是该对象/函数的this,否则,箭头函数的this指向window。eg:对于事件处理中的this默认为事件源对象,如果在箭头函数中既想使用外部this又想使用事件源对象,可以把event传参(不传也可以,默认单击事件中的event指向事件源,但传了阅读方便)
// 方法1(推荐)
button.addEventListener("click",event=>{
	console.log(`${this.title}-${event.target.innerHTML}`)
})	
// 方法2(使用外部变量记录this)
const self = this;
button.addEventListener("click",function(){
	console.log(`${self.title}-${event.target.innerHTML}`)
})
// 方法3(使用bind更改函数中的this)
button.addEventListener("click",function(){
	console.log(`${this.title}-${event.target.innerHTML}`)
}.bind(this)
// 方法4(当前对象中有一个handleEvent方法会自动调用,里面的this就执行当前对象)
handleEvent:function(event){
	console.log(`${self.title}-${event.target.innerHTML}`)
},
button.addEventListener("click",this) 
  • 回调函数中的this指向其函数运行所在环境的对象,而不是定义时所在的this对象,建议使用箭头函数
  • call()apply()bind() 方法可以将function方法中this 更改引用到其他对象
  • call:调用一个对象的一个函数,用另一个对象替换当前对象。例如:B.call(A, args1,args2);即A对象调用B对象的方法。它可以接受多个参数,第一个参数与apply一样,后面则是一串参数列表,会立刻执行。
  • apply:调用一个对象的一个函数,用另一个对象替换当前对象。例如:B.apply(A, arguments);即A对象应用B对象的方法。最多只能有两个参数——新this对象和一个数组argArray,会立刻执行。
  • bind:复制一个对象的一个函数,用另一个对象替换当前对象。例如:B.bind(A, args1,args2)();同call,单调用需要结尾加上(),他返回的是一个函数,需要()调用才可以,参数可以在bind时传也可以再调用再传(是在bing参数的基础上继续传参,不会覆盖bind的参数,在后面继续添加)。
 var person1 = {
     firstName:"Jack",
     lastName: "Tom",
     fullName: function(name,age) {
         console.log(name,age)
         return this.firstName + " " + this.lastName;
     }
 }
 var person2 = {
     firstName:"John",
     lastName: "Doe",
 }
person1.fullName(1,2); // 1 2 "Jack Tom"
person1.fullName.call(person2,1,2);  // 1 2 "John Doe"
person1.fullName.apply(person2,[1,2]); //同上
person1.fullName.bind(person2,1,2)(); //同上

JSON和eval

  • JSON拥有两个方法parse和stringify用于对象/数组与字符串之间的互转,JSON对于字符串对象的解析有一定的格式要求,
    1. 属性名称必须用双引号包裹
    2. 最后一个属性后面不能有逗号
 JSON.parse("{a:1}") // 错误,属性必须使用双括号,改位JSON.parse('{"a":1}')即可
 let index = 1
 JSON.parse(`{"item[${index}].age":"${new Date()%100}"}`) // {item[1].age: 57}
  • eval也能完成JSON格式数据的解析,而且可以进行语句的运算和变量声明等操作,如果这个字符串不受第三方影响,也可以使用,但要在其前后加上大括号(),原因如下:
    1. json对象是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理
    2. 加上圆括号为了处理字符串为表达式,而不是语句(statement)来执行
eval("({a:1})") // 可以不加双括号
eval(`({"item[${index}].age":new Date()%100})`) // {item[1].age: 57}

进制转换

  • parseInt(val,n) n进制val转十进制
  • Number(val).toString(n)十进制val转n进制
	let a =parseInt(110,8) 结果:72
	a.toString(8) 结果 110
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

信息技术王凤龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值