🍉学习JS不得不知的原型原型链、闭包和异步!

简介: 🍉学习JS不得不知的原型原型链、闭包和异步!

写在前面


本文主要为笔者对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()
复制代码


运行结果:


988b32a79b474d26bf414281109a89f7_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


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 原型关系


713cdeead7ab4de38c53d945cd63046d_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


  • 每个class都有显示原型prototype
  • 每个实例都有隐式原型__proto__
  • 实例的__proto__指向对应class的prototype


1.3 基于原型的执行规则


  • 获取属性xialuo.name或执行方法xialuo.sayHi()时
  • 先在自身属性和方法寻找
  • 如果找不到则自动去__proto__中去查找


1.4 原型链


console.log(Student.__proto__ === People.prototype) // true
复制代码


7d77aaf9fc394e0790e372dbcf89f4a6_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


二、作用域与闭包


2.1 作用域


作用域就是一个变量合法的使用范围


9725b1f50f5a4ab7943688f6875b74a1_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


作用域分为


  • 全局作用域
  • 函数作用域
  • 块级作用域(【大括号】ES6新增)


2.2 自由变量


  • 一个变量在当前作用域没有定义,但被使用了
  • 向上级作用域,一层一层依次寻找,直至找到为止
  • 如果到全局作用域都没找到,则报错xx is not defined


2.3 闭包


有两种情况:


  • 函数作为返回值
  • 函数作为参数

1a19181646cf43aab8d30ff1de52db5c_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


2.4 this


this的取值是在函数执行的时候确定的,不是在定义的时候确定的!


调用的几种方式


  • 作为普通函数
  • 使用call apply bind调用
  • 作为对象方法被调用
  • 在class方法中调用
  • 箭头函数(箭头函数的this始终指向函数定义时的this,而非执行时)

877c31f511664300b8e18b4aa2b2036e_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


2.5 作用域相关面试题

this的不同应用场景,如何取值?


  • 作为普通函数
  • 使用call apply bind调用
  • 作为对象方法被调用
  • 在class方法中调用
  • 箭头函数(箭头函数的this始终指向函数定义时的this,而非执行时)


手写bind函数


547f209c25874cf5a4caecf8f5ab76fb_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


实际开发中闭包的应用场景


隐藏数据


比如做一个简单的cache工具

da8ff91759714a3e9649c5263ebd8407_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


创建10个a标签,点击每个a标签,弹出对应序号


4095424d900748f8883482ae35adee9c_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


三、 异步与单线程



3.1 异步


  • JS是单线程语言,只能同时做一件事儿
  • 浏览器和node.js已支持JS启动进程,如Web Worker
  • JS和DOM渲染公用同一个线程,因为JS可修改DOM结构
  • 异步不会阻塞代码执行
  • 同步会阻塞代码执行


3.2 应用场景


  • 网络请求,如ajax图片加载
  • 定时任务,如setTimeout


04a7b6ce03a64aaebf928f38a776797b_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png

ae18124e7e7d469a8be85409db144f71_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


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加载一张图片


d301405035af4050948f8c1e5146ae92_tplv-k3u1fbpfcp-zoom-in-crop-mark_4536_0_0_0.png


最后


本文总结了JS的三座大山,帮助读者快速理解原型,闭包和异步的知识~

如果这篇文章对你有帮助的话,麻烦点赞收藏哟~


后期更文计划


  • 异步进阶及event loop的那些事儿~
  • Grid布局原理及实战
  • vw和vh布局或许会成为新趋势?
相关文章
|
29天前
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
5天前
|
JSON 前端开发 JavaScript
在 JavaScript 中,如何使用 Promise 处理异步操作?
通过以上方式,可以使用Promise来有效地处理各种异步操作,使异步代码更加清晰、易读和易于维护,避免了回调地狱的问题,提高了代码的质量和可维护性。
|
13天前
|
JavaScript 前端开发
js 闭包的优点和缺点
【10月更文挑战第27天】JavaScript闭包是一把双刃剑,在合理使用的情况下,它可以带来很多好处,如实现数据封装、记忆功能和模块化等;但如果不注意其缺点,如内存泄漏、变量共享和性能开销等问题,可能会导致代码出现难以调试的错误和性能问题。因此,在使用闭包时,需要谨慎权衡其优缺点,根据具体的应用场景合理地运用闭包。
103 58
|
7天前
|
JavaScript 前端开发
JavaScript 原型链的实现原理是什么?
JavaScript 原型链的实现原理是通过构造函数的`prototype`属性、对象的`__proto__`属性以及属性查找机制等相互配合,构建了一个从对象到`Object.prototype`的链式结构,实现了对象之间的继承、属性共享和动态扩展等功能,为 JavaScript 的面向对象编程提供了强大的支持。
|
7天前
|
JavaScript 前端开发
原型链在 JavaScript 中的作用是什么?
原型链是 JavaScript 中实现面向对象编程的重要机制之一,它为代码的组织、复用、扩展和多态性提供了强大的支持,使得 JavaScript 能够以简洁而灵活的方式构建复杂的应用程序。深入理解和熟练运用原型链,对于提升 JavaScript 编程能力和开发高质量的应用具有重要意义。
|
13天前
|
缓存 JavaScript 前端开发
js 闭包
【10月更文挑战第27天】JavaScript闭包是一种强大的特性,它可以用于实现数据隐藏、记忆和缓存等功能,但在使用时也需要注意内存泄漏和变量共享等问题,以确保代码的质量和性能。
32 7
|
9天前
|
JavaScript 前端开发
如何使用原型链继承实现 JavaScript 继承?
【10月更文挑战第22天】使用原型链继承可以实现JavaScript中的继承关系,但需要注意其共享性、查找效率以及参数传递等问题,根据具体的应用场景合理地选择和使用继承方式,以满足代码的复用性和可维护性要求。
|
16天前
|
自然语言处理 JavaScript 前端开发
JavaScript闭包:解锁编程潜能,释放你的创造力
【10月更文挑战第25天】本文深入探讨了JavaScript中的闭包,包括其基本概念、创建方法和实践应用。闭包允许函数访问其定义时的作用域链,常用于数据封装、函数柯里化和模块化编程。文章还提供了闭包的最佳实践,帮助读者更好地理解和使用这一强大特性。
11 2
|
19天前
|
JavaScript 前端开发 开发者
探索JavaScript原型链:深入理解与实战应用
【10月更文挑战第21天】探索JavaScript原型链:深入理解与实战应用
26 1
|
28天前
|
JavaScript 前端开发 开发者
深入理解JavaScript原型链:从基础到进阶
【10月更文挑战第13天】深入理解JavaScript原型链:从基础到进阶
19 0