红宝书——章节读感(第三章 语法、关键字、变量、数据类型)

343 阅读2分钟

语言基础

说到基础,红宝书讲述的这一章可谓是ECMAScript的主心骨、大蟒蛇的七寸了。个人通过这一章节,重新巩固认识了JS这门语言。后面章节的学习也是依赖此章节知识的堆叠,后面就是个人竭尽全力的细致总结了。

PS:解释借助了书中一些例子,个人认为讲的非常清晰了,就借用一下。

语法

  • 区分大小写,例子:testTest是两个不同的变量
  • 跟大多数语言一样,变量名称也有相同的规范:/^[字母、下划线、美元符号][字母、下划线、美元符号或数字]*$/ (正则来了 清晰吧 ^=^)

关键字、保留字、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是最初的变量声明方式,而constlet则是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的情况下会报错 image.png
  • 因此可以采用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来的,毕竟是浏览器里面的