Skip to content

Latest commit

 

History

History
356 lines (279 loc) · 27 KB

各种区别.md

File metadata and controls

356 lines (279 loc) · 27 KB

各种区别

箭头函数和普通函数的区别

  • 箭头函数和普通函数的写法不同
    • 箭头函数语法更加简洁、清晰,是 => 定义函数,但不能写成generator形式。
    • 普通函数是function定义函数,可以定义成generator: function* ()。
  • 箭头函数会捕获其所在上下文的 this 值,作为自己的 this 值,定义的时候就确定并固定了。call、apply、bind 并不会影响其 this 的指向。
  • 箭头函数不能作为构造函数使用,也不能使用new关键字(因为箭头函数没有自己的this,它的this其实是继承了外层执行环境中的this,且this指向永远不会改变,作为构造函数其的this要是指向创建的新对象)。
  • 箭头函数没有自己的arguments。在箭头函数中访问arguments实际上获得的是外层局部(函数)执行环境中的值。
  • 箭头函数没有原型prototype。

var,let和const之间的区别

变量提升方面:

  • var声明的变量存在变量提升,即变量可以在声明之前调用,值为undefined。
  • let和const不存在变量提升问题(注意这个‘问题’后缀,其实是有提升的,只不过是let和const具有一个暂时性死区的概念,即没有到其赋值时,之前就不能用),即它们所声明的变量一定要在声明后使用,否则报错。

块级作用域方面:

  • var不存在块级作用域
  • let和const存在块级作用域

声明方面:

  • var允许重复声明变量
  • let和const在同一作用域不允许重复声明变量。其中const声明一个只读的常量(因为如此,其声明时就一定要赋值,不然报错)。一旦声明,常量的值就不能改变。

如何使const声明的对象内属性不可变,只可读?

如果const声明了一个对象,对象里的属性是可以改变的。因为const声明的obj只是保存着其对象的引用地址,只要地址不变,就不会出错。

使用Object.freeze(obj) 冻结obj,就能使其内的属性不可变,但它有局限,就是obj对象中要是有属性是对象,该对象内属性还能改变,要全不可变,就需要使用递归等方式一层一层全部冻结。

Bigint和Number的区别

Number类型的数字有精度限制,数值的精度只能到 53 个二进制位(相当于 16 个十进制位, 正负9007199254740992),大于这个范围的整数,就无法精确表示了。

Bigint没有位数的限制,任何位数的整数都可以精确表示。但是其只能用于表示整数,且为了与Number进行区分,BigInt 类型的数据必须添加后缀n。BigInt 可以使用负号(-),但是不能使用正号(+)。

另外number类型的数字和Bigint类型的数字不能混合计算。

12n+12; //报错

基本数据类型和引用数据类型的区别

基本数据类型:

  • 基本数据类型的值是不可变的(重新赋值属于改变属性名的指向了,而不是对值进行操作)。
  • 基本数据类型不可以添加属性和方法,虽然不会报错,但也只是一瞬间转为了相应包装对象,操作完又转化回原基本数据类型,不会保存结果。
  • 基本数据类型的赋值是简单赋值,比较是值的比较。
  • 基本数据类型是存放在栈区的

引用数据类型:

  • 引用类型的值是可以改变的,例如对象就可以通过修改对象属性值更改对象。
  • 引用类型可以添加属性和方法。
  • 引用类型的赋值是对象引用,即声明的变量标识符,存储的只是对象的指针地址,比较是引用(指针地址)的比较
  • 引用类型是同时保存在栈区和堆区中的,栈区保存变量标识符和指向堆内存的地址。

BTW所有关于字符串和数字(基本数据类型)的方法都是带有返回值的,而不是改变原字符串或数字。

let a='abc';
a.split('');
console.log(a);   //abc (没变)

defer和async的区别

