You Don't know JS学习笔记(一)

你不知道的JS中册学习笔记

类型和语法啊

类型

  • 七种内置类型

    • null
    • undefined
    • boolean
    • number
    • string
    • object
    • symbol(ES6)
  • 变量是没有类型的,只有值才有类型

  • 数组中存取的键值如果是数字的话,将会被转换成索引值
var a = [];
a["2"] = 4;
console.log('a.length',a.length)    // 3

如果采用键值赋值的方式,并不是按照顺序的存储

var a = [];
a["test"] = 4;
console.log("a["test"]", a["test"])
console.log('a.length', a.length)

// a["test"] 4
// a.length 0   ????为什么是这么个结果
  • 字符串是不可变的,数组是可变的。

    • 字符串的成员函数不会改变其原始值,而是创建并返回一个新的字符串
    • 数组的成员函数是在其原始值上进行操作的
  • 简单的字符串反转[不包括Unicode,星号,多字节字符]

var a = "test";
var c = a.split("").reverse().join("");
  • 数字

    • 由于二进制浮点数精度的问题 0.1 + 0.2 === 0.3 //false
      (0.1+0.2实际等于0.300000000004)
    • 上述问题的常见解决方法是设置一个误差范围值(“机器精度”)–2^-52
  • void 没有返回值,因此返回结果是undefined(可以不让表达式返回任何结果)

  • NaN(not a number)是一个“警戒值”(sentinel value)仍然是数字类型,但是它和自身不相等,是唯一一个非自反的值

  • 引用

    • JS中引用指向的是值。在JS中变量不可能成为指向另一个变量的引用(区别与C++)
    • JS对值和引用的赋值/传递在语法上没有区别,完全根据值的类型来决定。
    var a = 2;
    var b = a; // b是a的一个副本
    b++;
    a;  // 2
    b;  // 3
    
    
    var c = [1,2,3];
    var d = c; // d是c的一个引用
    d.push(4);
    console.log("c",c,"d",d);   //c [ 1, 2, 3, 4 ] d [ 1, 2, 3, 4 ]
    
    • 简单值总是通过值复制的方式来赋值/传递,包括null,undefined,字符串,数字,布尔,symbol
    • 复合值–对象(包括数组和封装对象),函数。总是通过引用复制的方式来赋值/传递。
    • 引用指向的是值本身而非变量,所以一个引用无法更改另一引用的指向
    function foo(x){
        x.push(4);
        console.log('x',x);
        x = [4,5,6]
        x.push(7);
        console.log('x',x);
    }
    
    var a = [1,2,3];
    foo(a);
    console.log('a',a)
    // x [ 1, 2, 3, 4 ]
    // x [ 4, 5, 6, 7 ]
    // a [ 1, 2, 3, 4 ]
    
    • 如果要更改上述a的为[4,5,6,7],必须更改x指向的数组,而不是为x赋值一个新数组。
    function foo(x){
    x.push(4);
    console.log('x',x);
    x.length = 0;   // 清空数组
    x.push(4,5,6,7);
    console.log('x',x);
    }
    
    var a = [1,2,3];
    foo(a);
    console.log('a',a)
     // x [ 1, 2, 3, 4 ]
    // x [ 4, 5, 6, 7 ]
    // a [ 4, 5, 6, 7 ]
    

原生函数

  • 常见原生函数

    • String()
    • Number()
    • Boolean()
    • Array()
    • Object()
    • Function()
    • RegExp()
    • Date()
    • Error()
    • Symbol()
  • 原生函数可以被当作构造函数使用(创建出封装了基本类型值的封装对象)

  • 浏览器已经为.length这样的常见情况做了性能优化,直接使用封装对象反而会降低执行效率

  • 如果想得到封装对象中的基本类型值,可以使用valueOf()函数

var a = new String("abc");
a.valueOf();    //  "abc"
  • Array

    • 构造函数Array不要求带new关键字
    • Array构造函数只带一个数字参数的时候,被设为数组长度,而不是数组元素。
  • RegExp

    • 以常量形式(/^a*b+/g)来定义正则表达式,执行效率会更高,JS引擎会对他们进行预编译和缓存
    • 动态正则表达式可用RegExp()
  • Date()和Errof()

    • Date()[不加new] 与 getTime() 与 Date.now()即可得当前时间
    • Error() 常与throw一起使用
  • Symbol()

    • 不能使用new关键字
    • 没有搞明白这东西到底是干嘛的

强制类型转换

语法

  • 语句都有一个结果值

    • statement completion value, undefined也算
    • 控制台中输入var a = 2会得到结果值undefined
  • 标签语句

    • 下列语句中的contine foo 不是跳转到标签foo所在位置执行,而是执行foo循环的下一轮循环
    foo:for(var i =0; i<4; i++){
    for(var j=0; j<4; j++){
        if(j == i){
            continue foo;
        }
        if((j*i)%2 == 1){
            continue;
        }
        console.log(i,j)
    }
    

}
//
1 0
2 0
2 1
3 0
3 2
```

  • 代码块

    []+{}; // [object Object]
    {}+[]; //  0
    
  • 运算符优先级

    • && > ||
  • 自动分号

    • 自动分号插入
  • 提前使用变量

    • ES6中规范了一个新概念叫做TDZ(Temporal Dead Zone, 暂时性死区)
  • try throw ,finally ,catch

异步和性能

异步

  • console环境实际是由宿主环境决定
  • 事件循环

异步是现在和将来事件之间的间隙,并行意味着可以同时发生

回调

  • 纸牌屋心理:它可以工作,但我不知道为什么,所以谁也别碰他
    • 嵌套回调和链式回调

Promise

  • 未来值
    • 可能拒绝,也可能完成

生成器

  • 生成器是一类特殊的函数,可以一次或多次启动和停止,不一定非要完成。

程序性能

性能测试与调优

上一篇:2019.7.17 Business english training-Job interview preparation


下一篇:Simple, Poetic, Pithy