这是我参与「第四届青训营 」笔记创作活动的第4天。
以下是深入学习JavaScript以及结合上课内容写的笔记,整理了一些JavaScript中可能会被忽略的知识和问题。
0.1+0.2!=0.3:
原因:JS采用的是双精度版本,即IEEE 754双精度版本(64位),这个版本存在精度问题,导致此情况
标签语法:
标签语句
可以为语句添加一个标签,例如:
start: //标签
for(let i=0;i<5;i++){
console.log(i);
}
可以使用break和continue来操作指定语句
outermost:
for(let i=0;i<5;i++){
for(let j=0;j<5;j++){
if(i==5&&j==5){
break outermost;
//continue outermost;
}
}
}
组合使用标签语句和break、continue可以实现复杂的逻辑,但也容易出错。
注意标签要使用描述性强的文本
for-in
for-in是一种严格的迭代语句,用于枚举对戏那个中的非符号键属性;
非符号键
符号键是计算机与用户或其他设备通信的桥梁
分为分隔符、特殊字符和空格字符
由于翻译错误,非符号键表示不是Symbol的键
所有元素都会遍历一遍,但是返回顺序不确定,不同的浏览器返回顺序不同。
如果迭代的值为null或者undefined,则不会产生迭代
通常使用for-in来遍历键名(key),for-of来遍历键值(value)
指数操作符(**)
使用**可以进行指数操作,如下
var a=5**2;
console.log(a==25);
with语句
With语句
let qs=location.search.substring(1);
let hostName=location.hostname;
let url=location.href;
以上语句都使用的location对象,使用with语句,可以少写一些代码
with(loaction){
let qs=search.substring(1);
let hostName=hostname;
let url=href;
}
但是with语句难于调试且影响性能,不推荐使用,在严格模式下会报错。
var变量声明
-
使用var声明变量时,变量会自动添加到最接近的上下文,如果变量未经声明就被初始化,那它将被添加到全局上下文中,并且,如果这个变量是在函数中生成的,函数退出后依然可以被访问到。
-
提升:var声明会被拿到函数或全局作用域的顶部,位于所有代码之前,这个现象叫作提升,但是在显示中,会导致一些问题
声明的提升意味着只会输出undefined而不会报错
console.log(name); //undefined var name='Jake'; //在console.log中,name先声明然后被调用,出现undefined情况
let变量声明
块级作用域声明
let声明的作用域是块级的,块级作用域是由最近的一对包含花括号{}界定,比如说:常见的if块、while块、function块,甚至单独的块也是let声明变量的作用域
另外,let与var的不同之处是在同一个作用域不能声明两次,重复的var会被忽略,但是重复的let会抛出错误
let也会被提升,但是由于暂时性死区,不能在声明之前使用let变量
const变量声明
使用const变量必须同时初始化为某个值,一经声明,在其生命周期的任何时候都不能再重新赋予新值。
赋值为对象的const变量不能再被重新赋值为其他引用值,但对象的键不受限制。
传递参数
即使对象是按照值传递函数的,obj也会通过引用访问对象。
复制值
以下代码中,num1和num2是两个独立的变量
let num1=5;
let num2=num1;
console.log(num1===num2); //false
但是,对于引用对象
let obj1=new Object();
let obj2=obj1;
obj1.name="Jack";
console.log(obj2.name); //Jack
这是因为obj1和obj2都是引用对象,属于指针,将obj1赋值给obj2只是将指针传递给obj2,底层的内存并没有改变,故obj1==obj2
所以原始值复制为新的变量,引用值赋值为同一个变量
原始值和引用值
引用值是保存在内存中的对象,与其他语言不同,JavaScript不允许直接访问内存位置,因此也就不能操作对象所在的内存空间。在操作对象是,实际上操作的是对对象的引用而非对象的本身。
在很多语言中,字符串时使用对象表示的,因此被认为是引用类型,ECMAScript打破了这个惯例
只有引用值可以动态地添加后面的属性,比如:
let p=new Person();
p.name="James"; //正常赋值
p.name.age=16; //undefined
Date
将字符串转为时间(三种方式):
- 月/日/年,切记要为月日年,比如:“5/23/2019”
- 月名 日,年,如:“May 25 2019”
- 周几 月名 日 年 时:分:秒 时区,如:“Tue May 23 2019 00:00:00 GMT-0700”
声明Date对象:
let date1=new Date(Date.parse("5/23/2019"));
上面与下面相等,是因为会默认调用Date.parse();
let date1=new Date("5/23/2019");
Date.UTC()
使用参数为年、零起点月数(1月是0,2月是1)
2022年7月25日下午三点55分16秒可以写为
let date2=new Date("2022,6,25,15,55,16");
//或者
let date2=new Date(Date.UTC("2022,6,25,15,55,16"));[
]