JavaScript代码可能会修改DOM树的结构,所以DOM树解析过程中如果节点是JavaScript代码,就需要停止当前DOM树的创建,直到JavaScript的资源加载并被JavaScript引擎执行后才继续DOM树的创建。这里就会产生阻塞,出现白屏问题。defer和async都可以用来解决JavaScript脚本阻塞问题。还有一种办法是把script标签放置在body的底部,好处是没有兼容性问题。

defer(延迟)。浏览器立即下载,但延迟执行,跟把script脚本放在body底部差不多。第一个延迟脚本会先于第二个延迟脚本执行,所以执行脚本之间存在依赖,需要有执行的先后顺序时,就可以使用defer。

async(异步),浏览器也会立即下载文件。但与defer不同的是,async脚本并不保证按照它们的先后顺序执行。适用于互不依赖的各脚本。

async await对比promise的优缺点

async/await优点:

  • 是很好的语法糖,用同步代码的写法写异步代码,代码阅读相对容易。处理复杂流程时,在代码清晰度方面有优势。
  • 对于条件语句和其他流程语句比较友好,可以直接写到判断条件里面
if (await fn() === 222) {}

**async/await缺点: **- 无法处理promise返回的reject对象,要借助try catch

  • 在可以平行处理的异步请求时,还是promise比较方便,因为 await 会阻塞代码,也许之后的异步代码并不依赖于前者,但仍然需要等待前者完成
  • try catch内部的变量无法传递给下一个try catch。Promise和then/catch内部定义的变量,能通过then链条的参数传递到下一个then/catch,但是async/await的try内部的变量,如果用let和const定义则无法传递到下一个try catch,只能在外层作用域先定义好。

promise的一些问题:

  • 一旦执行,无法中途取消,链式调用多个then中间不能随便跳出来
  • 错误无法在外部被捕捉到,只能在内部进行预判处理,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
  • Promise内部如何执行,监测起来很难,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)

get和post的区别

传值方式:

  • GET通过地址栏来传值,将参数写在 URL 中 ? 的后面,并用 & 分隔不同参数。使用Request.QueryString来取得变量的值
  • POST是通过提交表单来传值,将信息存放在 Message Body 中传送,参数‘不会’显示在 URL 中(Restful规范中是这样,但post在有需要时可以把参数放URL里)。通过Request.Form来获取变量的值。

长度限制:

  • GET 通过 url 传参,浏览器会限制 url 的长度(http不会)。
  • POST请求没有内容长度限制。

缓存:

  • GET请求返回的内容会被浏览器缓存起来。
  • 浏览器不会缓存POST请求返回的内容,除非手动设置

编码方式:

  • GET 请求只能进行 url 编码
  • POST 支持多种编码方式。

用途:

  • GET对数据进行查询(读)
  • POST主要对数据进行增删改(写)

幂等性(幂等表示执行相同的操作,结果也是相同的):

  • GET是幂等的
  • POST不是

安全性: GET 请求方式从浏览器的 URL 地址就可以看到参数;所以post更安全。

其实无论是 GET 还是 POST 其实都是不安全的,因为 HTTP 协议是明文传输,只要拦截封包便能轻易获取重要资讯。想要安全传输资料,必须使用 SSL/TLS来加密封包,也就是 HTTPS。

那为什么推崇使用post来处理敏感数据呢?

  • get的记录会保存在浏览器,上网日志中
  • Post的数据不会记录存储在浏览器的记录和网址访问记录中,这样会有更大的安全性。

一个误区:GET产生一个TCP数据包;POST产生两个TCP数据包。其说法是:

  • 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务端响应200,请求成功。
  • 对于POST方式的请求,浏览器会先发送http header给服务端,告诉服务端等一下会有数据过来,服务端响应100 continue,告诉浏览器我已经准备接收数据,浏览器再post发送一个data给服务端,服务端响应200,请求成功。

