语言基础
说到基础,红宝书讲述的这一章可谓是ECMAScript的主心骨、大蟒蛇的七寸了。个人通过这一章节,重新巩固认识了JS这门语言。后面章节的学习也是依赖此章节知识的堆叠,后面就是个人竭尽全力的细致总结了。
PS:解释借助了书中一些例子,个人认为讲的非常清晰了,就借用一下。
语法
- 区分大小写,例子:
test
和Test
是两个不同的变量 - 跟大多数语言一样,变量名称也有相同的规范:
/^[字母、下划线、美元符号][字母、下划线、美元符号或数字]*$/
(正则来了 清晰吧 ^=^)
关键字、保留字、true、false、null不是标识符
- 注释 // /** */
- 严格模式 "use strict" 可以在代码块中用doSomething{ "use strict" ...... } 有用TS的大佬应该比较有感触
- 语句
let num = 1;
这个分号;
真的要养成习惯,书中说道提升性能这点,可不是吹的; 红宝书告诉我们,其实这写法看似高大上,但不实际,影响阅读
if(test)
console.info("test");
下面这样说实话舒服多了,大不了不换行也行呀
if(test){
console.info("test");
}
关键字与保留字
- 关键字
let
const
break
yield
debugger
default
export
还有很多的
- 保留字
enum
await
严格模式下的更多 public static
变量(作用域学习关键)
var
是最初的变量声明方式,而const
和let
则是es6出现的语法
var关键字
var reader = "爸爸";
reader = "大佬";
reader = 666; //不推荐 ts中需要定义变量类型
- var声明作用域 var会把变量变为局部
function test() {
var reader = "爸爸";
}
test();
console.info(reader); //报错 这时候reader未定义
声明全局变量便不会有问题
function test() {
reader = "爸爸"; //相当于window.reader = "爸爸" 严格模式不行
}
test();
console.info(reader); // 打印“爸爸”
- var声明提升
function test(){
console.info(age); //不会报错 打印undefined 变量声明会提升
var age = 18;
var age = 30; // 可以一直声明
}
test();
let声明(作用域开始出现)
if(true){
var age = 30;
let fakeAge = 18;
let fakeAge = 10; // 不能声明多次
}
console.info(age) // 30
console.info(fakeAge); // ERROR 未定义
let fakeAge = 10;
if(true){ let fakeAge = 18; } //不会报错
- 暂时性死区
function test(){
console.info(age); //ERROR 未定义 无法被提升
let age = 18;
}
test();
- 全局声明
//这时候上下文就是window 跟上面test方法里的reader不一样
var reader = "爸爸";
window.reader //“爸爸”
let reader = "爸爸";
window.reader //undefined
条件中尽量不要声明值,理解难
if(true) {
let age = 18;
}
console.info(age); //容易出现未定义bug
养成先声明习惯
let age;
if(true){
age = 18;
}
- 循环中的let声明
for (let i = 0;i < 5; ++i){} //i的作用域在全局
console.info(i); // ERROR 未定义
红宝书举了个很有趣的例子
for(var i = 0;i < 5; ++i){
setTimeout(()=>{ console.info(i) },0);
}
//结果会输入5、5、5、5、5
for(let i = 0;i < 5; ++i){
setTimeout(()=>{ console.info(i) },0);
}
//结果会输入0、1、2、3、4
关键就是引用不同:var是全局的,而let是在作用域中的变量
const 声明
const age = 30;
age = 18; //不可以再改变了 时光无法倒流T-T
经常用来定义全局枚举变量
const CHINA = "中国";
解析对象和数组的时候可以用
for(const key in {a:1,b:2}){}
for(const value of [1,2,3,4,5]){}
声明风格及最佳实践
- var被淘汰了
- const优先,let次之
数据类型
Undefined、Null、Boolean、Number、String、Symbol。Objet这种数据类型在ECMAScript中简直是锦上添花的存在,后面的集合引用类型章节会重点描述!重点描述!重点描述!
typeof操作符
我们开发中算是经常用了
typeof "爸爸" === "string"
typeof 666 === "number"
但是要注意 typeof null === "object"
,因为是空对象。
Undefined 类型
并不是没有实例化的意思(这个会报错),而是没有赋过值(未初始化)。
let message;
console.info(message); //undefined
console.info(age); //报错
Null类型
- 初始化一般用null来初始化
let car = null;
- null == undefined //true 这个要记住
- 区分好假值和空值,也就是null与undefined
Boolean类型
Number中的NaN和0表示false,要记住的只有这一点
Number类型(进制的利用)
八进制:0开头
- 070:有效,56
- 079:无效,当成79
- 08:无效,当成8 十六进制:0x开头
- 0x1f:31
1、浮点值
- 科学计数法:3.14e7
- 加法不行:0.1+0.2是等于0.3000000000000000004,因为使用了IEEE754;如果是0.15和0.15 ,那么没问题。至于这个规律嘛,书中没说,可以去了解一下IEEE754~。~ 2、值的范围
- Number.MAX_VALUE ,可用isFinite(num)判断
- Number.MIN_VALUE 3、NaN
- 0/0就是NaN
- NaN != NaN
isNaN()
表示是不是数值 4、数值转换
Number("") // 0
Number("LOL") // NaN
parseInt("") // NaN
parseInt("10",2) // 2 二进制
parseFloat 重点
parseFloat("0xA") //0
// 因为parseFloat只能解析十进制
parseFloat("3.125e7") //31250000 可以解析科学计数法
// 项目中需要可以如此转换,但是要注意number空值的时候是NaN 要单独判断
parseFloat(number).toString()
String类型
2、字符串的特点
- 拼接字符串的原因:String不可变,必须先销毁原来的变量重新赋新变量才能改变 3、转换为字符串
let num = 10;
num.toString(2); // "1010"二进制转换
- 不确定a的情况下会报错
- 因此可以采用
String(null)
、String(undefined)
,会直接转为字符串 4、模板字面量
`
<div>${name}</div>
`
重点来了:新技能
5、字符串插值
let foo = { toString: () => 'World' };
console.log(`Hello,${foo}!`) //Hello,World!
//${ }中可以传入对象,里面实例化toString方法即可
当然,也可以直接传入方法
let getStringFunc = (str) => {
let obj = {
"1": "测试中",
"2": "测试通过"
}
return obj[str] || '';
}
console.log(`您好,您现在${ getStringFunc("1") }`)
console.log(`您好,您现在${ getStringFunc("2") }`)
6、模板字面量标签函数
function strFormat(stringIn,...expressions){
//里面stringIn表示整个字符串
//expressions表示所有${ }的值:[a,b,a+b]这样
}
strFormat`${a}+${b}=${a+b}`
7、原始字符串
可以通过strings.raw
获得初始字符串 不含\n、\t之类的数组
Symbol类型
这一章节在我目前编码中用途不是很大*(主要我自己也没整明白用途会在哪,所以不好发表),但是会单独作为一章节来讲(待我后续研究完整再跟各位分享)*
Object类型
let o = new Object(); //与{}是不一样的 实例对象
先记住这些非原型的Object实例属性和方法,否则会容易跟后面的第五章和第六章的原型应用混
- constructor:就是Object()函数本身 其实Function也是Object
- hasOwnProperty(属性名):检验对象实例,不能检验原型是否存在原型属性
- isPropertyof(Object):一个对象是不是另一个对象的原型
- porpertyIsEnumerable(属性名):是否可以用for-in枚举
- toLocaleString():返回对象的字符串表示(更详细)
- toSring():转字符串
- valueOf():与toString差不多 后面讲到原型链的继承机制,就可以看出Object是基类
当然BOM和DOM不是Object来的,毕竟是浏览器里面的