一、 ES6 ES7 ES8的学习

ES6常用新特性

  • ES7新特性
    • Array.prototype.includes
    • Exponentiation Operator(求幂运算)
  • ES8新特性
    • Object.values/Object.entries
    • String padding(字符串填充)
    • Object.getOwnPropertyDescriptors
    • 函数参数列表和调用中的尾逗号(Trailing commas)
    • 异步函数(Async Functions)

二 问题集合

一行代码实现数组去重? new set()

怎么判断两个对象相等? JSON.stringify(obj2);

1 WeakMap 和 Map 的区别?

Set 和 Map 数据结构

ES6 提供了新的数据结构 Set 它类似于数组,但是成员的值都是唯一的,没有重复的值。

ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说, Object 结构提供了“字符串—值”的对应, Map 结构提供了“值—值”的对应,是一种更完善的 Hash结构实现。

WeakMap 结构与 Map 结构基本类似,唯一的区别是它只接受对象作为键名( null 除外),不接受其他类型的值作为键名,而且键名所指向的对象,不计入垃圾回收机制。

WeakMap 最大的好处是可以避免内存泄漏。一个仅被 WeakMap 作为 key 而引用的对象,会被垃圾回收器回收掉。

WeakMap 拥有和 Map 类似的 set(key, value) 、 get(key)、has(key)、 delete(key) 和 clear() 方法, 没有任何与迭代有关的属性和方法。

2、浏览器缓存

浏览器缓存分为强缓存和协商缓存。当客户端请求某个资源时,获取缓存的流程如下:

先根据这个资源的一些 http header 判断它是否命中强缓存,如果命中,则直接从本地获取缓存资源,不会发请求到服务器;

当强缓存没有命中时,客户端会发送请求到服务器,服务器通过另一些 request header验证这个资源是否命中协商缓存,称为 http再验证,如果命中,服务器将请求返回,但不返回资源,而是告诉客户端直接从缓存中获取,客户端收到返回后就会从缓存中获取资源;

强缓存和协商缓存共同之处在于,如果命中缓存,服务器都不会返回资源;

区别是,强缓存不对发送请求到服务器,但协商缓存会。

当协商缓存也没命中时,服务器就会将资源发送回客户端。

当 ctrl+f5 强制刷新网页时,直接从服务器加载,跳过强缓存和协商缓存;

当 f5 刷新网页时,跳过强缓存,但是会检查协商缓存;

强缓存

Expires(该字段是 http1.0 时的规范,值为一个绝对时间的 GMT 格式的时间字符串,代表缓存资源的过期时间)

Cache-Control:max-age(该字段是 http1.1 的规范,强缓存利用其 max-age 值来判断缓存资源的最大生命周期,它的值单位为秒)

协商缓存

Last-Modified(值为资源最后更新时间,随服务器response返回)

If-Modified-Since(通过比较两个时间来判断资源在两次请求期间是否有过修改,如果没有修改,则命中协商缓存)

ETag(表示资源内容的唯一标识,随服务器response返回)

If-None-Match(服务器通过比较请求头部的If-None-Match与当前资源的ETag是否一致来判断资源是否在两次请求之间有过修改,如果没有修改,则命中协商缓存)

What's FC?

一定不是KFC,FC的全称是:Formatting Contexts,是W3C CSS2.1规范中的一个概念。它是页面中的一块渲染区域,并且有一套渲染规则,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。

BFC

BFC(Block Formatting Contexts)直译为"块级格式化上下文"。Block Formatting Contexts就是页面上的一个隔离的渲染区域,容器里面的子元素不会在布局上影响到外面的元素,反之也是如此。如何产生BFC?

float的值不为none。

overflow的值不为visible。

position的值不为relative和static。

display的值为table-cell, table-caption, inline-block中的任何一个。

那BFC一般有什么用呢?比如常见的多栏布局,结合块级别元素浮动,里面的元素则是在一个相对隔离的环境里运行。

IFC

IFC(Inline Formatting Contexts)直译为"内联格式化上下文",IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响)

IFC中的line box一般左右都贴紧整个IFC,但是会因为float元素而扰乱。float元素会位于IFC与与line box之间,使得line box宽度缩短。 同个ifc下的多个line box高度会不同。 IFC中时不可能有块级元素的,当插入块级元素时(如p中插入div)会产生两个匿名块与div分隔开,即产生两个IFC,每个IFC对外表现为块级元素,与div垂直排列。