为其正名:上面所说的post会比get多一个tcp包其实不太严谨。多发的那个expect 100 continue header报文,是由客户端对http的post和get的请求策略决定的,目的是为了避免浪费资源,如带宽,数据传输消耗的时间等等。所以客户端会在发送header的时候添加expect 100去探探路,如果失败了就不用继续发送data,从而减少了资源的浪费。所以是否再发送一个包取决了客户端的实现策略,和get/post并没什么关系。有的客户端比如fireFox就只发送一个包。

用框架和不用框架的区别

使用框架好处:

  • 使用框架工具写项目,在浏览器中代码依然是原生的HTML CSS JS。而框架帮开发者做了很多事情,开发者只关注业务逻辑就可以,极大的加快了开发速度。前端框架根本上是解决了UI 与状态同步问题,频繁操作 DOM 性能低下.中间步骤过多,易产生 bug且不易维护,而且心智要求较高不利于开发效率的一系列阻碍
  • 组件化: 其中以 React 的组件化最为彻底,甚至可以到函数级别的原子组件,高度的组件化可以是我们的工程易于维护、易于组合拓展。
  • 天然分层: JQuery 时代的代码大部分情况下是面条代码,耦合严重,现代框架不管是 MVC、MVP还是MVVM 模式都能帮助我们进行分层,代码解耦更易于读写。
  • 生态: 现在主流前端框架都自带生态,不管是数据流管理架构还是 UI 库都有成熟的解决方案

框架缺点:

  • 代码臃肿,使用者使用框架的时候会将整个框架引入,而框架封装了很多功能和组件,使用者必须按照它的规则使用,而实际开发中很多功能和组件是用不到的。
  • 框架迭代更新速度非常快,需要时间熟悉它。上手需要一定成本。

Vue和React的区别

相似之处

  • 都使用了Virtual DOM(虚拟DOM)提高重绘性能
  • 都有props的概念,允许组件间的数据传递
  • 都鼓励组件化应用,将应用分拆成一个个功能明确的模块,提高复用性
  • 都有自己的构建工具,能让你得到一个根据最佳实践设置的项目模板。

思想差异和数据流 react整体是函数式的思想,把组件设计成纯组件,状态和逻辑通过参数传入,所以在react中,是单向数据流 vue的思想是响应式的,也就是基于是数据可变的,通过对每一个属性建立Watcher来监听,当属性变化的时候,响应式的更新对应的虚拟dom。

模板和jsx

  • Vue鼓励写近似常规HTML的模板。写起来很接近标准 HTML元素,只是多了一些属性。
  • React推荐你所有的模板通用JavaScript的语法扩展——JSX书写。

jsx更强大,能想怎么写就怎么写,但是缺点就是无法静态编译优化。模板可以静态编译优化,比如提升父节点,在编译阶段就知道了哪些元素肯定不会重新渲染。所以react就在运行时的优化做到极致,引入了fiber。

react虽然不能静态编译,但是能通过手动优化达到类似的效果,比如用memo和shouldComponentUpdate。我更喜欢这样的让开发者有更大控制权的模式,在写react的过程中也对这些优化有了更深的理解。

拓展来讲,像react-router,react-redux都是社区中很优秀的库,然后集成到react身上。我非常喜欢这样的模式,就是我本身是一个包含最少东西的库,但是有着很好可拓展性,让工具,插件,库来完善我的功能,而不是一开始就全部自带。类似的例子有:

  • redux本身是很简洁的,连异步处理的能力都没有。但是给了一个enhancer的接口,通过可拓展性来拓展功能。
  • 类组件就是集成,耦合的(vue)。函数组件(react) + hook(各种生态)就是自由了,可拓展的,解耦的。
  • polkadot

拓展
react可以通过高阶组件HOC来扩展,而vue需要通过mixins来扩展。

原因高阶组件就是高阶函数,而React的组件本身就是纯粹的函数,所以高阶函数对React来说易如反掌。相反Vue.js使用HTML模板创建视图组件,这时模板无法有效的编译,因此Vue不采用HOC来实现。

