曾经的纯JavaScript基础

如题这是曾经纯JavaScript基础,有些写法语法和最新得瑟ES6语法不适用了。留作纪念吧!
控制台输出内容  console.log("content");

数据类型:
    Number(整数,浮点数,NaN, Infinity)
    Boolean
    null表示一个"空"的值
    undefined表示"未定义"
    NaN === NaN; // false
    isNaN(NaN); // true

一定要使用静态模式
    在文件或者脚本的最上面写上'use strict'
    之后定义变量必须使用var关键字,如果忘记写var则会在控制台报ReferenceError错误
    创建对象的构造函数,在strict模式下this.name = name将报错因为this绑定为undefined在非strict模式下this.name = name不报错因为this绑定为window于是无意间创建了全局变量name并且返回undefined这个结果更糟糕
字符串可以用 `` 支持多行模式
    alert(`多行
    字符串
    测试`);
字符串常用
    s.length;
    s.toUpperCase();//大写
    s.toLowerCase();//小写
    s.indexOf("..");搜索指定字符串出现的位置
    s.substring(0, 5); // 从索引0开始到5(不包括5),返回'hello'
    s.substring(7); // 从索引7开始到结束,返回'world'
数组常用
    arr.length;
    arr.indexOf(value);元素 value 的索引位置
    arr.slice();//对应string的substring函数
    push('A', 'B')向Array的末尾添加若干元素
    arr.pop();//删除数组最后的元素并返回它
    arr.unshift('A', 'B');//往Array的头部添加若干元素
    arr.shift();//删除数组第一个元素并返回
    arr.sort();//数组排序,具体在函数部分
    arr.reverse();//反转数组
    arr.concat(arr2);//连接两个数组
    arr.join('-');//用-将数组连接起来成字符串

对象常用
obj.属性key = 属性value;
delete obj.属性key
'属性key' in ojb;//属性key是否在obj中,继承的也算
obj.hasOwnProperty('属性key');只判断属性key是否在当前对象中

for (var i in 可迭代集合)
for...of//可以循环数组,map,set)
    for(var x of a)
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, 被迭代对象) {
    // element: 指向当前元素的值
    // index: 指向当前索引
    // 被迭代对象: 被迭代对象本身
    alert(element);
});


map--键值存储
m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);//初始化一个map
m.set('Adam', 67);
m.has('Adam');
m.get('Adam');
m.delete('Adam');

set--不重复集合
var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
s.add(4)
s.delete(3);

函数
    arguments关键字,收集函数的所有参数到数组(这是隐藏的可以直接使用)
    rest关键字定义变量可以 function foo(a,b, ...rest)
        除了前两个参数,后面的存在rest数组中
    apply
        函数名.apply(被绑定对象, 函数参数)//这样使用时在函数体内的this关键字都是指向"被绑定对象"
    call -- 与apply区别
    apply()把参数打包成Array再传入
    call()把参数按顺序传入
    Math.max.apply(null, [3, 5, 4]); // 5
    Math.max.call(null, 3, 5, 4); // 5
    map() reduce()
    filter(匿名函数)//过滤,根据匿名函数返回Boolean值决定是否保留
    排序函数sort(),原则是按照(规定对于两个元素x和y如果认为x < y则返回-1如果认为x == y则返回0如果认为x > y则返回1这样排序算法就不用关心具体的比较过程而是根据比较结果直接排序),并且会修改原数组
        数字从小到大排序//从大到小
        arr.sort(function (x, y) {
            if (x < y) {
                return -1;//return 1
            }
            if (x > y) {
                return 1;//return -1
            }
            return 0;
        });
        //对字符串数组排序(按照ASCII的小到大)
        arr.sort(function (s1, s2) {
            x1 = s1.toUpperCase();
            x2 = s2.toUpperCase();
            if (x1 < x2) {
                return -1;
            }
            if (x1 > x2) {
                return 1;
            }
            return 0;
        });
    闭包
    箭头函数(相当于匿名函数)//还是用匿名函数吧

作用域
使用一个全局变量推荐 window.变量
自己写代码推荐使用一个名字空间(就是建立一个对象,自己的变量都当做对象属性操作)
申明一个块级变量用let
申请一个常量const PI = 3.14;//不可修改

生成器function* fib(参数) {}
    js引擎遇到yield就会停止并返回yield后值,并保持函数执行的所有状态,下次调用从上次yield的后面接着执行
调用生成器
    
    var f = fib(5);
    f.next(); 
    f.next(); 
    f.next(); 
    f.next(); 
    f.next(); 
    
    for (var x of fib(5)) {
        console.log(x); // 依次输出0, 1, 1, 2, 3
    }

js标准对象
typeof 123; // 'number'
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {}; // 'object'
总结一下有这么几条规则需要遵守

    不要使用new Number()new Boolean()new String()创建包装对象
    用parseInt()或parseFloat()来转换任意类型到number
    用String()来转换任意类型到string或者直接调用某个对象的toString()方法
    通常不必把任意类型转换为boolean再判断因为可以直接写if (myVar) {...}
    typeof操作符可以判断出numberbooleanstringfunction和undefined
    判断Array要使用Array.isArray(arr)
    判断null请使用myVar === null
    判断某个全局变量是否存在用typeof window.myVar === 'undefined'
    函数内部判断某个变量是否存在用typeof myVar === 'undefined'
    null和undefined没有toString()方法
    number使用toString()(123).toString();


JSON
var xiaoming = {
    name: '小明',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp']
};
JSON.stringify(xiaoming); // '{"name":"小明","age":14,"gender":true,"height":1.65,"grade":null,"middle-school":"\"W3C\" Middle School","skills":["JavaScript","Java","Python","Lisp"]}'
JSON.stringify(xiaoming, null, '  ');
{
  "name": "小明",
  "age": 14,
  "gender": true,
  "height": 1.65,
  "grade": null,
  "middle-school": "\"W3C\" Middle School",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}
JSON.stringify(xiaoming, ['name', 'skills'], '  ');
{
  "name": "小明",
  "skills": [
    "JavaScript",
    "Java",
    "Python",
    "Lisp"
  ]
}
JSON.stringify(xiaoming, convert, '  ');//每个键值都会被convert函数处理
function convert(key, value) {
    if (typeof value === 'string') {
        return value.toUpperCase();
    }
    return value;
}
在对象中重写toJSON
var xiaoming = {
    name: '小明',
    age: 14,
    gender: true,
    height: 1.65,
    grade: null,
    'middle-school': '\"W3C\" Middle School',
    skills: ['JavaScript', 'Java', 'Python', 'Lisp'],
    toJSON: function () {
        return { // 只输出name和age,并且改变了key:
            'Name': this.name,
            'Age': this.age
        };
    }
};

JSON.stringify(xiaoming); // '{"Name":"小明","Age":14}'

反序列化json
JSON.parse('json字符串')
JSON.parse('json字符串', function(key, value){
    //pass
});


js使用classs构建对象
class Student extends 父类{
    //构造函数
    constructor(name) {
        super(name); // 记得用super调用父类的构造方法!
        this.name = name;
    }

    hello() {
        alert('Hello, ' + this.name + '!');
    }
}