Coder Social home page Coder Social logo

blog's People

Contributors

meooxx avatar

Watchers

 avatar  avatar

blog's Issues

词法分析

函数执行过程词法分析
1 分析参数
2 分析声明变量
3 分析函数声明

面试遇到的问题
1 作用域问题

var a = 1
function f1() {
    console.log(a)
}

function f2() {
    var a = 2 
    f1()
}

f2() 
//  1 执行结果 

2 由1 变化
1 作用域问题

var a = 1
function f1() {
    console.log(a)
}

function f2() {
    var a = 2 
    f1()
}

f2() 
//   error  a is  not define 执行结果 在声明时候查找 var , this则在 运行时候指定

2 关于 localStorage, sessionStorage
大小限制为 5M 玩法:当设置足够多的时候导致 exceed错误, 玩法,设置key的时候 对value额外处理附带lastmodify 字段,判定过期时间进行删除操作。
3 http 方面的问题
(1)tcp 片段的发送 1,2,3 如果此时 1 丢失, 则 2,3 即使被 接收到,也会被阻塞,保证传输数据的靠行
(2)http请求缓存问题:
last-modified: 浏览器第一次请求,返回的 信息会携带 last-modify 信息, 下一次请求会 带上
last-modified-since ;expires 时间, 浏览器直接根据时间就行判断,如果有效可能,连请求都不会发送。 其时间以服务端时间为标准,可能导致会和客户端差别很大;
etag: 被请求变量的实体值, 服务端对uri 的标记,告诉client 当前资源标记为 etag值, 发送请求附带 if-none-match ;
关于 Cache-Control: max-age=秒 和 Expires

Expires = 时间,HTTP 1.0 版本,缓存的载止时间,允许客户端在这个时间之前不去检查(发请求)
max-age = 秒,HTTP 1.1版本,资源在本地缓存多少秒。
如果max-age和Expires同时存在,则被Cache-Control的max-age覆盖。

Expires 的一个缺点就是,返回的到期时间是服务器端的时间,这样存在一个问题,如果客户端的时间与服务器的时间相差很大,那么误差就很大,所以在HTTP 1.1版开始,使用Cache-Control: max-age=秒替代。

Expires =max-age + “每次下载时的当前的request时间”

所以一旦重新下载的页面后,expires就重新计算一次,但last-modified不会变化

git

# 跟踪分支
$ git checkout --track origin/somebranch
# 如果想要将本地分支与远程分支设置为不同名字
$ git checkout -b sb origin/somebranch
# 设置已有的本地分支跟踪一个刚刚拉取下来的远程分支
$ git branch -u origin/somebranch
#如果想要查看设置的所有跟踪分支
$ git branch -vv
# 查看远程 origin 信息
$git remote show origin 
#查看文件的更改信息
$git blame 




normalize.css

转载: http://jerryzou.com/posts/aboutNormalizeCss/
将就看一下

咀嚼之味
首页 所有文章 关于我 RSS订阅
Fork me on GitHub
来,让我们谈一谈 Normalize.css
Nov 18, 2014 - 浏览量:51,403次 | Normalize.css CSS

本文译自Normalize.css官网: http://nicolasgallagher.com/about-normalize-css/

Normalize.css 只是一个很小的CSS文件,但它在默认的HTML元素样式上提供了跨浏览器的高度一致性。相比于传统的CSS reset,Normalize.css是一种现代的、为HTML5准备的优质替代方案。Normalize.css现在已经被用于Twitter Bootstrap、HTML5 Boilerplate、GOV.UK、Rdio、CSS Tricks 以及许许多多其他框架、工具和网站上。

Normalize.css 项目地址
Normalize.css 在GitHub上的源码
综述
Normalize.css是一种CSS reset的替代方案。经过@necolas和@jon_neal花了几百个小时来努力研究不同浏览器的默认样式的差异,这个项目终于变成了现在这样。

我们创造normalize.css有下面这几个目的:

保护有用的浏览器默认样式而不是完全去掉它们
一般化的样式:为大部分HTML元素提供
修复浏览器自身的bug并保证各浏览器的一致性
优化CSS可用性:用一些小技巧
解释代码:用注释和详细的文档来
Normalize.css支持包括手机浏览器在内的超多浏览器,同时对HTML5元素、排版、列表、嵌入的内容、表单和表格都进行了一般化。尽管这个项目基于一般化的原则,但我们还是在合适的地方使用了更实用的默认值。

Normalize vs Reset
知道Normalize.css和传统Reset的区别是非常有价值的。

  1. Normalize.css 保护了有价值的默认值
    Reset通过为几乎所有的元素施加默认样式,强行使得元素有相同的视觉效果。相比之下,Normalize.css保持了许多默认的浏览器样式。这就意味着你不用再为所有公共的排版元素重新设置样式。当一个元素在不同的浏览器中有不同的默认值时,Normalize.css会力求让这些样式保持一致并尽可能与现代标准相符合。

  2. Normalize.css 修复了浏览器的bug
    它修复了常见的桌面端和移动端浏览器的bug。这往往超出了Reset所能做到的范畴。关于这一点,Normalize.css修复的问题包含了HTML5元素的显示设置、预格式化文字的font-size问题、在IE9中SVG的溢出、许多出现在各浏览器和操作系统中的与表单相关的bug。

可以看以下这个例子,看看对于HTML5中新出现的input类型search,Normalize.css是如何保证跨浏览器的一致性的。

/**

    1. Addresses appearance set to searchfield in S5, Chrome
    1. Addresses box-sizing set to border-box in S5, Chrome (include -moz to future-proof)
      */

input[type="search"] {
-webkit-appearance: textfield; /* 1 /
-moz-box-sizing: content-box;
-webkit-box-sizing: content-box; /
2 */
box-sizing: content-box;
}

/**

  • Removes inner padding and search cancel button in S5, Chrome on OS X
    */

input[type="search"]::-webkit-search-decoration,
input[type="search"]::-webkit-search-cancel-button {
-webkit-appearance: none;
}
3. Normalize.css 不会让你的调试工具变的杂乱
使用Reset最让人困扰的地方莫过于在浏览器调试工具中大段大段的继承链,如下图所示。在Normalize.css中就不会有这样的问题,因为在我们的准则中对多选择器的使用时非常谨慎的,我们仅会有目的地对目标元素设置样式。

A common sight in browser debugging tools when using a CSS reset

  1. Normalize.css 是模块化的
    这个项目已经被拆分为多个相关却又独立的部分,这使得你能够很容易也很清楚地知道哪些元素被设置了特定的值。因此这能让你自己选择性地移除掉某些永远不会用到部分(比如表单的一般化)。

  2. Normalize.css 拥有详细的文档
    Normalize.css的代码基于详细而全面的跨浏览器研究与测试。这个文件中拥有详细的代码说明并在Github Wiki中有进一步的说明。这意味着你可以找到每一行代码具体完成了什么工作、为什么要写这句代码、浏览器之间的差异,并且你可以更容易地进行自己的测试。

这个项目的目标是帮助人们了解浏览器默认是如何渲染元素的,同时也让人们很容易地明白如何改进浏览器渲染。

如何使用 normalize.css
首先,安装或从Github下载Normalize.css,接下来有两种主要途径去使用它。

策略一:将normalize.css作为你自己项目的基础CSS,自定义样式值以满足设计师的需求。
策略二:引入normalize.css源码并在此基础上构建,在必要的时候用你自己写的CSS覆盖默认值。
结语
无论从适用范畴还是实施上,Normalize.css与Reset都有极大的不同。尝试一下这两种方法并看看到底哪种更适合你的开发偏好是非常值得的。这个项目在Github上以开源的形式开发。任何人都能够提交问题报告或者提交补丁。整个项目发展的过程对所有人都是可见的,而每一次改动的原因也都写在commit信息中,这些都是有迹可循的。

相关阅读
关于更多默认UA样式的详细信息:

WHATWG suggestions for rendering HTML documents
Internet Explorer User Agent Style Sheets
CSS2.1 User Agent Style Sheet Defaults
本文的版权归作者 邹润阳 所有,采用 Attribution-NonCommercial 3.0 License。任何人可以进行转载、分享,但不可在未经允许的情况下用于商业用途;转载请注明出处。感谢配合!

Jayce Li 羡辙 xidui Dozer LeuisKen szhshp 淘宝电影 LeetCode Baidu EFE Baidu FEX
Powered by Jekyll , Github Pages and UPYUN.

xcrun: errors

If you are facing an error like that on new MacOS version.

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

It means that you need to install XCode command line, open a Terminal and run this command:

$ xcode-select --install

[typeScript] function-this

1

 class Handler {
     info: string;
     onClickBad(this:void, e: Event) {
        // oops, used this here. using this callback would crash at runtime
        this.info = e.message;
      }
  }

 interface Element {
     addClickListener(onclick: (this: void, e: Event) => void): void;
   }
  addClickListener(new Handle().onClickBad)  // 'this' is unusable 

2

   class Handler {
      info: string;
      onClickGood(this: Handler, e: Event) {
        this.info = e.message;
    }
   }
     interface Element {
       addClickListener(onclick: (this: Handle, e: Event) => void): void;
     }

     interface Element {
         // arrow functions don’t capture this, 
         // so you can always pass them to something that expects this: void
       addClickListener(onclick: ( e: Event) => void): void; 
     }
    addClickListener(new Handle(). onClickGood)  // `this` is usable 

[js]注释图例详解 Redux `applyMiddleware`