cookies和session的区别

存储位置:

  • cookie的数据信息存放在客户端浏览器上
  • session的数据信息存放在服务器上。

存储容量:

  • 单个cookie保存的数据<=4KB,一个站点最多保存20个Cookie
  • session存储并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制。

存储方式:

  • cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。
  • session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。

隐私策略:

  • cookie对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的
  • session存储在服务器上,对客户端是透明的,不存在敏感信息泄漏的风险。

有效期:

  • 开发可以通过设置cookie的属性,达到使cookie长期有效的效果。
  • session依赖于名为JSESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。

服务器压力不同:

  • cookie保管在客户端,不占用服务器资源。对于并发用户十分多的网站,cookie是很好的选择。
  • session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。

跨域支持

  • :cookie支持跨域名访问(不是跨域,是跨域名,二级域名是可以共享cookie的)。
  • session不支持跨域名访问。

localstorage、sessionstorage、cookie的区别

  • 相同点是都是保存在浏览器端、且同源的
  • cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
  • 存储大小限制:
    • cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。
    • sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
  • 数据有效期不同:
    • sessionStorage:仅在当前浏览器窗口关闭之前有效;
    • localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;
    • cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
  • 作用域不同:
    • sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;
    • localstorage和cookie也是在所有同源窗口中都是共享的
  • webStorage(webstorage是本地存储,存储在客户端,包括localStorage和sessionStorage)支持事件通知机制,可以将数据更新的通知发送给监听者
  • webStorage的api接口使用更方便

宏任务和微任务有什么区别

这个不结合event loop很难讲清楚

fetch,Ajax,axios区别

Ajax是什么:Ajax是(Asynchronous JavaScript and XML)的缩写。现在,允许浏览器与服务器通信而无须刷新当前页面的技术都被叫做Ajax。核心使用XMLHttpRequest对象。

axios是什么:axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本,符合最新的ES规范。

fetch是什么:Fetch被称为下一代Ajax技术,采用Promise方式来处理数据。是一种简洁明了的API,比XMLHttpRequest更加简单易用。

主要区别是 axios、fetch请求后都支持Promise对象API,ajax只能用回调函数。

TCP和UDP的区别

  • TCP 是面向连接的,UDP 是无连接的即发送数据前不需要先建立链接。
  • TCP 是面向连接的可靠性传输,而 UDP 是不可靠的。通过 TCP 连接传送的数据,无差错,不丢失,不重复,且按序到达; UDP 尽最大努力交付,即不保证可靠交付。并且因为 TCP 可靠, 面向连接,不会丢失数据因此适合大数据量的交换。
  • TCP 是面向字节流,UDP 面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实时的应用比如 IP 电话和视频会议等)。
  • TCP 只能是 1 对 1 的,而UDP 支持 1 对 1,1 对多。
  • TCP 的首部较大为 20 字节,而 UDP 只有 8 字节。

js中的堆和栈,栈和队列有什么区别

堆(heap)和栈(stack)的区别:

  • 原始类型的数据会存在stack里面,如果复制的话就是存了一个copy在stack里。
  • 引用类型[object X] X = { Array, function, data, RegExp 等}会存在heap里,在stack里面存的是指向数据的指针。如果复制的话,就是复制这个指针。

WebSocket和HTTP有什么区别

相同点

  • 都是一样基于TCP的,都是可靠性传输协议。
  • 都是应用层协议。

不同点

  • WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息。HTTP是单向的。
  • WebSocket是需要握手进行建立连接的(相对HTTP来说,WebSocket是一种持久化的协议。它会基于HTTP协议,来完成一部分握手,HTTP握手部分完成,协议升级为WebSocket)。

http和https的区别

  • HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
  • 使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。
  • HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
  • http 和 https 用的端口不一样,http是 80,https是 443。
  • HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。