那么IFC一般有什么用呢?

水平居中:当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。

垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。

GFC

GFC(GridLayout Formatting Contexts)直译为"网格布局格式化上下文",当为一个元素设置display值为grid的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器(grid container)上定义网格定义行(grid definition rows)和网格定义列(grid definition columns)属性各在网格项目(grid item)上定义网格行(grid row)和网格列(grid columns)为每一个网格项目(grid item)定义位置和空间。那么GFC有什么用呢,和table又有什么区别呢?首先同样是一个二维的表格,但GridLayout会有更加丰富的属性来控制行列,控制对齐以及更为精细的渲染语义和控制

FFC

FFC(Flex Formatting Contexts)直译为"自适应格式化上下文",display值为flex或者inline-flex的元素将会生成自适应容器(flex container),可惜这个牛逼的属性只有谷歌和火狐支持,不过在移动端也足够了,至少safari和chrome还是OK的,毕竟这俩在移动端才是王道。

Flex Box 由伸缩容器和伸缩项目组成。通过设置元素的 display 属性为 flex 或 inline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。

伸缩容器中的每一个子元素都是一个伸缩项目。伸缩项目可以是任意数量的。伸缩容器外和伸缩项目内的一切元素都不受影响。简单地说,Flexbox 定义了伸缩容器内伸缩项目该如何布局。

div 模拟 textarea 的实现

``#box{
    width: 400px;
    min-height: 100px;
    max-height: 300px;
    height: auto;
    outline: none;
    border: 1px solid #f00;
    overflow-y: auto;
  }

实现extend函数

JavaScript 原生js深拷贝的实现

function deepCopy(initalObject){
    var finalObject = {}
    try {
        finalObject = JSON.parse(JSON.stringify(initalObject))
    }
    return finalObject
}

function deepCopy(initalObject,finalObject){
  var finalObject = finalObject || {}
  for(var key in initalObject){
    if(typeof initalObject[key] === "object"){
      finalObject[key] = (initalObj[key].constructor === Array) ? [] : {}  // 区分是数组还是对象
      arguments.callee(initalObject[key],finalOjbect[key]) //调用自身函数方法
    }else{
      finalObject[key] = initalObject[key]
    }
  }
  return finalObject
}

function deepCopy(initalObject,finalObject){
  var finalObject = finalObject || {}
  for(var key in initalObject){
    var tempProperty = initalObject[key]
    if(tempProperty === initalObject){
      continue //
      当自身属性引用自己的时候,跳过执行,不拷贝,避免相互引用导致内存溢出的情况
    }
    if(typeof initalObject[key] === "object"){
      finalObject[key] = (initalObject[key].constructor === Array) ? [] : {}  //区分构造函数
      arguments.callee(initalObject[key],finalObject[key]) //调用自身函数方法
    }else{
      finalObject[key] = initalObject[key]
    }
  }
  return finalObject
}

vue 实现的原理

https://juejin.im/entry/59116fa6a0bb9f0058aaaa4c

nodejs的通信方式

通信方式与进程产生方式有关,而Node有4种创建进程的方式:

spawn()

exec()

execFile()

fork()

通过stdin/stdout传递json:最直接的方式,适用于能够拿到“子”进程handle的场景,适用于关联进程之间通信,无法跨机器

  • Node原生IPC支持:最native(地道?)的方式,比上一种“正规”一些,具有同样的局限性

  • 通过sockets:最通用的方式,有良好的跨环境能力,但存在网络的性能损耗

  • 借助message queue:最强大的方式,既然要通信,场景还复杂,不妨扩展出一层消息中间件,漂亮地解决各种通信问题

MV**

https://github.com/livoras/blog/issues/11

项目做过哪些性能优化?

写到这里,雅虎的35条军规算是介绍完了。条目虽然很多,但经过分类,可以发现,性能优化主要切入点可以从以下几个方面去考虑:

  • 资源本身大小的压缩优化(想办法减少资源的体积)
  • 网络请求的全过程(从url地址栏输入发送请求开始到返回响应包的每个环节)
  • 浏览器渲染的全过程(拿到资源后浏览器渲染的每个环节)

    看下雅虎军规 https://github.com/creeperyang/blog/issues/1

results matching ""

    No results matching ""