JS概念梳理

201 阅读5分钟

名词释义

  • ECMA(European Computer Manufacturers Association)欧洲计算机制造商协会;ECMA International国际性会员制度的信息和电信标准组织;JavaScript由Netscape网景公司Brendan Eich发明。
  • ECMAScript是一种语言标准、规范,JavaScript是基于标准的实现。
  • JavaScript是一种直译式客户端脚本语言,是一种动态类型、弱类型、基于原型的语言,其解释器一般被称为JavaScript引擎。
  • JQuery是一个JavaScript函数库,是JavaScript中最流行的一种框架。
  • Node.js是一个基于Chrome V8引擎的JavaScript运行环境,即服务端语言。使用事件驱动、非阻塞式 I/O 的模型。是基于CommonJS规范的实现。无阻塞高并发。
  • CommonJS最初是服务于服务端的,它的载体是前端语言JavaScript,是一种标准规范。CommonJS规范的模块同步加载不适用于浏览器环境客户端(运行时确定依赖)。
  • AMD(Asynchronous Module Definition异步模块定义,是一种客户端异步方式加载模块的规范,避免浏览器因为服务端的等待处于"假死"状态,(回调执行,运行时确定依赖)。
  • CMD推崇依赖就近,AMD推崇依赖前置,(回调执行,运行时确定依赖)。
// AMD vs CMD
// CMD
define(function(require, exports, module) {
    var m1 = require('./m1')
    m1.doSomething...
    var m2 = require('/m2')
    b.doSomething...
})
//AMD
define(['/m1','./m2'], function(m1, m2) {
    m1.doSomething...
    m2.doSomething...
})
  • ES6模块化采用静态编译,编译时确定模块依赖关系,不支持动态导入require。

JS基础

  1. this指向:永远指向对象。一般函数中this指的是全局对象Window对象;对象方法调用中,this指上级对象;作为构造函数使用,this指向实例化的对象;apply、call、bind改变函数的调用对象,此方法的第一个参数为改变后调用这个函数的对象;匿名函数的执行this通常指向Window对象;
var obj = {
    luckyNum: 666,
    fun: function() {
        return this.luckyNum
    }
}
console.log(obj.fun) // function native code
let t = obj.fun // 纯function代码 this指向全局变量Window对象
console.log(t()) // undefined
console.log(obj.fun()) // 666
// 匿名函数示例
var name = 'The Window';
var obj = {
    name: 'My obj',
    getName: function() {
        return function() {
            console.log(this.name);
        };
    }
};
obj.getName()(); // 'The Window'
// Ps: 匿名函数在函数里,this指向当前匿名函数
  1. 匿名函数 例function(){return 666;},单独无法执行,可通过表达式自我执行(function(){return 666;})();或赋值给变量执行var lucky = function(){return 666;};lucky();//调用;或把自我执行的返回值赋值给变量;匿名传参:(function(param) {return param;})(666);;
// 结合this的示例
function fun(x,y) {
    console.log(y);
    return {
        fun: function(m) {
            return fun(m, x);
        }
    }
}
let a = fun(0) // a: fun: function(m) {return fun(m, x);}
a.fun(1) // y=0
a.fun(2) // y=0
a.fun(3) // y=0
fun(0).fun(1).fun(2).fun(3) // y=2
  1. 闭包函数 有权访问另一个函数作用域里变量的函数
    在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量
    由于闭包里作用域返回的局部变量资源不会被立刻撤销回收,所以可能会占用过多内存,过度使用将导致性能下降,建议在必要时才使用
// 函数里放一个匿名函数形成闭包
function mm(){
    return function(){
        return 'mm';
    }
}
box()() // 'mm'

HTTP交互请求

  • XHR是浏览器API,简化异步通信过程,XHR对象提供HTTP协议的完全访问,包括POST GET等,以文本或DOM文档形式返回。Content-type: application/json
var xhr = new XMLHttpRequest();
// 示例1 GET
xhr.open('GET', '/img.jpg', true);
xhr.responseType = 'blob';
xhr.onload = function() {
    if (this.status == 200) {
        img.src = window.URL.createObjectURL(this.response);
        img.onload = function() {
            window.URL.revokeObjectURL(this.src);
        }
        // doSomething about img
    }
}
xhr.send();
// 示例2 POST
var formData = { action: 'testPostFormData', purpose: 'validate'}
xhr.open('POST', '/upload', true);
xhr.onload = function() { ... };
xhr.send(formData);
// 示例2 POST 分段上传
var blob = ...;
const BYTES_PER_CHUNK = 1024 * 1024;
const SIZE = blob.size;
var start = 0;
var end = BYTES_PER_CHUNK;
while(start < SIZE) {
  xhr.open('POST', '/upload', true);
  xhr.onload = function() { // doSomething };
  xhr.setRequestHeader('Content-Range', start+'-'+end+'/'+SIZE);
  xhr.send(blob.slice(start, end));
  start = end;
  end = start + BYTES_PER_CHUNK;
}
  • Ajax指的是XMLHttpRequest(XHR),多用于原始js中,多个请求易出现回调地狱。JQueryAjax再次封装,增加JSONP支持,主要针对MVC,不符合MVVM。
  • Fetch脱离XHR,基于Promise设计的原生Js,类似于原生XHR。
  • MVVM(Model-View-ViewModel)模式,ViewModel是一个中转站,与View视图层进行双向数据绑定,与Model层通过接口请求进行数据交互,转换Model中数据对象,解藕View与Model。
  • Axios是Ajax技术的一种封装实现,基于Promise的HTTP库,符合ES规范,多用于浏览器或Node.js为服务端的HTTP客户端,从浏览器中创建XMLHttpRequest。
let baseUrl = 'http://xxx'
const get = (url, params)=>{
    params = params || {};
    return new Promise((resolve, reject)=>{
        // axiso 自带 get 和 post 方法
        axios.create({ baseURL }).get(url,{ params}).then(res=>{
            if(res.data.status===0){
                resolve(res);
            }else{
                console.log(res.msg)
            }
        }).catch(error=>{
            console.log(error)
        })
    })
}
// 参考官网 http://www.axios-js.com/zh-cn/docs/#请求配置
  • Promise替代Ajax执行回调的异步执行一个可链式调用对象,避免回调地狱。

Promise

定义:Promise对象表示一个异步操作的最终完成 (或失败)及其结果值,本质上是一个函数返回的对象
几种状态:待定(pending)、已兑现(fulfilled)、已拒绝(rejected)
链式调用:promise.then(),promise.catch() 和 promise.finally()

  • resolve更新Promise对象状态从pending->fulfilled,异步操作成功时调用,并将预设结果作为参数传递出去
  • reject更新Promise对象状态pending->rejected,异步操作失败时调用,并将失败错误作为参数传递出去
// my first promise
const myPromise = new Promise((resolve, reject) => {
    setTimeout(function(){
        resolve({ code: 200, data: 'Success', msg: 'call api success!' })
        console.log('First!')
    }, 300)
}).then(res =>{
    console.log(res)
    throw new Error('First 404 Error!')
})
.catch((error) => {
    console.log(error)
})

  • Promise.all:所有的promise对象都成功的时候才会触发成功,一旦有任何一个promise对象失败则立即触发该promise对象的失败。
Promise.all([
  Promise.resolve(1),
  Promise.reject(2),
  Promise.resolve(3)
]).then(res => {
    console.log('res: ', res)
}).catch(err => {
    console.error('err: ', err)
});
// 输出 err: 2
  • Promise.allSettled:在所有promise完成后完成。并带有一个对象数组,每个对象对应每个promise的结果。
Promise.allSettled([
  Promise.resolve(1),
  Promise.reject(2),
  Promise.resolve(3)
]).then(res => {
    console.log('res: ', res)
}).catch(err => {
    console.error('err: ', err)
});

输出结果: image.png

  • Promise.race:任意一个子promise被成功或失败后,返回该promise对象。
Promise.race([
  Promise.resolve(1),
  Promise.reject(2),
  Promise.resolve(3)
]).then(res => {
    console.log('res: ', res)
}).catch(err => {
    console.error('err: ', err)
});
// 输出 res:  1
  • Promise.any: 接收一个Promise对象的集合,当其中的一个 promise 成功,就返回那个成功的promise的值。
Promise.any([
  Promise.reject(1),
  Promise.resolve(2)
]).then(res => {
    console.log('res: ', res)
}).catch(err => {
    console.error('err: ', err)
});
// 输出 res:  2

async/await

// ES2017 async/await语法糖
async function potato() {
  try {
    const result = await doSomething();
    const newResult = await doSomethingElse(result);
    const finalResult = await doThirdThing(newResult);
    console.log(`Got the final result: ${finalResult}`);
  } catch(error) {
    failureCallback(error);
  }
}
/**
* ---------------
* 以分批处理请求为例
* ---------------
*/
const taskList = []
for (let y = 0; y < 10; y++) {
    const asyncTask = (y) => {
        return new Promise((resolve) => {
            // 向后端发起API http请求
            api(param).then(res => {
                // 将后端反馈结果作为参数传递出去
                resolve(res)
            }).catch(error => {
                // 根据实际需求处理抛错
                console.log(error)
            })
        })
    }
    taskList.push(asyncTask(y))
}
// .all 有点类似后端事务处理机制
Promise.all(taskList).then(res => {
    console.log(res)
})

根据实际应用场景采用合适的Promise的静态方法。

ECMAScript时间史

journey
title ES时间轴
section 1998年6月
ECMAScript 2.0 : 5: ES2
section 1999年12月
ECMAScript 3.0 : 5: ES3
section 2009年12月
ECMAScript5.0(ES5): 5: ES5
section 2015年6月17日
ECMAScript6(ES2015): 5: ES6
section 2021年
ES2021 Stage 4 : -4: ES12