px,em,rem,vw,vh区别

  • px: px就是pixel的缩写,意为像素。px就是一张图片最小的一个点,一张位图就是千千万万的这样的点构成的。
  • em: 参考物是父元素的font-size,具有继承的特点。如果自身定义了font-size按自身来计算(浏览器默认字体是16px),整个页面内1em不是一个固定的值。
  • rem: css3新单位,相对于根元素html(网页)的font-size,不会像em那样,依赖于父元素的字体大小,而造成混乱。
  • vw: css3新单位,viewpoint width的缩写,视窗宽度,1vw等于视窗宽度的1%。
  • vh: css3新单位,viewpoint height的缩写,视窗高度,1vh等于视窗高度的1%。

wepack中loader和plugin的区别

什么是loader? loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中

什么是plugin? 在webpack运行的生命周期中会广播出许多事件,plugin可以监听这些事件,在合适的时机通过webpack提供的API改变输出结果。

区别: 对于loader,它是一个转换器,将A文件进行编译形成B文件,这里操作的是文件,比如将A.scss转换为A.css,单纯的文件转换过程。常用的:

  • babel-loade处理js
  • sass-loader, css-loader, style-loader处理样式
  • file-loader,url-loader处理文件

plugin是一个扩展器,它丰富了webpack本身,针对是loader结束后,webpack打包的整个过程,它并不直接操作文件,而是基于事件机制工作,会监听webpack打包过程中的某些节点,执行广泛的任务。常用的:

  • HtmlWebPackPlugin:自动把bundle注入html
  • CleanTerminalPlugin
  • BundleAnalyzerPlugin:分析bundle里面具体包含什么和对应大小

bind call apply区别

  • 三者都可以改变函数的this对象指向。
  • 三者第一个参数都是this要指向的对象,如果如果没有这个参数或参数为undefined或null,则默认指向全局window。
  • 三者都可以传参,但是apply是数组,而call是参数列表,且apply和call是一次性传入参数,而bind可以分为多次传入。
  • bind 改变this指向后不会立即执行,而是返回一个永久改变this指向的函数便于稍后调用;apply, call则是立即调用

进程线程的区别

  • 根本区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位
  • 资源开销:每个进程都有独立的代码和数据空间(程序上下文),程序之间的切换会有较大的开销;线程可以看做轻量级的进程,同一类线程共享代码和数据空间,每个线程都有自己独立的运行栈和程序计数器(PC),线程之间切换的开销小。
  • 包含关系:如果一个进程内有多个线程,则执行过程不是一条线的,而是多条线(线程)共同完成的;线程是进程的一部分,所以线程也被称为轻权进程或者轻量级进程。
  • 内存分配:同一进程的线程共享本进程的地址空间和资源,而进程之间的地址空间和资源是相互独立的
  • 影响关系:因为进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉(以前一个tab崩了就会整个浏览器崩),所以多进程要比多线程健壮。

JavaScript和typescript的区别

  • TS是JS的超集,JS 代码可以在无需任何修改的情况下与 TS 一同工作,同时可以使用编译器将 TS 代码转换为 JS。
  • TS 通过类型注解提供编译时的静态类型检查,
  • TS 中的数据要求带有明确的类型,JS不要求。
  • TS 为函数提供了缺省参数值。
  • TS 引入了 JS 中没有的“类”概念。
  • TS 中引入了模块的概念,可以把声明、数据、函数和类封装在模块中。

http 1.0/ 1.1/ 2.0的不同

http 1.0(构建可扩展性)

  • 版本信息现在会随着每个请求发送(HTTP1.0 被追加到GET行)
  • 状态代码行也会在响应开始时发送,允许浏览器本身了解请求的成功或失败,并相应地调整其行为(如以特定方式更新或使用本地缓存)
  • 引入了HTTP头的概念,无论是对于请求还是响应,允许传输元数据,并使协议非常灵活和可扩展。
  • Content-Type标头告诉客户端实际返回的内容的内容类型。在Content-Type标头帮助下,增加了传输除纯文本HTML文件外的其他类型文档的能力。

