写在前面
本文主要为笔者对JS学习的总结,介绍原型、闭包和异步这三座JS大山,希望对大家有帮助哦~
一、原型和原型链
谈起原型和原型链我们要清楚一点:
JS是一门基于原型继承的语言。
那么,这里就要介绍一下继承了
1.1 class与继承
这里有一段代码:
// 父类 class People { constructor(name) { this.name = name } eat() { console.log(`${this.name}eat something~`) } } // 子类(学生) class Student extends People { constructor(name, number) { super(name) this.number = number } sayHi() { console.log(`你好,我是${this.name},我的学号是${this.number}`) } } // 子类(老师) class Teacher extends People { constructor(name, major) { super(name) this.major = major } teach() { console.log(`我是${this.name},我教授的学科是${this.major}`) } } let xialuo = new Student("夏洛", 100) let wanglaoshi = new Teacher("王老师", "数学") console.log(xialuo.name) console.log(wanglaoshi.name) xialuo.sayHi() wanglaoshi.teach() wanglaoshi.eat() 复制代码
运行结果:
console.log(typeof People) // function console.log(typeof Student) // function 复制代码
class实际上是一个函数,它是一个语法糖 再看下面这段代码运行结果:
console.log(xialuo.__proto__) // People{} console.log(Student.prototype) // People{} console.log(xialuo.__proto__ === Student.prototype) // true 复制代码
由此引出了我们的主角:
- 隐式原型:_proto_
- 显式原型:prototype
1.2 原型关系
- 每个class都有显示原型prototype
- 每个实例都有隐式原型__proto__
- 实例的__proto__指向对应class的prototype
1.3 基于原型的执行规则
- 获取属性xialuo.name或执行方法xialuo.sayHi()时
- 先在自身属性和方法寻找
- 如果找不到则自动去__proto__中去查找
1.4 原型链
console.log(Student.__proto__ === People.prototype) // true 复制代码
二、作用域与闭包
2.1 作用域
作用域就是一个变量合法的使用范围
作用域分为
- 全局作用域
- 函数作用域
- 块级作用域(【大括号】ES6新增)
2.2 自由变量
- 一个变量在当前作用域没有定义,但被使用了
- 向上级作用域,一层一层依次寻找,直至找到为止
- 如果到全局作用域都没找到,则报错xx is not defined
2.3 闭包
有两种情况:
- 函数作为返回值
- 函数作为参数
2.4 this
this的取值是在函数执行的时候确定的,不是在定义的时候确定的!
调用的几种方式
- 作为普通函数
- 使用call apply bind调用
- 作为对象方法被调用
- 在class方法中调用
- 箭头函数(箭头函数的this始终指向函数定义时的this,而非执行时)
2.5 作用域相关面试题
this的不同应用场景,如何取值?
- 作为普通函数
- 使用call apply bind调用
- 作为对象方法被调用
- 在class方法中调用
- 箭头函数(箭头函数的this始终指向函数定义时的this,而非执行时)
手写bind函数
实际开发中闭包的应用场景
隐藏数据
比如做一个简单的cache工具
创建10个a标签,点击每个a标签,弹出对应序号
三、 异步与单线程
3.1 异步
- JS是单线程语言,只能同时做一件事儿
- 浏览器和node.js已支持JS启动进程,如Web Worker
- JS和DOM渲染公用同一个线程,因为JS可修改DOM结构
- 异步不会阻塞代码执行
- 同步会阻塞代码执行
3.2 应用场景
- 网络请求,如ajax图片加载
- 定时任务,如setTimeout
3.3 Promise的基本使用
创建一个 Promise
const myPromise = new Promise((resolve,reject)=>{ }) 复制代码
通过resolve和reject完成Promise
const myPromise = new Promsie(()=>{ if(true){ resolve('Promise was fulfilled') }else{ reject('Promise was rejected') } }) 复制代码
用then和catch处理Promise完成的情况
myPromsie.then(result=>{ }).catch(err=>{ }) 复制代码
3.4 JS异步相关的面试题
异步和同步的区别是什么?
- 基于JS是单线程语言
- 异步不会阻塞代码执行
- 同步会阻塞代码执行
手写用Promise加载一张图片
最后
本文总结了JS的三座大山,帮助读者快速理解原型,闭包和异步的知识~
如果这篇文章对你有帮助的话,麻烦点赞收藏哟~
后期更文计划
- 异步进阶及event loop的那些事儿~
- Grid布局原理及实战
- vw和vh布局或许会成为新趋势?