├── .gitignore ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | bower_components/ 3 | *.log 4 | 5 | build/ 6 | dist/ 7 | .idea/ 8 | .DS_store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Erichain 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 前端知识点集锦 2 | 收集关于前端的各个方面的知识 3 | 4 | ### 关于前端是什么,以及需要学习什么,移步这里: 5 | 6 | #### [Front-End Developer Handbook](https://github.com/FrontendMasters/front-end-handbook-2017) 7 | 8 | --- 9 | 10 | ### HTML部分 11 | 12 | #### docType 13 | 14 | - 混杂模式 15 | - 触发条件:不加文档类型声明 16 | - 标准模式 17 | - 触发条件:`` 18 | 19 | #### 标签语义化 20 | 21 | - 去掉或者丢失样式的时候能够让页面呈现出清晰的结构 22 | - 有利于 SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重 23 | - 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页 24 | - 便于团队开发和维护,语义化更具可读性,是下一步网页的重要动向,遵循 W3C 标准的团队都遵循这个标准,可以减少差异化 25 | 26 | #### 替换元素和非替换元素 27 | 28 | - 替换元素 29 | - `img, object, iframe, video` 等。即元素本身没有实际内容,通过元素的标签和属性来显示内容 30 | - 非替换元素 31 | - 大多数标签属于非替换元素,这部分标签把标签里的内容直接告诉浏览器显示出来 32 | 33 | #### meta 标签 34 | 35 | - 如何在不使用JS的情况下刷新页面(``) 36 | - 设置页面缓存(``) 37 | - 移动端设置 38 | 39 | #### HTML 代码优化 40 | 41 | - 标签嵌套层级不要太深,标签尽量简洁化.如懒加载后将 data 属性去除 42 | - 大量图片的懒加载策略,以及一些元素利用 ajax 在 onload 后实行延迟加载 43 | - 对一些 js 的异步加载 44 | 45 | #### 搜索引擎优化 SEO 46 | 47 | #### 关于 HTML,CSS 的一些鲜为人知的知识 48 | 49 | 1、对于 `box-sizing`,最好将其设置为 `border-box`,这样,设置了宽高再设置 padding 的时候,它的尺寸就不会再变化了; 50 | 51 | 2、设置浮动的元素在 HTML 文档中需要排列在其余未设置浮动的元素之前,否则,浮动的元素默认就会一直在页面下方; 52 | 53 | 3、设置了浮动的元素默认会被设置为块级元素; 54 | 55 | 4、边距折叠只会发生在毗邻的元素上,定位或者浮动的元素不会发生边距折叠,同时,边距折叠只有纵向的,没有横向的;Flexbox 的子元素不会发生边距折叠; 56 | 57 | 5、对 button 要总是设置 type 属性,form 里面的 button 如果不设置 type 的话,默认为提交按钮; 58 | 59 | 6、对于 form,避免在 input 中按回车的时候提交表单,最好设置 form 的 `onsubmit` 属性为 `return false;`; 60 | 61 | 7、设置 fixed 定位的元素相对于浏览器窗口,但是,设置了 absolute 定位的元素不一定相对于其设置了 relative 定位的元素进行定位,而是相对于最近的设置的 position 属性不为 `static` 的父级元素进行定位; 62 | 63 | 8、CSS 属性不区分大小写; 64 | 65 | #### `img` 标签的跨域设置 66 | 67 | > 尤其是在使用 canvas 画图的时候会用到 68 | 69 | ``` vbscript-html 70 | 71 | ``` 72 | 73 | --- 74 | 75 | ### CSS 部分 76 | 77 | #### 浮动,清除浮动的方法和原理(4 种方法) 78 | 79 | - 使用空标签设置 `clear: both;`(`clear` 有哪些值可以设置?应用在什么元素上?) 80 | - 为父级元素设置 `overflow: hidden;` (利用 BFC 的原理,除了设置 `hidden`,还能设置其他的值吗?) 81 | - 使用伪元素,为要清除浮动的元素添加 `.clearfix` 类(推荐,其原理可查看 http://nicolasgallagher.com/micro-clearfix-hack/) 82 | - 使用 `min-height: contain-floats;` (不推荐,兼容性不好) 83 | 84 | #### CSS 块级格式化上下文 85 | 86 | - 触发条件 87 | - `position` 属性不为 `static` 或者 `relative` 88 | - `float` 属性不为 `none` 89 | - 非块级的块级元素 (inline-block, table-cell) 90 | - `overflow` 不为 `visible` 91 | - 特性 92 | - 内部的 Box 会在垂直方向,从顶部开始一个接一个地放置 93 | - Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生叠加 94 | - BFC 的区域不会与 float box 叠加 95 | - BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然 96 | - 计算 BFC 的高度时,浮动元素也参与计算 97 | - 用处 98 | - 解决 margin 边距叠加问题。为元素单独创建一个 BFC 来防止外边距的折叠 99 | - 清除浮动。为包含浮动元素的 container 创建 BFC 来清除浮动 100 | 101 | #### 盒子模型(IE 盒子模型的区别) 102 | 103 | - 总宽度 = margin + padding + border + content,IE 的盒子模型的宽度不计 padding 和 border 104 | - css3 的 `box-sizing` 属性,详见 https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing 105 | - content-box,border 和 padding 不计算入 width 之内 106 | - border-box,border 和 padding 计算入 width 之内 107 | 108 | #### position vs float 109 | 110 | > 定位和浮动的区别? 111 | 112 | > 什么时候使用定位,什么时候使用浮动? 113 | 114 | > 如何使用定位或者浮动来进行布局?有什么优点或者缺点? 115 | 116 | > 设置了定位或者浮动的元素对标准文档流有什么影响? 117 | 118 | #### z-index 属性 119 | 120 | > z-index 对哪些元素起作用? 121 | 122 | > z-index 的层级关系是怎么样的? 123 | 124 | - z-index 与 Stacking Context 相关,详见 https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context 125 | 126 | #### 布局模型 127 | 128 | - 两列(三种)和三列布局(五种方式) 129 | - [Columns-Layout](http://codepen.io/Erichain/pen/mOZNxE) 130 | - 弹性布局 131 | - 流式布局 132 | - 瀑布流布局 133 | - 多列布局等高 134 | 135 | #### CSS 优先级 136 | 137 | - 行内样式 > 内联样式 > 外部样式,ID > Class > Element 138 | - 设置了 `!important` 的样式优先级更高 139 | 140 | #### Flexbox 141 | 142 | - [A Complete Guide to Flexbox](https://css-tricks.com/snippets/css/a-guide-to-flexbox/) 143 | 144 | > Flexbox 内部的元素会发生 margin collapse 吗? 145 | 146 | > Flexbox 的子元素可以设置 z-index 吗? 147 | 148 | #### 各个单位的区别(px, em, rem, 百分比, vw, vh, vmax, vmin) 149 | 150 | - [Understanding Font sizing in CSS: em – px – pt – percent – rem](https://www.narga.net/understanding-font-sizing-in-css-em-px-pt-percent-rem/) 151 | - [REM vs EM – The Great Debate](http://zellwk.com/blog/rem-vs-em/?utm_source=CSS-Weekly&utm_campaign=Issue-204&utm_medium=email) 152 | 153 | > rem 所相对的根元素是指哪一个元素? 154 | 155 | #### CSS Grid 156 | 157 | - [A Complete Guide to Grid](https://css-tricks.com/snippets/css/complete-guide-grid/) 158 | 159 | #### 居中 160 | 161 | - [CSS Center Complete](https://github.com/Erichain/css-center-complete) 162 | 163 | #### CSS 工程化 164 | 165 | - [OOCSS](http://oocss.org/) 166 | - [BEM](http://getbem.com/) 167 | - [SMACSS](https://smacss.com/) 168 | - [ITCSS](https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/) 169 | - [styled-components](https://www.styled-components.com/) 170 | 171 | [An Overview Of OOCSS BEM SMACSS](http://codetheory.in/an-overview-of-oocss-bem-smacss/) 172 | 173 | > 样式文件结构如何组织? 174 | 175 | **Some Questions** 176 | 177 | #### 如何将 div 与图片设置等宽,inline-block 元素之间的空隙如何解决 178 | 179 | - 设置父元素 `font-size` 为 0,再对里面的文字单独设置 `font-size` 180 | - 全兼容的样式解决方法 181 | 182 | ``` scss 183 | .finally-solve { 184 | // 根据不同字体字号或许需要做一定的调整 185 | letter-spacing: -4px; 186 | word-spacing: -4px; 187 | font-size: 0; 188 | } 189 | 190 | .finally-solve li { 191 | font-size: 16px; 192 | letter-spacing: normal; 193 | word-spacing: normal; 194 | display:inline-block; 195 | *display: inline; 196 | zoom:1; 197 | } 198 | ``` 199 | 200 | #### `text-overflow` 可以用来设置文本省略显示,那么,多行文本的省略显示如何设置? 201 | 202 | ``` scss 203 | .truncate-multiple-line($fontSize: 14px, $lineCount: 3, $lineHeight: 1.4) { 204 | font-size: $fontSize; 205 | line-height: $lineHeight; 206 | display: block; 207 | display: -webkit-box; 208 | overflow: hidden; 209 | max-height: calc($lineHeight * $lineCount * $fontSize); 210 | text-overflow: ellipsis; 211 | -webkit-line-clamp: $lineCount; 212 | -webkit-box-orient: vertical; 213 | } 214 | ``` 215 | 216 | --- 217 | 218 | ### JavaScript 部分 219 | 220 | > JavaScript 的历史发展? 221 | 222 | > 为什么要设计 JavaScript?为了解决什么问题? 223 | 224 | #### 变量 225 | 226 | - 使用 var 定义的全局变量不能使用 delete 删除 227 | - 无 var 创建的全局变量可以使用 delete 删除(为什么可以删除?全局变量与 Object.prototype 有什么关系?) 228 | - 隐式类型转换 229 | - 数字与字符串相加,结果为字符串 230 | - 数字与字符串相减,结果为数字 231 | - 比较变量的是否相同时,要采用 `===`,`==` 会发生隐式类型转换 232 | - NaN 与任何变量不相等(如何判断 `NaN` 呢?) 233 | 234 | > 变量是如何初始化的? 235 | 236 | > 类型转换的时候,如果同时存在 `toString` 和 `valueOf` 方法,会如何处理? 237 | 238 | #### 类型检测 239 | 240 | - `typeof` 241 | - `instanceof` 242 | - `Object.prototype.toString.apply()`(在 ES6 里面这个方法是否一定准确?) 243 | 244 | #### 对象 245 | 246 | > 对象可以怎么创建?有哪些方式?区别是什么?可以用到什么模式? 247 | 248 | > 在对象创建的时候设置好属性与动态添加属性有什么区别? 249 | 250 | - `hasOwnProperty, isPrototypeOf, propertyIsEnumerable` 251 | - 配置属性 (`configurable, enumerable, writable, value`) 252 | - 特性 253 | - 扩展: `isExtensible`, `preventExtensions` (是否可以添加新的属性) 254 | - 密封: `isSealed`, `seal` (是否可以删除属性,是否可以配置属性) 255 | - 冻结: `isFrozen`, `freeze` (所有属性是否可读可写) 256 | - 定义属性 257 | - `defineProperty`, `defineProperties` 258 | 259 | #### 函数 260 | 261 | > 普通函数与 arrow function 的区别? 262 | 263 | > 函数的默认参数和解构赋值的默认值工作机制?哪种情况下会采用默认值? 264 | 265 | - 柯里化 266 | - 概念:部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术(curry 的作用是什么?为什么需要 curry?) 267 | 268 | ``` javascript 269 | function currying(fn) { 270 | const args = Array.prototype.slice.call(arguments, 1); 271 | 272 | return function () { 273 | const newArgs = args.concat(Array.prototype.slice.call(arguments)); 274 | return fn.apply(null, newArgs); 275 | } 276 | } 277 | ``` 278 | - JavaScript 函数不存在重载,后定义的函数会覆盖先定义的函数 279 | - 函数调用模式 280 | - 方法调用 281 | - 函数调用 282 | - 构造器调用 283 | - apply 调用 284 | - 高阶函数 285 | - 高阶函数与普通函数有什么区别? 286 | - 为什么需要高阶函数? 287 | 288 | #### 作用域 289 | 290 | > JavaScript 的作用域链是怎么工作的? 291 | 292 | > JavaScript 的变量对象,活动对象,执行栈是怎么样的?与作用域有什么关系? 293 | 294 | > ES6 之后的版本中的作用域是什么样的? 295 | 296 | #### `new` 操作符的原理 297 | 298 | 使用 `new` 关键字来创建实例的时候,原理如下: 299 | 300 | - 首先,在构造函数内部使用 `Object.create(constructor.prototype)` 创建一个对象继承自构造函数 301 | - 然后,将构造函数的 `this` 指向改变到创建的对象 302 | - 最后,返回创建的对象 303 | 304 | ``` javascript 305 | function newFunc(ctor, ...args) { 306 | let proto = Object.create(ctor.prototype); 307 | ctor.call(proto, ...args); 308 | return proto; 309 | } 310 | ``` 311 | 312 | #### 闭包 313 | 314 | - 概念 315 | - 作用 316 | - 创建匿名执行函数 317 | - 缓存变量,防止被垃圾回收 318 | - 实现函数的封装 319 | - 应用场景 320 | - 内部函数访问外部函数的变量 321 | - 使用闭包代替全局变量 322 | - 封装相关功能 323 | - 回调函数 324 | - 创建私有变量和公有变量 325 | - 特性 326 | 327 | > 闭包函数内部的 this 值是如何变化的? 328 | 329 | > arrow function 内部的 this 值是怎么样的? 330 | 331 | #### this 332 | 333 | - 函数的 `this` 的值永远绑定在调用此函数的对象上 334 | - 可以使用 `apply`,`call` 或者 `bind` 改变 `this` 值的指向 335 | 336 | #### 原型 337 | 338 | - 原型链是如何工作的? 339 | - `__proto__` 属性与 `prototype` 的关系? 340 | - The prototype is a property on a constructor function that sets what will become the `__proto__` property on the constructed object. 341 | - https://hackernoon.com/understand-nodejs-javascript-object-inheritance-proto-prototype-class-9bd951700b29 342 | - 原型链有终点吗?终点是什么? 343 | - 如何设置对象的原型? 344 | 345 | #### 继承 346 | 347 | > 使用 `A.prototype = B.prototype` 与 `A.prototype = new B()` 与 `A.prototype = Object.create(B)` 这三种方式实现继承有什么区别? 348 | 349 | **借用构造函数** 350 | 351 | ``` javascript 352 | function Person(name) { 353 | this.name = name; 354 | } 355 | 356 | function man() { 357 | // 继承自 Person,可以选择是否传入参数 358 | Person.call(this, 'Erichain'); 359 | } 360 | ``` 361 | 362 | **组合继承** 363 | 364 | **原型式继承** 365 | 366 | **寄生式继承** 367 | 368 | **寄生组合式继承** 369 | 370 | - `new Object()` 和 `Object.create()` 的区别 371 | - `Object.create` 创建的对象直接从他的第一个参数继承,而 `new Object` 所创建的对象是从对象的原型上继承 372 | - 使用 `Object.create`,可以创建一个不继承于任何东西的对象,但是,如果设置 `someConstructor.prototype = null`,那么,这个新创建的对象会继承自 `Object.prototype` 373 | 374 | > 实例与构造函数与 Object.prototype 的原型之间的关系是怎么样的? 375 | 376 | #### ES6 Class 377 | 378 | > class 内部是如何处理原型和 this 值的绑定的? 379 | 380 | > super 的原理是什么? 381 | 382 | > static 关键字的原理? 383 | 384 | > 属性是添加到对象的哪个地方? 385 | 386 | #### 变量提升,函数声明提升 387 | 388 | - 函数声明优于变量声明 389 | - 函数声明会覆盖变量声明,但是不会覆盖变量赋值 390 | 391 | > ES6 还有变量提升吗?TDZ 是怎么形成的?会造成什么样的影响? 392 | 393 | #### 事件 394 | 395 | > 如何将事件绑定到 document 上? 396 | 397 | > React 是如何处理多个元素的事件的? 398 | 399 | > React 的事件对象和原生事件对象有什么区别? 400 | 401 | - 事件流的三个阶段 402 | - 事件捕获 403 | - 处于目标 404 | - 事件冒泡 405 | 406 | **跨浏览器事件处理函数** 407 | 408 | ``` javascript 409 | const EventUtil = { 410 | getEvent(event) { 411 | return event ? event : window.event; 412 | }, 413 | getTarget(event) { 414 | return event.target || event.srcElement; 415 | }, 416 | addHandler(elem, type, handler) { 417 | if (elem.addEventListener) { 418 | elem.addEventListener(type, handler, false); 419 | } else if (elem.attachEvent) { 420 | elem.attachEvent('on' + type, handler); 421 | } else { 422 | elem['on' + type] = handler; 423 | } 424 | }, 425 | preventDefault(event) { 426 | if (event.preventDefault) { 427 | event.preventDefault(); 428 | } else { 429 | event.returnValue = false; 430 | } 431 | }, 432 | stopPropagation(event) { 433 | if (event.stopPropagation) { 434 | event.stopPropagation(); 435 | } else { 436 | event.cancelable = true; 437 | } 438 | } 439 | }; 440 | ``` 441 | 442 | **事件代理** 443 | 444 | ``` vbscript-html 445 | 450 | ``` 451 | 452 | ``` javascript 453 | var links = document.getElementById('links'); 454 | 455 | // 使用之前定义的跨浏览器事件处理程序 456 | EventUtil.addHandler(links, 'click', function (event) { 457 | const target = EventUtil.getTarget(event); 458 | event = EventUtil.getEvent(event); 459 | 460 | switch (target.id) { 461 | case 'link1': 462 | // do something 463 | break; 464 | case 'link2': 465 | // do something 466 | break; 467 | case 'link3': 468 | // do something 469 | break; 470 | } 471 | }); 472 | ``` 473 | 474 | > 为什么要使用事件代理?有什么好处? 475 | 476 | - 事件函数的参数(注意 `addEventListener()` 的最后一个参数,如果为 false 表示在冒泡阶段获取事件,如果为 true,表示在事件捕获阶段获取事件) 477 | 478 | #### promise 479 | 480 | - [Javascript Promise 迷你书](http://liubin.org/promises-book/) 481 | - [JavaScript Promise API](http://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=402552108&idx=1&sn=b0d4d986984a45276c6bbbf386c04790&scene=0#wechat_redirect) 482 | - https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html 483 | 484 | > `.catch` 与 `.then(null, function () {})` 的区别? 485 | 486 | > 在 `.then` 中返回一个函数与直接执行一个函数的区别? 487 | 488 | > promise 的 `.then` 与 setTimeout 的回调的执行顺序? 489 | 490 | > promise 有什么优缺点? 491 | 492 | #### generator 493 | 494 | > generator 用来干什么? 495 | 496 | > 如何使用 generator 来创建异步行为? 497 | 498 | > 使用 generator 实现 async 和 await? 499 | 500 | > 在 yield 后面执行另外一个 generator 是怎么工作的? 501 | 502 | #### async and await 503 | 504 | #### Set && Map 505 | 506 | > weak Set(Map) 与 Set(Map) 的区别? 507 | 508 | > Map 与对象的区别? 509 | 510 | > Set 与 Map 的适用场景? 511 | 512 | #### Decorator 513 | 514 | > 什么是 Decorator?如何使用?可以用来干什么? 515 | 516 | > 原理是什么? 517 | 518 | > 与 React 可以怎么结合?与其他框架呢? 519 | 520 | #### JavaScript 中的 Event Loop,Job Queue 与 Task,MicroTask 521 | 522 | > 什么是 Event Loop?什么是 Job Queue?什么是 Task,什么是 MicroTask? 523 | 524 | > Event Loop 的工作流程是怎么样的?与执行栈的关系? 525 | 526 | > Event Loop,Job,Task 的执行顺序是怎么样的? 527 | 528 | #### 性能优化 529 | 530 | > React 是怎么批量更新 DOM 的? 531 | 532 | > CDN 是什么?如何应用?有什么好处? 533 | 534 | - 操作 DOM 的时候一定要缓存变量,避免发生大量的重排重绘 535 | - 异步加载 JavaScript 文件 536 | - 使用 `document.write()` 537 | - 动态改变已有 script 标签的 `src` 属性 538 | - 使用 DOM 方法动态创建 script 元素 539 | - 使用 Ajax 获取脚本内容再加载 540 | - 在 script 标签中使用 `defer` 以及 `async` 属性(defer 和 async 的区别?) 541 | - 按需加载 542 | - 合并文件 543 | - 图片懒加载 544 | - [懒加载——网页图片的加载技术](https://segmentfault.com/a/1190000003881643) 545 | - [Lazy Load Plugin for jQuery](https://github.com/tuupola/jquery_lazyload) 546 | - 预加载 547 | - [3 Ways to Preload Images with CSS, JavaScript, or Ajax](https://perishablepress.com/3-ways-preload-images-css-javascript-ajax/) 548 | - [Prefetching, preloading, prebrowsing](https://css-tricks.com/prefetching-preloading-prebrowsing/) 549 | - prefetch 550 | - [HTML5 Prefetch](https://medium.com/@luisvieira_gmr/html5-prefetch-1e54f6dda15d) 551 | - 函数节流 552 | - [浅谈函数节流](http://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=402737833&idx=2&sn=c051cfa8a5ea025da9129295d666743a&scene=0#wechat_redirect) 553 | - 函数式,抽象,组件复用,减少无用代码 554 | 555 | #### 内存管理 556 | 557 | > 引用计数是怎么工作的?有什么弊端? 558 | 559 | - 引用计数 560 | 561 | ``` javascript 562 | // 出现循环引用的例子 563 | function loopRef() { 564 | const objectA = {}; 565 | const objectB = {}; 566 | 567 | objectA.someOtherObject = objectB; 568 | objectB.anotherObject = objectA; 569 | } 570 | ``` 571 | 572 | - 标记清除,详细可查看 https://blog.sessionstack.com/how-javascript-works-memory-management-how-to-handle-4-common-memory-leaks-3f28b94cfbec 573 | 574 | - 内存泄漏 575 | - setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏 576 | - 循环引用 577 | - DOM 元素的引用可能会触发内存无法被回收 578 | 579 | #### XMLHttpRequest 对象 580 | 581 | - 一段比较完整的使用原生 JavaScript 实现 ajax 请求方法 582 | 583 | ``` javascript 584 | function createRequestObject() { 585 | if (window.XMLHttpRequest) { 586 | return new XMLHttpRequest(); 587 | } 588 | 589 | // 针对IE 590 | else if (window.ActiveXObject) { 591 | return new ActiveXObject('Microsoft.XMLHTTP'); 592 | } 593 | } 594 | 595 | // 请求的回调函数 596 | function requestCallBack() { 597 | if (request.readyState === 4 && request.status === 200) { 598 | console.log(request.responseText); 599 | } 600 | } 601 | 602 | const request = createRequestObject(); 603 | 604 | request.onreadystatechange = requestCallBack; 605 | // open 函数的三个参数分别是请求的方法, 请求的地址, 是否异步 (true 表示异步) 606 | request.open('POST', url, true); 607 | request.send(null); 608 | ``` 609 | 610 | #### `Array.prototype.slice.call()`原理 611 | 612 | - [how does Array.prototype.slice.call() work?](http://stackoverflow.com/questions/7056925/how-does-array-prototype-slice-call-work) 613 | 614 | #### RESTful 615 | 616 | #### 尾递归 617 | 618 | - [尾调用优化](http://es6.ruanyifeng.com/#docs/function#尾调用优化) 619 | 620 | > 尾递归的原理是什么?为什么能够达到性能优化? 621 | 622 | > 所有的函数都能进行尾递归优化吗?尾递归优化的条件是什么? 623 | 624 | --- 625 | 626 | ### 浏览器部分 627 | 628 | #### 浏览器针对页面的渲染过程 629 | 630 | - [How browsers work](http://taligarsiel.com/Projects/howbrowserswork1.htm#Introduction) 631 | 632 | > 设置了 `display: none` 的元素节点会被渲染吗?设置了 `visible: hidden` 的元素呢? 633 | 634 | > 外部 CSS,内联 CSS,行内 CSS 的加载顺序是怎么样的? 635 | 636 | > 渲染分为哪几个阶段?每一个阶段具体做了什么? 637 | 638 | > 重排和重绘的区别? 639 | 640 | > 什么情况会触发重排?什么情况会触发重绘? 641 | 642 | > 如何针对浏览器的渲染过程就进行优化? 643 | 644 | #### 关于浏览器缓存 645 | 646 | - [浅谈Web缓存](http://www.alloyteam.com/2016/03/discussion-on-web-caching/) 647 | - cookie 由服务器生成,可设置失效时间。如果是浏览器端生成的 cookie,则在浏览器关闭之后失效;而 localStorage 除非被清除,否则永久保存,sessionStorage 则在关闭浏览器或者页面之后清除 648 | - cookie 的大小为 4k 左右,localStorage 和 sessionStorage 的大小一般为5MB 649 | - 与服务器通信的时候,cookie 每次都会携带在 http 头中,但是其他两个不参与服务器通信 650 | - cookie 中最好不要放置任何的明文的东西,其他两个的数据如果提交到服务器一定要校验 651 | - https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching 652 | - https://www.keycdn.com/support/304-not-modified/ 653 | 654 | > sessionStorage, cookie, localStorage 的适用场景? 655 | 656 | --- 657 | 658 | ### 前端安全 659 | 660 | - 防止 XSS (跨站点脚本)攻击 661 | - [XSS Prevention Rules](https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#XSS_Prevention_Rules) 662 | - 防止 CSRF (跨站点伪造请求攻击) 663 | - [CSRF Specific Defense](https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)_Prevention_Cheat_Sheet#CSRF_Specific_Defense) 664 | - 防止跨 iframe 攻击 665 | - DDoS 攻击 666 | 667 | > 从攻击类别的概念,分类,和结果进行说明? 668 | 669 | > 防止方式有哪些?每一种是怎么样的? 670 | 671 | --- 672 | 673 | ### 构建工具 674 | 675 | ### Webpack 676 | 677 | - css loader 与 style loader 的区别 678 | - 减少 Webpack build 时间 679 | - DllPlugin,HappyPack 的使用 680 | 681 | > webpack 默认对代码的处理? 682 | 683 | > DllPlugin 的工作原理? 684 | 685 | > webpack 的性能可以怎么优化? 686 | 687 | #### gulp 流与管道的概念 688 | 689 | > Gulp 的工作原理 690 | 691 | - Unix 流 692 | - 管道 693 | - 管道是一个固定大小的缓冲区 694 | - 从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛弃,释放空间以便写更多的数据 695 | - 可以把一个进程的标准输出流与另一个进程的标准输入流连接起来 696 | 697 | > 构建系统如何选择? 698 | 699 | > Webpack 和 Gulp 分别适用于什么样的项目?他们有什么区别? 700 | 701 | --- 702 | 703 | ### 网络知识部分 704 | 705 | #### 同源策略 706 | 707 | - 同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。指一段脚本只能读取来自同一来源的窗口和文档的属性 708 | 709 | > 什么是同源? 710 | 711 | #### 跨域处理 CORS (方法和区别) 712 | 713 | - JSONP 714 | - `document.domain` 715 | - `window.name` 716 | - HTML5 的 `window.postMessage` 和 `window.onmessage` 717 | 718 | #### HTTP 基本知识 719 | 720 | - [前端进阶--让你升级的网络知识](http://mp.weixin.qq.com/s?__biz=MjM5OTkwOTA5Mw==&mid=409908127&idx=1&sn=56a1110d6c22571c04ce13e889aeac87&scene=0#wechat_redirect) 721 | - 三次握手 722 | - 客户端发起连接试探 723 | - 服务端接收到试探请求,向客户端发送确认消息 724 | - 客户端得到服务端的确认消息之后,再次向服务端发送确认消息 725 | - 四次挥手 726 | - 一次完整的 HTTP 请求是怎么样的 727 | - 域名解析 728 | - TCP 三次握手 729 | - 发起 http 请求 730 | - 服务器端响应 http 请求,客户端得到 html 代码 731 | - 浏览器解析 html 代码,并请求 html 代码中的资源 732 | - 浏览器对页面进行渲染呈现给用户 733 | - Get 与 Post 的区别 734 | - [99%的人都理解错了 HTTP 中 GET 与 POST 的区别](http://mp.weixin.qq.com/s?__biz=MzI3NzIzMzg3Mw==&mid=100000054&idx=1&sn=71f6c214f3833d9ca20b9f7dcd9d33e4#rd&utm_source=tuicool&utm_medium=referral) 735 | 736 | > cookie 工作机制是怎么样的? 737 | 738 | > 如何在 header 中对浏览器的缓存进行设置? 739 | 740 | > 重定向是如何工作的? 741 | 742 | > 什么是长连接和短连接? 743 | 744 | #### HTTPS 745 | 746 | #### HTTP/2 747 | 748 | > HTTP/2 有哪些特性?与 HTTP/1.1 的区别与联系? 749 | 750 | #### WebSocket 751 | 752 | > WebSocket 协议是什么? 753 | 754 | > 如何通过原生的 WebSocket 来建立通信? 755 | 756 | > WebSocket 通信的 Request Header 与 HTTP 有什么区别? 757 | 758 | > WebSocket 的长连接和 HTTP/2 的长连接有什么区别? 759 | 760 | --- 761 | 762 | ### 框架相关知识 763 | 764 | #### jQuery 765 | 766 | - [jQuery Tips Everyone Should Know](https://github.com/Erichain/jquery-tips-everyone-should-know) 767 | - 如何组织 jQuery 项目的代码结构 768 | - [Best Practice to Organize Javascript Library & CSS Folder Structure](http://stackoverflow.com/questions/24199004/best-practice-to-organize-javascript-library-css-folder-structure) 769 | 770 | #### Vue 771 | 772 | > 思考: 773 | 774 | > 为什么要创建 Vue? 775 | 776 | > Vue 的设计理念和其他框架有什么区别和联系? 777 | 778 | > Vue 适用于什么样的项目? 779 | 780 | > Vue 是否能够与其他框架或者库兼容? 781 | 782 | > Vue 的性能怎么样?与其他框架对比呢? 783 | 784 | > Vue 的基本原理,生命周期? 785 | 786 | > Vuex 是怎么工作的?为什么要使用 Vuex? 787 | 788 | > Vuex 与其他的状态管理工具的区别? 789 | 790 | - `v-if`与`v-show`的区别 791 | - `v-show`控制节点的`display`属性,`v-if`为true的时候节点才会存在于DOM中 792 | - 频繁切换`v-show`较好,如果在运行时条件不大可能改变`v-if`较好 793 | - Vue 如何为 input 的 onchange 事件添加延时 794 | - `$emit`, `$broadcast`, `$dispatch` 的区别 795 | - 如何在两个同级的 component 之间通信 796 | - Vuex 797 | 798 | #### React 799 | 800 | > 思考: 801 | 802 | > 已经有那么多的前端框架了?为什么要设计 React? 803 | 804 | > React 适用于什么样的项目? 805 | 806 | > React 的性能如何?如何进行优化? 807 | 808 | > React 的基本原理,生命周期? 809 | 810 | > Redux 的设计理念? 811 | 812 | > Redux 的原理? 813 | 814 | > Redux 有什么替代品? 815 | 816 | - Virtual DOM 如何实现? 817 | - 生命周期 818 | - 性能优化,如何减少不必要的更新 819 | - 组件之间通信,数据流动 820 | - `setState` 的用法,优点缺点 821 | - `Container Component` 和 `Presentational Component` 822 | - Redux 思想 823 | 824 | > 多个框架之间如何选择? 825 | 826 | > React,Vue,Angular 之间的对比和联系? 827 | 828 | > Vue 的 DOM diff 与 React 的 Reconciler 有什么区别? 829 | 830 | > 前端状态管理? 831 | 832 | > - https://medium.com/@vyaron/who-needs-state-management-anyways-55e6d1c74239 833 | 834 | > Redux vs Flux vs Vuex vs RxJS 835 | 836 | > - https://edgecoders.com/the-difference-between-flux-and-redux-71d31b118c1 837 | > - https://medium.com/@Musclenun/redux-vs-vuex-9b682529c36 838 | > 839 | 840 | > MVC 与 MVVM 与 MVP? 841 | 842 | --- 843 | 844 | ### Practices 845 | 846 | #### 浏览器的多个标签页之间如何通信 847 | 848 | - [Javascript communication between browser tabs/windows](http://stackoverflow.com/questions/4079280/javascript-communication-between-browser-tabs-windows) 849 | 850 | #### 数组降维 851 | 852 | - [优雅的数组降维——Javascript中apply方法的妙用](http://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=402262046&idx=1&sn=bdcdcb93392c147a7b5449bd2d639a3b&scene=0#wechat_redirect) 853 | 854 | #### 对象深度复制 855 | 856 | ``` javascript 857 | function deepClone(resource) { 858 | if (Array.isArray(resource)) { 859 | let dest = []; 860 | let length = resource.length; 861 | while (length--) { 862 | console.log(length) 863 | dest[length] = deepClone(resource[length]) 864 | } 865 | return dest 866 | } else if (typeof resource === 'object') { 867 | let dest = {} 868 | for (let key in resource) { 869 | if (resource.hasOwnProperty(key)) { 870 | dest[key] = deepClone(resource[key]) 871 | } 872 | } 873 | return dest 874 | } 875 | return resource 876 | } 877 | ``` 878 | 879 | #### 排序 880 | 881 | - 快速排序 882 | 883 | ``` javascript 884 | function quickSort(list) { 885 | if (list.length < 2) { 886 | return list 887 | } 888 | 889 | const base = list[0]; 890 | const left = [] 891 | const right = [] 892 | 893 | for (let item of list.slice(1)) { 894 | if (item <= base) { 895 | left.push(item) 896 | } else { 897 | right.push(item) 898 | } 899 | } 900 | 901 | return quickSort(left).concat(base, quickSort(right)) 902 | } 903 | ``` 904 | 905 | - 冒泡排序 906 | 907 | ``` javascript 908 | function bubbleSort(list) { 909 | if (list.length < 2) { 910 | return list; 911 | } 912 | 913 | let len = list.length; 914 | 915 | while (len) { 916 | for (let i = 0; i < len - 1; i++) { 917 | if (list[i] > list[i + 1]) { 918 | [list[i], list[i + 1]] = [list[i + 1], list[i]]; 919 | } 920 | } 921 | 922 | len--; 923 | } 924 | 925 | return list; 926 | } 927 | ``` 928 | 929 | - 插入排序 930 | 931 | ``` javascript 932 | function insertionSort(array) { 933 | let length = array.length; 934 | let i, j; 935 | 936 | for(i = 1; i < length; i++) { 937 | let temp = array[i]; 938 | 939 | for(j = i - 1; j >= 0 && array[j] > temp; j--) { 940 | array[j + 1] = array[j]; 941 | } 942 | 943 | array[j + 1] = temp; 944 | } 945 | 946 | return array; 947 | } 948 | ``` 949 | 950 | - 合并排序 951 | 952 | ``` javascript 953 | function mergeSort(list) { 954 | if (list.length < 2) { 955 | return list 956 | } 957 | 958 | const mid = Math.floor(list.length / 2) 959 | const left = mergeSort(list.slice(0, mid)) 960 | const right = mergeSort(list.slice(mid)) 961 | 962 | return mergeSub(left, right) 963 | } 964 | 965 | function mergeSub(node1, node2) { 966 | const result = [] 967 | 968 | while (node1.length > 0 && node2.length > 0) { 969 | result.push(node1[0] < node2[0] ? node1.shift() : node2.shift()) 970 | } 971 | 972 | return result.concat(node1.length ? node1 : node2) 973 | } 974 | ``` 975 | 976 | #### 去除首尾空格 977 | 978 | ``` javascript 979 | function removePlace(str) { 980 | const reg = /(^s*)|(s*)$/; 981 | 982 | if (str && typeof str === 'string') { 983 | return str.replace(reg, ''); 984 | } 985 | } 986 | ``` 987 | 988 | #### 使用 JavaScript 计算两个日期的时间差 989 | 990 | - [JavaScript: DateDiff & DateMeasure: Calculate days, hours, minutes, seconds between two Dates](https://gist.github.com/remino/1563963) 991 | 992 | #### 阶乘 993 | 994 | ``` javascript 995 | // 普通递归方式 996 | function factorial(n) { 997 | if (n === 1) { 998 | return 1; 999 | } 1000 | return n * factorial(n - 1); 1001 | } 1002 | 1003 | // 尾递归方式 1004 | function factorial(n, result) { 1005 | if (n === 1) { 1006 | return 1; 1007 | } 1008 | return factorial(n - 1, n * result); 1009 | } 1010 | ``` 1011 | 1012 | #### Fibonacci 数列 1013 | 1014 | ``` javascript 1015 | // 普通递归方式 1016 | function fibonacci(n) { 1017 | if (n <=1) { 1018 | return 1; 1019 | } 1020 | return fibonacci(n - 1) + fibonacci(n - 2); 1021 | } 1022 | 1023 | // 尾递归方式 1024 | function fibonacci1(n, ac = 1, ac2 = 1) { 1025 | if (n <= 1) { 1026 | return 1; 1027 | } 1028 | return fibonacci1(n - 1, ac2, ac + ac2); 1029 | } 1030 | ``` 1031 | 1032 | #### 广度优先 1033 | 1034 | #### 深度优先 1035 | 1036 | #### 动态规划 1037 | 1038 | #### 最短路径 1039 | 1040 | #### 图 1041 | 1042 | --- 1043 | 1044 | ### 插件编写 1045 | 1046 | > 关于某些插件编写,可参考:[jQuery插件库](http://www.jq22.com) 1047 | 1048 | #### 焦点轮播图 Carousel 1049 | 1050 | #### 网页弹出层 Modal 1051 | 1052 | #### 多级菜单 1053 | 1054 | #### Tab 切换 1055 | 1056 | #### Lightbox 1057 | 1058 | #### 模板引擎 1059 | 1060 | #### 路由 1061 | 1062 | #### 数据双向绑定 1063 | 1064 | #### 拖动 1065 | 1066 | --- 1067 | 1068 | ### JavaScript 模块化 1069 | 1070 | #### CommonJS 1071 | 1072 | - 同步的方式加载模块,服务器优先 1073 | - 使用`require`加载模块,使用`module.exports`定义模块 1074 | 1075 | #### AMD 1076 | 1077 | - 浏览器优先的方式,通过异步加载的方式完成任务 1078 | - 使用`define(['module'], function ( module ) {})`加载模块 1079 | - 不兼容 io、文件系统(filesystem)和其它通过 CommonJS 实现的面向服务器的功能 1080 | - 推崇依赖前置 1081 | - 对于依赖的模块提前执行 1082 | 1083 | --- 1084 | 1085 | ### NodeJS 1086 | 1087 | ### HTML5 1088 | 1089 | > HTML5 新增了哪些功能? 1090 | 1091 | > 为什么 HTML5 能够引起那么多的反响? 1092 | 1093 | ### WebSocket 1094 | 1095 | ### Progressive Web Application 1096 | 1097 | > 什么是 PWA,与普通应用的区别是什么? 1098 | 1099 | > 它采用了什么技术? 1100 | 1101 | ### Canvas 1102 | 1103 | ### Functional Programming 1104 | 1105 | ### Design Patterns 1106 | 1107 | > 各个设计模式的定义,适用场景,分别为了解决什么样的问题? 1108 | 1109 | ### Data Structure 1110 | 1111 | ## Contribution 1112 | 1113 | 如果对内容有什么好的建议以及有新的知识点, 欢迎提交 Pull Request. 1114 | 1115 | ## License 1116 | 1117 | Release under the MIT License. 1118 | --------------------------------------------------------------------------------