http 1.1(标准化的协议) HTTP/1.0的多种不同的实现运用起来有些混乱,HTTP1.1是第一个标准化版本,重点关注的是校正HTTP设计中的结构性缺陷:

  • 连接可以重复使用,节省了多次打开它的时间,以显示嵌入到单个原始文档中的资源。
  • 增加流水线操作,允许在第一个应答被完全发送之前发送第二个请求,以降低通信的延迟。
  • 支持响应分块。
  • 引入额外的缓存控制机制。
  • 引入内容协商,包括语言,编码,或类型,并允许客户端和服务器约定以最适当的内容进行交换。
  • 通过 Host 头,能够使不同的域名配置在同一个IP地址的服务器。
  • 安全性得到了提高

http 2.0(为了更优异的表现) HTTP/2在HTTP/1.1有几处基本的不同:

  • HTTP2是二进制协议而不是文本协议。不再可读和无障碍的手动创建,改善的优化技术现在可被实施。
  • 这是一个复用协议。并行的请求能在同一个链接中处理,移除了HTTP/1.x中顺序和阻塞的约束。
  • 压缩了headers。因为headers在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。
  • 其允许服务器在客户端缓存中填充数据,通过一个叫服务器推送的机制来提前请求。

MongoDB和MySQL

数据库模型 非关系型 关系型
存储方式 以类JSON的文档的格式存储 不同引擎有不同的存储方式
查询语句 MongoDB查询方式(类似JavaScript的函数) SQL语句
数据处理方式 基于内存,将热数据存放在物理内存中,从而达到高速读写 不同引擎有自己的特点
成熟度 新兴数据库,成熟度较低 成熟度高
广泛度 NoSQL数据库中,比较完善且开源,使用人数在不断增长 开源数据库,市场份额不断增长
事务性 仅支持单文档事务操作,弱一致性 支持事务操作
占用空间 占用空间大 占用空间小
join操作 MongoDB没有join MySQL支持join

观察者模式 vs 发布订阅模式

其实他们的思路很相似,最重要的区别是中间有没有一个“中间商”。

发布订阅模式 消息的发送者(称为发布者)不会将消息直接发送给特定的接收者(称为订阅者)。而是将发布的消息分为不同的类别,无需了解哪些订阅者(如果有的话)可能存在。同样的,订阅者可以表达对一个或多个类别的兴趣,只接收感兴趣的消息,无需了解哪些发布者(如果有的话)存在。

事件中心提供了订阅和发布功能。订阅者在订阅事件的时候,只关注事件本身,而不关心谁会发布这个事件;发布者在发布事件的时候,只关注事件本身,而不关心谁订阅了这个事件。

发布订阅模式

观察者模式 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个目标对象,当这个目标对象的状态发生变化时,会通知所有观察者对象,使它们能够自动更新。

观察者模式

例子:公司招聘。

  • 观察者模式:几个感兴趣的人在关注公司有没有发布前端职位,公司官网发了,他们立刻就知道了。
  • 发布订阅模式:公司跟猎头说,我有新职位,招聘者跟猎头说,我对前端感兴趣。

区别

  • 在观察者模式中,观察者是知道Subject的,Subject一直保持对观察者进行记录。然而,在发布订阅模式中,发布者和订阅者不知道对方的存在。它们只有通过消息代理进行通信。
  • 观察者模式是松散耦合的(有一定耦合度)。在发布订阅模式中,组件是完全解耦的,互相根本不知道彼此。
  • 观察者模式大多数时候是同步的,比如当事件触发,Subject就会去调用观察者的方法。而发布-订阅模式大多数时候是异步的(使用消息队列)。
  • 观察者模式需要在单个应用程序地址空间中实现,而发布-订阅更像交叉应用模式。

reference