export default function applyMiddleware(
  ...middlewares: Middleware[]
): StoreEnhancer<any> {
  return (createStore: StoreEnhancerStoreCreator) => <S, A extends AnyAction>(
    reducer: Reducer<S, A>,
    preloadedState?: PreloadedState<S>
  ) => {
    const store = createStore(reducer, preloadedState)
    let dispatch: Dispatch = () => {
      throw new Error(
        'Dispatching while constructing your middleware is not allowed. ' +
          'Other middleware would not be applied to this dispatch.'
      )
    }

    const middlewareAPI: MiddlewareAPI = {
      getState: store.getState,
      dispatch: (action, ...args) => dispatch(action, ...args)
    }
    const chain = middlewares.map(middleware => middleware(middlewareAPI))
    /**
     * compose 顺序
     * 
     * const dipatch = compose(f1, f2, f3, f4)(store.dispatch)
     *
     *   return4 = f4(dispatch): <A, T extends typeof A>(action:A) => T
     *      |
     *   return3 = f3(return4): <A, T extends typeof A>(action:A) => T
     *      |
     *   return2 = f2(return3): <A, T extends typeof A>(action:A) => T
     *      |
     *   return1 = f1(return2): <A, T extends typeof A>(action:A) => T
     *
     * 使用此`diaptch` dispatch(action) 执行顺序
     * 
     *    return1 执行, return1 中执行 next(action) 即执行 return2
     *       |
     *    return2 执行, return3 中执行 next(action)即 return3
     *       |
     *    return3 执行, return4 中执行 next(action) 即 return 4
     *       |
     *    return4 执行, return T4
     *       |
     *    返回到 f3 next() 后面代码执行, 返回 T3
     *       |
     *    返回到 f2 next() 后面代码执行, 返回 T2
     *       |
     *    返回到 f1 next() 后面代码执行, 返回 T1
     *
     */
    dispatch = compose<typeof dispatch>(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

[html] the difference between property and attribute

When writing HTML source code, you can define attributes on your HTML elements. Then, once the browser parses your code, a corresponding DOM node will be created. This node is an object, and therefore it has properties.
当写 HTML 代码当时候,你可以定义 attributes在 HTML 元素上。 一旦浏览器解析你的代码, 对应当DOM node 将会被创建。 这个node 是一个 object, 因此他有 properties

[img-lazyload]

lazyload

引用自 leo555's blog

懒加载

Lazyload 可以加快网页访问速度,减少请求,实现思路就是判断图片元素是否可见来决定是否加载图片。当图片位于浏览器视口 (viewport) 中时,动态设置 <img> 标签的 src 属性,浏览器会根据 src 属性发送请求加载图片。

懒加载实现

首先不设置 src 属性,将图片真正的 url 放在另外一个属性 data-src 中,在图片即将进入浏览器可视区域之前,将 url 取出放到 src 中。

懒加载的关键是如何判断图片处于浏览器可视范围内,通常有三种方法:

方法一

通过对比屏幕可视窗口高度和浏览器滚动距离与元素相对文档顶部的距离之间的关系,判断元素是否可见。

示意图如下:

lazyload.svg

代码如下:

function isInSight(el) {
    const clientHeight = window.innerHeight // 获取屏幕可视窗口高度
    const scrollTop = document.body.scrollTop // 浏览器窗口顶部与文档顶部之间的距离
    // el.offsetTop 元素相对于文档顶部的距离 
    // +100是为了提前加载
    return el.offsetTop <= clientHeight + scrollTop + 100
}

方法二

通过 getBoundingClientRect() 获取图片相对于浏览器视窗的位置

示意图如下:

lazyload1.svg

getBoundingClientRect() 方法返回一个 ClientRect 对象,里面包含元素的位置和大小的信息

ClientRect {
	bottom: 596,
	height: 596,
	left: 0,
	right: 1920,
	top: 0,
	width: 1920
}

其中位置是相对于浏览器视图左上角而言。代码如下:

function isInSight1(el) {
    const bound = el.getBoundingClientRect() 
    const clientHeight = window.innerHeight // 表示浏览器可视区域的高度
    // bound.top 表示图片到可视区域顶部距离
    // +100是为了提前加载
    return bound.top <= clientHeight + 100 
}

方法三

使用 IntersectionObserver API,观察元素是否可见。“可见”的本质是目标元素与 viewport 是否有交叉区,所以这个 API 叫做“交叉观察器”。

实现方式

function loadImg(el) {
    if (!el.src) {
        const source = el.dataset.src
        el.src = source
        el.removeAttribute('data-src')
    }
}

const io = new IntersectionObserver(entries => {
	for (const entry of entries) {
        const el = entry.target
        const intersectionRatio = entry.intersectionRatio
        if (intersectionRatio > 0 && intersectionRatio <= 1) {
            loadImg(el)
        }
        el.onload = el.onerror = () => io.unobserve(el)
    }
})

function checkImgs() {
    const imgs = Array.from(document.querySelectorAll('img[data-src]'))
    imgs.forEach(item => io.observe(item))
}

IntersectionObserver

IntersectionObserver 的作用就是检测一个元素是否可见,以及元素什么时候进入或者离开浏览器视口。

兼容性

  • Chrome 51+(发布于 2016-05-25)
  • Android 5+ (Chrome 56 发布于 2017-02-06)
  • Edge 15 (2017-04-11)
  • iOS 不支持

Polyfill

WICG 提供了一个 polyfill

API

const io = new IntersectionObserver(callback, option)

IntersectionObserver 是一个构造函数,接受两个参数,第一个参数是可见性变化时的回调函数,第二个参数定制了一些关于可见性的参数(可选),IntersectionObserver 实例化后返回一个观察器,可以指定观察哪些 DOM 节点。

下面是一个最简单的应用:

// 1. 获取 img
const img = document.querySelector('img')
// 2. 实例化 IntersectionObserver,添加 img 出现在 viewport 瞬间的回调
const observer =  new IntersectionObserver(changes => { 
  console.log('我出现了!') 
});
// 3. 开始监听 img
observer.observe(img)

(1) callback

回调 callback 接受一个数组作为参数,数组元素是 IntersectionObserverEntry 对象。IntersectionObserverEntry 对象上有7个属性,

IntersectionObserverEntry {
	time: 72.15500000000002, 
	rootBounds: ClientRect, 
	boundingClientRect: ClientRect, 
	intersectionRatio: 0.4502074718475342,
	intersectionRect: ClientRect, 
	isIntersecting: true,
	target: img
}
  • boundingClientRect: 对 observe 的元素执行 getBoundingClientRect 的结果
  • rootBounds: 对根视图执行 getBoundingClientRect 的结果
  • intersectionRect: 目标元素与视口(或根元素)的交叉区域的信息
  • target: observe 的对象,如上述代码就是 img
  • time: 过了多久才出现在 viewport 内
  • intersectionRatio:目标元素的可见比例,intersectionRect 占 boundingClientRect 的比例,完全可见时为1,完全不可见时小于等于0
  • isIntersecting: 目标元素是否处于视口中

(2) option

假如我们需要特殊的触发条件,比如元素可见性为一半的时候触发,或者我们需要更改根元素,这时就需要配置第二个参数 option 了。

通过设置 option 的 threshold 改变回调函数的触发条件,threshold 是一个范围为0到1数组,默认值是[0],也就是在元素可见高度变为0时就会触发。如果赋值为 [0, 0.5, 1],那回调就会在元素可见高度是0%,50%,100%时,各触发一次回调。

const observer =  new IntersectionObserver((changes) => { 
  console.log(changes.length); 
}, {
  root: null, 
  rootMargin: '20px', 
  threshold: [0, 0.5, 1]
});

root 参数默认是 null,也就是浏览器的 viewport,可以设置为其它元素,rootMargin 参数可以给 root 元素添加一个 margin,如 rootMargin: '20px' 时,回调会在元素出现前 20px 提前调用,消失后延迟 20px 调用回调。

(3) 观察器

// 开始观察
io.observe(document.getElementById('root'))

// 观察多个 DOM 元素
io.observe(elementA)
io.observe(elementB)

// 停止观察
io.unobserve(element)

// 关闭观察器
io.disconnect()

使用 IntersectionObserver 优势

使用前两种方式实现 lazyload 都需要监听浏览器 scroll 事件,而且要对每个目标元素执行 getBoundingClientRect() 方法以获取所需信息,这些代码都在主线程上运行,所以可能造成性能问题。

Intersection Observer API 会注册一个回调方法,每当期望被监视的元素进入或者退出另外一个元素的时候(或者浏览器的视口)该回调方法将会被执行,或者两个元素的交集部分大小发生变化的时候回调方法也会被执行。通过这种方式,网站将不需要为了监听两个元素的交集变化而在主线程里面做任何操作,并且浏览器可以帮助我们优化和管理两个元素的交集变化。

参考资料

  1. 原生 JS 实现最简单的图片懒加载
  2. IntersectionObserver
  3. IntersectionObserver API 使用教程
  4. MDN-Intersection Observer API


Website lz5z.com  · 
GitHub @Leo555  · 
demo lazyload

关于first-letter 奇怪特性

1 first-child first-letter 属于伪元素
2 :active :hover 属于伪类
3 display值如果是inline, block, table, table-row, table-caption, table-cell, list-item都是可以的;但是不能是inline-block, inline-table,会直接无效;而display:flex则改变了规则,直接选择了下一行的字符内容。
4 对:before 元素生效
5 在p 元素上面使用
6 属于子元素
参考:张鑫旭博客

[serverjs][major, minor, patch]

[major, minor, patch] 主版本, 次要版本 , 补丁版本

~: minor位存在 允许更改patch, 不存在可以修改minor位

  • ~1.2.3 := >=1.2.3 <1.(2+1).0 := >=1.2.3 <1.3.0
  • ~1.2 := >=1.2.0 <1.(2+1).0 := >=1.2.0 <1.3.0 (Same as 1.2.x)
  • ~1 := >=1.0.0 <(1+1).0.0 := >=1.0.0 <2.0.0 (Same as 1.x)
  • ~0.2.3 := >=0.2.3 <0.(2+1).0 := >=0.2.3 <0.3.0
  • ~0.2 := >=0.2.0 <0.(2+1).0 := >=0.2.0 <0.3.0 (Same as 0.2.x)
  • ~0 := >=0.0.0 <(0+1).0.0 := >=0.0.0 <1.0.0 (Same as 0.x)
  • ~1.2.3-beta.2 := >=1.2.3-beta.2 <1.3.0 Note that prereleases in the 1.2.3 version will be allowed, if they are greater than or equal to beta.2. So, 1.2.3-beta.4 would be allowed, but 1.2.4-beta.2 would not, because it is a prerelease of a different [major, minor, patch] tuple.
    注意: 如果它们大于等于 beta.2.,则1.2.3版本预发布版本是被允许的 , 所以1.2.3-beta4 可以,但是1.2.4-beta.2 不行, 因为它是不同[major, minor, patch]元组的 prerelease

^: 最左侧非0的版本
Allows changes that do not modify the left-most non-zero digit in the [major, minor, patch] tuple. In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for versions 0.X >=0.1.0, and no updates for versions 0.0.X.

Many authors treat a 0.x version as if the x were the major "breaking-change" indicator.

Caret ranges are ideal when an author may make breaking changes between 0.2.4 and 0.3.0 releases, which is a common practice. However, it presumes that there will not be breaking changes between 0.2.4 and 0.2.5. It allows for changes that are presumed to be additive (but non-breaking), according to commonly observed practices.
允许 那些不是更改[major, minor, patch]中最左非零位 的更改。 换句话说 这允许对 1.0.0 的patch 和minor 更新, 对0.X >= 0.1.0的 patch 更新 , 不会对0.0.X更新

  • 许多作者对待0.X的版本, 认为X是 marjor“breaking-change” (不兼容更新?) 的标识指示
    当一个作者可能在 0.2.4 和 0.3.0 之间 做重大更新的时候,版本范围是理想的, 这种是常见的做法。但是, 它是预设在0.2.4 和0.2.5中间是没有重大更新。 依据在常见的实践观察中, 它被假设为附加性的更新(非破坏性的)。

  • ^1.2.3 := >=1.2.3 <2.0.0

  • ^0.2.3 := >=0.2.3 <0.3.0

  • ^0.0.3 := >=0.0.3 <0.0.4

  • ^1.2.3-beta.2 := >=1.2.3-beta.2 <2.0.0 Note that prereleases in the 1.2.3 version will be allowed, if they are greater than or equal to beta.2. So, 1.2.3-beta.4 would be allowed, but 1.2.4-beta.2 would not, because it is a prerelease of a different [major, minor, patch] tuple.

  • 注意 如果它们大于等于 beta.2. , 1.2.3 之间prerelease版本 不被允许的, 所以1.2.3-beta.4 会被允许的,但是1.2.4-beta.2不可以 ,因为这个是不同 [major, minor, patch] 元组的prerelease。

  • ^0.0.3-beta := >=0.0.3-beta <0.0.4 Note that prereleases in the 0.0.3 version only will be allowed, if they are greater than or equal to beta. So, 0.0.3-pr.2 would be allowed.

  • 0.0.3 版本的prerelaese版本只有 大于等于beta.才被允许。所以 0.0.3-pr.2可以

When parsing caret ranges, a missing patch value desugars to the number 0, but will allow flexibility within that value, even if the major and minor versions are both 0.
当解析范围时,缺patch 值 视为 0 , 但是允许在该值内灵活选择, 即使major 和minor 版本是 0

  • ^1.2.x := >=1.2.0 <2.0.0
  • ^0.0.x := >=0.0.0 <0.1.0
  • ^0.0 := >=0.0.0 <0.1.0
    A missing minor and patch values will desugar to zero, but also allow flexibility within those values, even if the major version is zero.

缺少 minor 和patch 值视为0, 但是也是灵活的,即使major 是0

  • ^1.x := >=1.0.0 <2.0.0
  • ^0.x := >=0.0.0 <1.0.0

[react] Modal 框点击其他区域关闭

1 全局遮罩这种, 在顶级监听click 时间

 handleClick = e => {
        if (e.target === e.currentTarget) {
            const { handleClose } = this.props;
            handleClose && handleClose(e);
        }
    };
 render() {
      <div
            onClick={this.handleClick}
            className={`modal-inner ${className}`}
       >
                        {this.props.children}
        </div>
}
    <div onclick={e=>console.log("outer:", e.target, e.currentTarget)}>
        <div  className=""inner" onclick={e=> conosle.log( e.target, e.currentTarget)}> // 点击 inner
   // inner: <div class="inner"> 和  <div class="inner"> 
  // outer:  <div class="inner"> 和 <div class="outer">

解释: 这种框是100% 覆盖的, 所以只要在顶级div 监听click 处理 target === currentTarget(被点击的dom 与事件触发dom相同 ) 说明在其本身触发关闭, 其他情况冒泡触发上来的 忽略

2 dropdown 这种 局部折罩

handleMousedown = e => {
        const { visible, handleClose } = this.props;
        const target = e.target;
        const root = findDOMNode(this);
        // mdn contains ie9 ✅
        if (!visible || root.contains(target)) return;
        if (handleClose) handleClose();
    };

处理逻辑, 全局监听mousedown事件, 只要点击 不是在dropdown() 元素上(findDOMNode(this),关闭弹窗

[typescript]ts这个就够了

interface vs type

文档说明

  • interface 使用 extends 关键词, type 使用 &
  • interface 可以增加新的关键词, A type can not be changed after being created

unkonw 关键词

function f1(a: any) {
  a.b(); // OK
}
function f2(a: unknown) {
  a.b();
// Object is of type 'unknown'.
}

This is useful when describing function types because you can describe functions that accept any value without having any values in your function body.

Conversely, you can describe a function that returns a value of unknown type:

function safeParse(s: string): unknown {
  return JSON.parse(s);
}

// Need to be careful with 'obj'!
const obj = safeParse(someRandomString);

Interfaces vs. Intersections

type Name1 {
    name: string
}
type Name2 {
   name: number
}
type A = Name1 & Name2 // works!
interface AA extends Name1, Nam2 {} // oops!
// Interface 'AA' cannot simultaneously extend types 'Id' and 'Name'.
// Named property 'name' of types 'Id' and 'Name' are not identical.

Member Visibility

public: can be accessed everywhere
protect: subClass and where it was declared in
private: can be accessed within class where it declared,private also allows access using bracket notation during type checking

class MySafe {
  private secretKey = 12345;
}
 
const s = new MySafe();
 
// Not allowed during type checking
console.log(s.secretKey);
Property 'secretKey' is private and only accessible within class 'MySafe'.
// OK
console.log(s["secretKey"]);

新一轮面试查漏(etag)

Etag 主要为了解决 Last-Modified 无法解决的一些问题。

1、一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
2、某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒)
3、某些服务器不能精确的得到文件的最后修改时间;
为此,HTTP/1.1引入了 Etag(Entity Tags).Etag仅仅是一个和文件相关的标记,可以是一个版本标记,比如说v1.0.0或者说"2e681a-6-5d044840"这么一串看起来很神秘的编码。但是HTTP/1.1标准并没有规定Etag的内容是什么或者说要怎么实现,唯一规定的是Etag需要放在""内。
尤其是在做断点下载/续传时,表现得比较明显

什么是”Etag”?

HTTP 协议规格说明定义ETag为“被请求变量的实体值” . 另一种说法是,ETag是一个可以与Web资源关联的记号(token)。典型的Web资源可以一个Web页,但也可能是JSON或XML文档。服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端,以下是服务器端返回的格式:
ETag: "50b1c1d4f775c61:df3"
客户端的查询更新格式是这样的:
If-None-Match: W/"50b1c1d4f775c61:df3"
如果ETag没改变,则返回状态304然后不返回,这也和Last-Modified一样。

#ETag应用:

Etag由服务器端生成,客户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改。常见的是使用If-None-Match.请求一个文件的流程可能如下:
====第一次请求===
1.客户端发起 HTTP GET 请求一个文件;
2.服务器处理请求,返回文件内容和一堆Header,当然包括Etag(例如"2e681a-6-5d044840")(假设服务器支持Etag生成和已经开启了Etag).状态码200
====第二次请求===
1.客户端发起 HTTP GET 请求一个文件,注意这个时候客户端同时发送一个If-None-Match头,这个头的内容就是第一次请求时服务器返回的Etag:2e681a-6-5d044840
2.服务器判断发送过来的Etag和计算出来的Etag匹配,因此If-None-Match为False,不返回200,返回304,客户端继续使用本地缓存;
流程很简单,问题是,如果服务器又设置了Cache-Control:max-age和Expires呢,怎么办?
答案是同时使用,也就是说在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后,服务器才能返回304.(不要陷入到底使用谁的问题怪圈)
#2 Last-Modified和ETags结合使用:
把Last-Modified 和ETags请求的http请求头一起使用,这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生 Last-Modified/Etag标记,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。
过程如下:
1. 客户端请求一个页面(A)。
2. 服务器返回页面A,并在给A加上一个Last-Modified/ETag。
3. 客户端展现该页面,并将页面连同Last-Modified/ETag一起缓存。
4. 客户再次请求页面A,并将上次请求时服务器返回的Last-Modified/ETag一起传递给服务器。
5. 服务器检查该Last-Modified或ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304和一个空的响应体。为什么使用Etag请求头?

[js] vue 响应式原理

let activeUpdate = '';
class Dep {
  constructor() {
    this.subcriber = new Set();
  }

  depend() {
    if (!activeUpdate) return;
    this.subcriber.add(activeUpdate);
  }

  notify() {
    this.subcriber.forEach((f) => f());
  }
}
const dep = new Dep();
function observe(data) {
  Object.keys(data).forEach((key) => {
    // good
    let v = data[key];
    // bad
    // return data[key] 爆栈
    Object.defineProperty(data, key, {
      get() {
        // 3 收集依赖,因为在update内执行,所以可以获取到update执行时候设置的activeUpdate
        dep.depend();
        return v;
      },
      set(newv) {
        if (newv === v) return;
        v = newv;
        // 5 遍历Dep类中由depend收集的依赖回调执行
        dep.notify();
      },
    });
  });
}

function autoRun(update) {
  const wrapUpdate = () => {
    activeUpdate = wrapUpdate;
    update();
    activeUpdate = null;
  };
  wrapUpdate();
}
const data = {
  count: 1,
};

// 0 转换data,提供get,set属性
observe(data);
// 1 执行updatedata
autoRun(() => {
// 2 访问get属性
  console.log('count:', data.count);
});
autoRun(() => {
  // good
  console.log(data.count + 1);
  // bad
  // console.log(data.count++)
  // data.count++ 触犯autoRun, autoRun data.count++ -> 触发autoRun
});

data.count++;
data.count++;
data.count++;

0 将data转换为响应式的
1 运行autoRun, autoRun将执行回调函数update的方法挂到全局(wrappedUpdate) activeUpdate上面
2 执行update, 此时如果函数有读取操作即访问了get属性, 则触发definePropertor 中的 depend
3 depend在update执行中执行, 可以读取到全局的activeUpdate,此时可以将update置入依赖回调收集set中
4 update执行完毕后,将当前activeUpdate置为null
5 更改值, 触发set触发notify, 遍历收集的依赖执行

参考:amandakelake/blog#63

[go] slice 与 array

array

特点 固定的长度

var a [n]int // a[n] {}
var a = [...]int {1,2,3} // a[3]{1,2,3}
var a = [2]int {1} //a[2]{1,0}

slice

灵活, 动态分配空间. 保持对底层数组的引用 在内存中, 可以像array 一样根据index 修改值,会反映在引用的数组上面
内部 三个部分 一个指向底层数组的指针, len, cap

  a:=[]{1,2,3} //不指明 数量
  a = make([]int, len, cap)
  a = array[start:end] 

func copy(dst, src []T) int 返回 copy的数量
func append(s []T, x...T ) []T

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.