ES6(ECMAScript 2015) 原生提供了 Promise 对象。 Promise 是异步编程的一种解决方法,比传统的回调函数和事件更合理更强大,Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。// Promise 新建后立即执行,所以首先输出的是Promise。然后,then方法指定的回调函数,将在当前脚本所有同步任务执行完才会执行,所以resolved最后输出。 let promise = new Promise(function (resolve, reject) { console.log('Promise'); // Promise resolve(); }); promise.then(function () { console.log('resolved.'); // resolved. }); console.log('Hi!'); // Promise // Hi! // resolved.1.Promise 的三种状态funct
1.前言JavaScript单线程语言,为了实现主线程的不阻塞,Event Loop这样的方案应运而生,Event Loop 就是异步回调的实现原理。2.JS的执行机制从前往后一行一行执行,如有报错后面代码停止执行先执行完成同步代码再执行异步代码3.Event Loop 执行过程console.log('hi'); setTimeout(function cb1() { console.log('cb1'); }, 5000); console.log('bye'); //先执行同步 //hi //bye //等待5秒后 //cb1同步代码(栈里面的代码)顺序执行,遇到异步代码就记录一下,在此过程中异步代码如果是宏任务移动到Web APIs,直到定时的时间到就放入宏任务队列,即图中的Callback Queue。如果是微任务则放入微任务队列(本例子没有微任务),不会经过Web APIs。如果同步代码执行完,调用栈call stack为空,去查看微任务队列,每执行完一个微任务,它就会从微任务队列出队,直到微任务队列微空后,尝试DOM渲染(如果DOM结构发生变化)。然后Event
1.同步和异步JS是单线程语言,只能同时处理一件事浏览器和nodejs支持js启动进程,如Web WorkerJS和DOM渲染共用一个线程,因为JS可以修改DOM遇到等待 (网络请求、 定时任务) 不能阻塞异步的目的是为了解决单线程存在等待的问题,是基于JS是单线程的本质,以callback函数形式来调用,不会阻塞代码执行。2.异步的应用场景网络请求(Ajax)定时任务(setTimeout)3.CallBack Hell(回调炼狱) 使用Promise解决
bind 的用法bind 和 call/apply 一样,都是用来改变上下文 this 指向的,不同的是,call/apply 是直接使用在函数上,而 bind 绑定 this 后返回一个函数(闭包),如下:let obj = { init: 1, add: function(a, b) { return a + b + this.init; } } obj.add(1, 2); // 4 let plus = obj.add; plus(3, 4); // NaN,因为 this.init 不存在,这里的 this 指向 window/global plus.call(obj, 3, 4) // 8 plus.apply(obj, [3, 4]); // 8, apply 和 call 的区别就是第二个参数为数组 plus.bind(obj, 3, 4); // 返回一个函数,这里就是 bind 和 call/apply 的区别之一,bind 的时候不会立即执行 plus.bind(obj, 3, 4)(); // 8 bind 的简单实现/
作为普通函数function fn1() { console.log(this); } fn1(); // window使用call、bind、apply 调用function fn1() { console.log(this); } fn1.call({ name: 'zhangsan' }); // {name: 'zhangsan'} const fn2 = fn1.bind({ name: 'lisi' }); fn2(); // {name: 'lisi'函数的bind是返回一个新的函数作为对象方法调用const fn1 = { name: 'gonwe', sayName() { console.log(this); // {name: 'gonwe'} }, wait() { setTimeout(function () { console.log(this); // window }); } }在箭头函数调用const fn2 = {
JS基础 - 作用域和闭包1.作用域作用域:一个变量的合法使用范围全局作用域直接编写在script标签之中或者是一个单独的js文件中的js代码,都是全局作用域。全局作用域在页面打开时创建,页面关闭时销毁;在全局作用域中有一个全局对象window (代表的是一个浏览器的窗口,有浏览器创建),可以直接使用。所有创建的变量都会作为window对象的属性保存。所有创建的函数都会作为window 对象的方法保存。//在任何地方都可以访问到的变量就是全局变量,对应全局作用域 console.log(this) window函数作用域 (局部作用域)在函数内部就是局部作用域,这个代码的名字只在函数的内部起作用调用函数是创建函数作用域,函数执行完毕之后,函数作用域就销毁;每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的。块级作用域(ES6 新增)//ES6 块级作用域 if (true) { let x = 100 } console.log(x) // Uncaught ReferenceError: x is not defined //只要使用 let 或者 const
如何理解 JS 原型和原型链(隐式原型和显示原型)1.原型ES6中的 class 是一个语法糖,class实际上是一个函数。// 父类(基类) class People { constructor(name, age) { this.name = name; this.age = age; } sayName() { console.log(this.name); } } // 子类使用 extends 关键字 实现继承 class Programmer extends People { constructor(name, type) { // super() 调用父类的构造函数 super(name); this.type = type; } code() { console.log(`${this.name} is 正在写代码`); } job() { console.log(`${
class JQuery { constructor(selector) { const dom = document.querySelectorAll(selector); for (let i = 0; i < dom.length; i++) { this[i] = dom[i]; } this.length = dom.length; this.selector = selector; } each(fn) { for (let i = 0; i < this.length; i++) { fn(this[i], i); } } get(index) { return this[index]; } on(eventName, fn) { this.each(function (item) { ite
1.ClassES6提供了更接近面向对象(注意:javascript本质上是基于对象的语言)语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。 基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。class Programmer { constructor(name, type) { this.name = name; this.type = type; } code() { console.log(`${this.name} is 正在写代码`); } job() { console.log(`${this.name} is ${this.type}`); } } const John = new Programmer('John', '前端工程师'); console.log(John.name); // John c
Gonwe
一念智即般若生。
CC BY-SA 4.0