中级前端知识点提要
标签(空格分隔): JavaScript HTML 基础
1 Restful API
Representational State Transfer(表现层状态转移)。
URL定位资源,用HTTP动词(GET POST PUT DELETE)描述操作。
资源、统一接口、URI、无状态。
应该将API的版本号放入URL;URL中只能有名词而不能有动词;API应该提供参数。
2 CommonJS/AMD/CMD/ES6 Module
2.1 CommonJS
是Node.js模块系统具体实现的基石
- JavaScript: not just for browsers any more!
为解决JavaScript没有模块系统,标准库较少,缺乏包管理工具。 - 定义的模块
- 模块引用(require)
- 模块定义(exports)
- 模块标识(module)
- 运行环境
- 服务端JavaScript应用程序
- 命令行工具
- 图形界面应用程序
- 混合应用程序
- 特点
- 所有代码运行在模块作用域,不会污染全局作用域
- 模块可以第一次加载,只在第一次加载时运行一次
- 模块按照其在代码中出现的顺序加载(同步)
- 包结构
package.json
包描述文件,存在于包根目录下bin
存放可执行二进制文件的目录lib
存放js代码的目录doc
存放文档的目录test
存放单元测试用例代码的目录
2.2 AMD Asynchronous Module Definition(异步模块定义)
浏览器端的模块,不能采用“同步加载(synchronous)”,只能采用“异步加载(asynchronous)”。这就是AMD规范诞生的背景。
典型代表require.js
-
模块定义
define(id?: String, dependencies?: String, factory: Function|Object);
id
是模块的名字。dependencies
是依赖模块列表,默认值是["require", "exports", "module"]
。factory
是模块的具体实现。
-
模块加载
require([module], callback);
-
require.js
- 实现js文件的异步加载,避免网页失去响应。
- 管理模块之间的依赖性,便于代码的编写和维护。
2.3 CMD Common Module Definition(通用模块定义)
一个模块就是一个文件,依赖就近;懒加载(延迟执行);没有全局require。
典型SeaJS
-
模块定义
define(factory);
-
factory
是函数时,表示是模块的构造方法。define(function(require, exports, module) { // 模块代码 });
-
-
SeaJS和RequireJS的差异
- 定位有差异
RequireJS目的是同时作为浏览器端和服务器端的模块加载器。
SeaJS专注于浏览器端。 - 遵循规范不同
RequireJS遵循AMD规范。
SeaJS遵循CMD规范,更贴近CommonJS和Node Modules。 - 执行方式不同(AMD和CMD的差异)
RequireJS依赖前置,预执行(异步加载:依赖先执行)(RequireJS从2.0开始,也改成可以延迟执行)。
SeaJS依赖就近,懒执行(运行到需加载,根据顺序执行)。 - 对开发调试的支持有差异
SeaJS有更多的调试插件。 - 插件机制不同
RequireJS采取源码中预留接口形式,插件类型比较单一。
SeaJS采取通用事件机制,插件类型更丰富。
- 定位有差异
2.4 ES6 Module
ES6模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。
这一点不同于CommonJS和AMD模块。因此也不能实现动态加载(提案import([path])
用于解决这个问题)。
一个文件就是一个模块。该文件内部的所有变量,外部无法获取,使用export
关键字输出指定变量。
-
export
命令-
使用
as
关键字重命名导出变量。 -
对外的接口,必须与模块内部的变量建立一一对应的关系。比如:
export 1; // 报错 var m = 1; export m; // 报错 // 因为1只是一个值不是接口 // 正确应该是这样 export var m = 1; export { m };
-
-
import
命令-
使用
as
关键字重命名变量名。 -
import
命令输入的变量是只读的,不能改写接口(比如重新赋值);但是如果变量是个对象,修改属性是允许的(不建议这么做)。 -
from
关键字指定模块文件的位置(相对/绝对路径);.js
后缀可以省略。 -
import
命令具有提升效果,率先执行。 -
import
命令是静态执行,不能使用表达式、变量或者在结构语句中。 -
重复
import
只执行一次。 -
使用
*
实现所有导出值都加载在as
的对象上,比如:import * as obj from './module'; obj.a();
虽然
obj
是个对象,但是不允许修改它的属性,比如:obj.a = 'Hello'; // 报错
。 -
import
默认输出(export default
)时候不需要大括号,而其它的则需要。 -
想要在一条
import
语句中同时导入默认接口export default
和其它接口,可以用_
实现:import _, { momduleA, moduleB as moduleC } from './module';
-
-
export default
命令-
为用户指定默认输出。
-
其它模块加载该模块时,
import
命令可以为该匿名导出接口指定任意名字(即便export
时候是具名接口,在外部模块视为无效)。export default function foo() { }; import bar from './foo';
-
一个模块只能使用一次
export default
。 -
本质上
export default
就是输出一个叫做default
的变量或方法,然后允许你为它取任意名字。 -
export default
后面不能跟变量声明语句。 -
可以直接把一个值或变量
export default
,比如:export default 123; var a = 1; export default a;
-
-
export
与import
复合写法export { foo as bar } from './module'; // 接口改名转发 export { default } from './module'; // 转发默认接口 export { foo as default } from './module'; // 转发具名接口为默认接口 export { default as foo } from './module'; // 转发默认接口为具名接口
-
模块的继承
假设有一个
moduleA
模块,继承了moduleB
模块。// @file moduleA.js export * from 'moduleB'; export var e = 123; export default function() { };
export *
表示输出moduleB
的所有属性和方法,且忽略default
方法。 -
跨模块常量
建立一个
constants
文件夹,各个文件保存不同类型的常量,加一个index.js
来合并(转发)这些常量,使用的时候直接加载index.js
就可以了。 -
import()
提案-
用于解决无法动态加载模块的问题。
-
返回一个
Promise
对象。 -
import()
与Node的require方法差异在于:异步加载。 -
使用场景:按需加载、条件加载、动态模块路径。
-
加载完成后模块会作为一个对象成为
then
方法的参数。
可以使用对象解构赋值语法:import('module.js').then((export1, export2) => { // TODO });
-
同时加载多个模块
promise.all([ import('moduleA.js'), import('moduleB.js') ]).then(([moduleA, moduleB]) => { // TODO });
-
3 三大框架底层原理
3.1 Angular2+
- Angular2+是通过
zone.js
代理原生异步事件,事件发生触发tick()
去执行变化检测。 - Angular2+脏值检测(存储所有变量的值,每当有变量发生变化时,就将所有变量的旧值与新值比较,不相等就说明检测到变化),Angular每个组件都有自己的变化检测器;数据流从上到下(从根组件向下)。
3.2 Vue2+
- Vue是通过
Object.defineProperty()
来劫持数据的getter/setter
实现数据绑定。 - 实现一个数据监听器
observer
,对所有属性进行监听,有变化通知订阅者。 - 实现一个指令解析器
compile
,根据指令模板替换数据。 - 实现一个
watcher
连接以上两者的联系。
3.3 React
- Virtual DOM(虚拟DOM)。
4 跨域
CORS Cross-Origin Resource Sharing(跨域资源共享)。
它允许向跨源服务器发出XHR请求。
实现关键是服务器实现了CORS接口,就可以跨源通信。
4.1 简单请求
同时满足两个条件:
-
请求方法时以下三种之一
- HEAD
- GET
- POST
-
HTTP头信息不超出以下几种字段
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type(仅限值为application/x-www-form-urlencoded、multipart/form-data、text/plain)。
4.1.1 基本流程
浏览器请求时,在head信息中增加Origin
字段。
服务器根据Origin
指定的源,判断是否在许可范围内:
- 如果不在
Response Headers
中就不会有Access-Control-Allow-Origin
字段,触发XHR的onerror
回调。 - 如果在,会返回以下字段:
Access-Control-Allow-Origin: https://www.google.com // 必有字段, *(接受任意域名)或者是Request Headers里的Origin字段值
Access-Control-Allow-Credentials: true // 可选字段,表示允许发送cookie;如果不发送删除该字段
Access-Control-Expose-Headers: FooBar // 可选字段,XHR的getResponseHeader方法只能拿到Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma字段,想要其他字段在这里指定
Content-Type: text/html;charset=utf-8
4.1.2 withCredentials属性
允许CORS发送cookie
和http
认证信息,服务器需要设置Access-Control-Allow-Credentials
为true
;浏览器端XHR请求需要设置:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
如果要发送cookie
,Access-Control-Allow-Origin
不能设置为*
,必须指定明确,与请求网页一致的域名。同时,cookie
依旧同源策略,只有服务器域名设置的cookie
才会上传,浏览器端document.cookie
无法读取服务器域名下的cookie
。
4.2 非简单请求
非简单请求,会在正式通信之前增加一次HTTP查询请求,叫“预检请求(preflight)”。
用以询问服务器当前浏览器端网页所在域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段,只有得到肯定答复才会发起正式请求,否则报错。
-
Preflight请求方法是OPTIONS,表示询问请求。
关键字段Origin
。Access-Control-Request-Method // 必有字段 表示CORS请求的HTTP方法 Access-Control-Request-Headers // 逗号分隔字符串,指定CORS请求额外发送头信息的字段
-
Preflight请求的Response。
Access-Control-Allow-Origin // 表示允许请求的源 Access-Control-Allow-Methods // 必有字段,逗号分隔字符串,表示服务器支持的跨域请求的所有方法 Access-Control-Allow-Headers // 如果request时包含Access-Control-Request-Headers字段,则此response字段必有。逗号分隔字符串,表示服务器支持的所有头信息字段 Access-Control-Allow-Credentials // 是否允许cookie Access-Control-Max-Age // 可选,单位是秒,表示该条回应缓存时间
-
浏览器正常请求和回应
与简单请求一致。
4.3 与JSONP跨域的区别
JSONP只支持GET请求,其优势在于支持老版本浏览器。
5 同源策略
Same-Origin Policy(同源策略)
1995年网景公司引入浏览器。目的是保证用户信息安全,防止恶意网站窃取数据。
- 概念
- 协议相同
- 域名相同
- 端口相同
- 限制范围
cookie
localStorage
和indexDB
- DOM
- Ajax请求
- 规避限制
-
cookie
如果一个网站一级域名相同,二级域名不同。两个网页设置相同的document.domain
共享cookie。 -
iframe
-
片段标识符
Fragment Indentifier指的是URL中#
后面的部分
父窗口可以把信息写入子窗口的片段标识符var src = './page-1.html' + '#test'; setTimeout(() => { document.getElementById('iframe').src = src; }, 1000);
子窗口通过监听
hashchange
事件得到通知:window.onhashchange = function() { console.log('Page-1 print fragment identifier: ', window.location.hash); }
同样的,子窗口也可以改变父窗口的片段标识符:
parent.location.href = target + '#' + hash;
demo如图所示:
-
window.name
无论同源,只要在一个窗口里,前一个网页设置了这个属性,后一个网页就可以读取它。 -
window.postMessage
HTML5新API:跨文档通信(Cross-Document Messaging)。
它允许跨窗口通信,不论是否同源。
-
-
ajax
JSONP
WebSocket
CORS
-
6 闭包
闭包是函数和声明该函数的词法环境的组合。
闭包(closure)就是能够读取其它函数内部变量的函数(定义在一个函数内部的函数)。
本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。
- 作用
- 读取函数内部的变量
- 让这些变量的值始终保持在内存中
- 实现私有属性
- 不能滥用
- 闭包在处理速度和内存消耗方面对脚本性能具有负面影响
- 造成内存溢出
7 面向对象
面向对象程序设置(OOP)的目的是在编程中促进更好的灵活性和可维护性、
-
Namesoace(命名空间)
一个独特、应用相关名字的名称下捆绑所有功能的容器。
在js中,命名空间只是一个包含方法、属性、对象的对象。 -
Class(类)
定义对象的特征。它是对象的属性和方法的模板定义。
js通过定义函数来声明类(ES6之前)。 -
Object(对象)
类的一个实例。
js中的每个对象都是Object
对象的实例且继承它所有的属性和方法。 -
Property(属性)
对象的特征。
通过this
关键字调用类中的属性。 -
Method(方法)
对象的能力(方法)。
将函数赋值给类的prototype
属性。 -
Constructor(构造函数)
对象初始化的瞬间,被调用的方法。通常它的名字与包含它的类一致。 -
Inheritance(继承)
一个类可以继承另一个类的特征。// 子类 // 调用父类构造器,确保(使用Function#call)“this”在调用过程中设置正确 Parent.call(this, args); // 同时需要显示的继承父类的prototype Child.prototype = Object.create(Parent.prototype); // 设置constructor属性指向子类 Child.prototype.contructor = Child; // Object.create()仅支持现代浏览器(IE9+),有shim方案 functuon createObject(proto) { function ctor() {} ctor.prototype = proto; return new ctor(); }
通用方法:
function extend(Child, Parent) { var F = function() {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.prototype.constructor = Child; Child.uber = Parent.prototype; // uber 是在模拟 class 时用来表示 super 的(因为super是关键字所以不能直接用) }
-
Encapsulation(封装)
一种把数据和相关方法绑定在一起使用的方法。 -
Abstraction(抽象)
结合复杂的继承、方法、属性的对象能够模拟现实的模型。 -
Polymorphism(多态)
多意思是“许多”,态是“形态”。不同类可以定义相同的方法或属性。
8 继承与原型链
js只有一种结构:对象。每个实例对象(object)都有一个私有属性(称之为[[prototype]])指向它的原型对象(prototype)。该原型对象也有一个自己的原型对象,层层向上直到一个对象的原型对象为null
。根据定义,null
没有原型,并作为这个原型链中的最后一环节。
几乎所有的js中的对象都是位于原型链顶端的Object
的实例。
prototype
属性属于构造函数,这个属性包含一个对象(prototype对象),所有实例对象需要共享的属性和方法,都放在这对象里;那些不需要共享的属性和方法,放在狗仔函数里。
9 前端优化
- Content
-
减少HTTP请求次数
- 合并文件
- CSS Sprites(雪碧图)
- image maps
- inline images 使用
data:url scheme
内联图片
-
减少DNS查询
缓存DNS查询。 -
避免重定向
最浪费的重定向发生在url尾部slash(/)缺失。 -
使Ajax可以缓存
Add an Expires or a Cache-Control Header. -
延迟加载组件
考虑什么是页面初始化必须的,剩下的内容和组件都可以延迟加载。包括隐藏的内容、折叠起来的图片等等。 -
预加载组件
- 无条件(Unconditional )预加载
一旦onload
触发,你立即获取另外的组件。比如谷歌会在主页这样加载搜索结果页面用到的雪碧图。 - 有条件(Conditional)预加载
基于用户动作,推测用户下一步会去哪里并加载相应的组件。 - 预期的(Anticipated)预加载
You can mitigate this side effect by preloading some components before you even launched the redesign.
- 无条件(Unconditional )预加载
-
减少DOM数量
-
跨域拆分组件
使用2-4个域名来拆分前端资源。比如可以把HTML和动态内容部署在www.example.com
,拆分静态资源到static1.example.com
和static2.example.com
。 -
减少
iframe
数量
iframe
优点:
* 解决缓慢的第三方内容的加载
* 安全沙盒
* 并行下载脚本iframe
缺点:
* 空的也消耗资源和时间
* 阻塞了页面的onload
* 非语义化 -
不要404
http请求是昂贵的,发出http请求但获得没用的响应(404)是完全不必要的。
-
- Server
-
使用CDN(Content Delivery Network)内容分发网络
CDN是一群不同地点的服务器,可以更高效地分发内容到用户。 -
在头信息使用
Expires
或是Cache-Control
- 对静态组件:通过设置
Expires
头部来实现“永不过期”策略,比如图片。当组件更新后,必须更改文件名。 - 对动态组件:用合适的
Cache-Control
来帮助浏览器进行有条件请求
- 对静态组件:通过设置
-
Gzip压缩组件
针对文本类型的文件(html,脚本,样式,xml和json等)。图片或pdf等不应该被gzip。
可以减小http响应的大小从而减少响应时间。Content-Encoding: gzip
-
配置
Etag
实体标记(Entity Tag, ETag)是服务器和浏览器之间判断浏览器缓存中某个组件是否匹配服务器端原组件的一种机制。实体就是组件:图片、脚本、样式等。ETag被当做验证实体的,且比last-modified
(最后更改)更高效地机制。服务器这样设置组件的ETag
:HTTP/1.1 200 OK Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT ETag: "10c24bc-4ab-457e1c1f" Content-Length: 12195
浏览器通过
If-None-Match
验证组件,如果ETag匹配,服务器返回304:GET /i/yahoo.gif HTTP/1.1 Host: us.yimg.com If-Modified-Since: Tue, 12 Dec 2006 03:03:59 GMT If-None-Match: "10c24bc-4ab-457e1c1f" HTTP/1.1 304 Not Modified
-
Flush the Buffer Early
-
Use GET for AJAX Requests
获取数据应该用GET,提交数据到服务器用POST。 -
避免空
src
的img
- IE,向页面所在的目录发请求。
- Safari和Chrome,请求实际的页面。
- FireFox3及之前和Safari/Chrome一样,但从3.5开始修复问题,不再发请求。
- Opera遇到空图片src不做任何事。
-
- Cookie
- 减小cookie体积
- 消除不必要的cookie
- 尽可能减小cookie的大小降低响应时间
- 注意设置cookie到合适的域名级别,则其它子域名不会被影响
- 适当设置
Expires
日期。
- 为静态资源设置不同域名(Use Cookie-free Domains for Components)
请求静态资源 不必传输cookie,所以启用一个新域名来托管静态资源。
- 减小cookie体积
- CSS
-
把样式文件放在顶部
<head>
。 -
避免使用CSS表达式(CSS Expressions)
// 背景颜色可以设置成每小时轮换 background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );
-
避免使用
@import
在IE用@import
等效于样式文件放到页面底部。 -
避免使用过滤器(Filters)
放弃IE的AlphaImageLoader
。用PNG8来优雅降级。
-
- JavaScript
- 把脚本放在底部
当脚本在下载,浏览器不会再下载其他组件,即使在不同域名下。
一个替代建议是使用异步脚本。defer
和async
。 - 使用外部CSS和js。
- 压缩js和css
- 删除重复脚本
- 最小化DOM访问
用js访问DOM元素是缓慢的:
* 缓存访问过的元素的引用
* 在DOM树外更新节点,然后添加到DOM树
* 避免使用js实现固定布局 - 使事件处理更灵活
考虑使用事件委托。
另外不必等到onload
事件来开始处理DOM树,DOMContentLoaded
更快。onload
包含图片都被下载完毕才执行。
- 把脚本放在底部
- Images
- 优化图片
- 检查gif图片的palette size(调色板大小)是否匹配图片颜色数。
- 可以把fig转成png看看有没有变小。gif一般可以转成png8,动画除外。
- 运行
pngcrush
或其它工具压缩png。 - 运行
jpegtran
或其它工具压缩jpeg。
- 优化雪碧图(CSS Sprites)
- 把图片横向合并而不是纵向,横向更小。
- 把颜色近似的图片合并到一张雪碧图,这样可以让颜色数更少,如果低于256就可以用png8。
- “Be mobile-friendly”并且合并时图片间的间距不要太大,这样对客户端解压时需要的内存更少。
- 不要把大图片缩成小图片
比如使用100x100的图片就使用这么大的,而不应该是500x500。 - 使
favicon.ico
小且可缓存- 最好1k以下
- 设置
Expires
头部,也许可以安全设置为几个月。
- 优化图片
- Mobile
- 保持资源小于25k
这个限制于iPhone不缓存大于25k的组件息息相关。而且注意是非压缩(uncompressed)的文件大小。 - Pack Components into a Multipart Document
- 保持资源小于25k
10 浏览器兼容性
-
推荐一个reboot样式表Normalize.css。
-
html5shiv.js 解决IE9以下浏览器对HTML5标签不识别的问题。
-
respond.js 解决IE9以下不支持媒体查询的问题。
-
picturefill.js 解决IE9 10 11等不支持
<picture>
标签的问题。 -
条件注释
操作符 范例 含义 lt
[if lt IE 10]
小于 gt
[if gt IE 9]
大于 lte
[if lte IE 6]
小于等于 gte
[if gte IE 5.5 ]
大于等于 !
[if !IE]
不等于 ()
[if !(IE 7)]
子表达式 &
[if (gt IE 5)&(lt IE 7)]
AND 竖线(md表格语法问题) [if (IE 6)竖线(IE 7)]
OR 比如:
<!--[if !IE]> 除IE外都可识别 <![endif]--> <!--[if IE]> 所有的IE可识别 <![endif]--> <!--[if IE 6]> 仅IE6可识别 <![endif]--> <!--[if lt IE 6]> IE6以及IE6以下版本可识别 <![endif]--> <!--[if gte IE 6]> IE6以及IE6以上版本可识别 <![endif]-->
-
浏览器CSS兼容前缀
-o-transform:rotate(7deg); // Opera -ms-transform:rotate(7deg); // IE -moz-transform:rotate(7deg); // Firefox -webkit-transform:rotate(7deg); // Chrome transform:rotate(7deg); // 统一标识语句
-
a标签CSS状态顺序
1:link
平常状态
2:visited
被访问过之后
3:hover
鼠标悬浮
4:active
链接被点击 -
求窗口大小
// 浏览器窗口可视区域大小(不包括工具栏和滚动条等边线) var client_w = document.documentElement.clientWidth || document.body.clientWidth; var client_h = document.documentElement.clientHeight || document.body.clientHeight; // 网页内容实际宽高(包括工具栏和滚动条等边线) var scroll_w = document.documentElement.scrollWidth || document.body.scrollWidth; var scroll_h = document.documentElement.scrollHeight || document.body.scrollHeight; // 网页内容实际宽高 (不包括工具栏和滚动条等边线) var offset_w = document.documentElement.offsetWidth || document.body.offsetWidth; var offset_h = document.documentElement.offsetHeight || document.body.offsetHeight; // 滚动的高度 var scroll_Top = document.documentElement.scrollTop || document.body.scrollTop;
11 浏览器内核
浏览器的内核分为两个部分,一个是渲染引擎(Rendering Engine),一个是js引擎。现在就是引擎比较独立,内核更加倾向于说渲染引擎。
- Trident(三叉戟)内核
代表作是IE浏览器。
- Gecko(壁虎)内核
代表作是Firefox。开源项目。 - Webkit(引擎)内核
苹果公司基于KDE的KHTML引擎开发的内核。
由WebCore和JSCore构成。严格意义上来讲不仅仅是Rendering Engine。
代表作是Safari、曾经的Chrome,开源项目。
谷歌Chrome/Chromium浏览器从08年创始至今一直使用苹果公司的Webkit作为浏览器内核原型,是Webkit的一个分支,可以称之为Chromium引擎。 - Presto(说变就变)内核
代表作是Opera(v7.0-v12.16)。13年Opera弃用了Presto转为WebKit分支上的Chromium。 - Blink(闪亮)内核
有Google和Opera Software开发的,2013年4月发布的浏览器排版引擎。现代Chrome(v28.0.1469.0~)内核是Blink。
12 经典算法和原理
13 TCP/IP协议
Transmission Control Protocol/Internet Protocol(传输控制协议/因特网互联协议)又名网络通讯协议,是Internet最基本的协议,Internet国际互联网的基础,由网络层的IP协议和传输层的TCP协议组成。
14 HTTP协议
HyperText Transfer Protocol(超文本传输协议),是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信基础。万维网协议(World Wide Web Consortium, W3C)。
通过HTTP或HTTPS协议请求的资源由统一资源标识符(Uniform Resource Identifiers, URI)来标识。
15 OSI模型
有国际标准化组织提出的使各种计算机在世界范围内互连为网络的标准框架。
Open System Interconnection Reference Model(开放式系统互联通信参考模型)
- 第1层 物理层
- 第2层 数据链路层
- 第3层 网络层
- 第4层 传输层
- 第5层 会话层
- 第6层 表达层
- 第7层 应用层
16 MVC设计模式
- Model
数据模型 - View
视图 - Controller
数据模型和视图之间的控制器。用户和应用产生交互时,控制器中的事件触发器触发工作,更新视图或者更新数据。
17 MVVM设计模式
- Model
数据层的域模型,域模型同步,主要用于抽象出ViewModel中视图的Model。 - View
视图动态模板。处理状态,数据绑定的声明、指令的声明、事件绑定的声明。 - ViewModel
处理View层的具体业务逻辑。底层做好绑定树形的监听,实现双向绑定。
18 分层架构模式
分层架构(3-tier architecture):界面层、业务逻辑层、数据访问层。
为了高内聚低耦合的软件设计思想。
19 三次握手
20 call & apply
是为了动态改变this而生(重新定义函数的执行环境)。
21 Map
Map对象保存键值对。任何值(对象或原始值)都可以以为一个键或一个值。
new Map([iterable]);
iterable可以是一个数组或者其他iterable对象,其元素或为键值对,或为两个元素的数组。每个键值对都会添加到新的Map。null会被当做undefined。
22 this
this
指的是函数运行时所在的环境。
由于函数可以在不同的运行运行环境中执行,所以需要一种机制,能够在函数体内部获得当前运行环境(context)。这就是this
的由来,它设计的目的就是在函数体内部,指代函数当前的运行环境。
23 undefined和null区别
null
表示没有对象(此处不应该有值)- 作为函数的参数,表示该函数的参数不是对象
- 作为对象原型链的终点
undefined
表示缺少值(此处应该有一个值,但是还没有定义)- 变量被声明了,但是没有赋值,就等于undefined;像GoLang里的零值
- 调用函数时,应该提供的参数没有提供,这个参数等于undefined
- 对象没有赋值的属性,该属性值为undefined
- 函数没有返回值时,默认返回undefined
24 HTML5之websocket
WebSockets 是一种先进的技术。它可以在用户的浏览器和服务器之间打开交互式通信会话。使用此API,您可以向服务器发送消息并接收事件驱动的响应,而无需通过轮询服务器的方式以获得响应。
- webSockets
用于连接websocket服务器的主要接口,之后可以在这个连接上发送和接受数据。 - closeEbent
连接关闭时wensocket对象发送的事件。 - messageEvent
当从服务器获取到消息时websocket对象触发的事件。
25 HTML5之history
26 HTML5之canvas
27 HTML5之picture
是一个容器,用来为其内部特定的<img>
元素提供多样的<source>
元素。浏览器会根据当前页面的布局以及当前浏览的设备区从中选择最合适的资源。
<picture>
<source srcset="./img/1.jpg" media="(max- 992px)">
<source srcset="./img/2.jpg" media="(max- 1200px)">
<img src="./img/3.jpg" alt="3">
</picture>
28 HTML5之localStorage和sessionStorage
29 W3C标准
- 网页设计和应用
- HTML和CSS
- HTML
HTML is the language for describing the sticture of web pages.
用途:
* 发布带有头部、文字、表格、列表、图片等的在线文档
* 点击按钮通过超文本链接检索在线信息
* 设计表单,用于和远程服务进行交易,用户搜索信息,预定,订购产品等
* 直接在其文档中包含电子表格,视频剪辑,声音剪辑和其它应用程序 - XHTML
XHTML is a variant(变种) of HTML that uses the syntax(语法) of XML, the Extensible Markup Language(可扩展标记语言). - CSS
CSS is the language for describing the presentation(呈现) of web pages, including colors, layout, and fonts.
It allows one to adapt(适应) the presentation to different types of devices, such as large screens, small screens, or printers(打印机). - WebFonts
WebFonts is a technology that enables people to use fonts on demand(按需) over the Web without installation in the operating system(操作系统).
- HTML
- JavaScript Web APIs
- Graphics
png, SVG, Canvas API. WebCGM - Audio and Video
- Accessibility(无障碍)
W3C的Web Accessibility Initiative(WAI 网页可访问性计划)发布了Web Content Accessibility Guidelines(WCAG 网页内容可访问性指南),以帮助开发者创建对残障人士可访问的内容。 - Internationalization(国际化)
- Mobile Web
- Privacy(隐私)
- Math on the Web
- HTML和CSS
30 自动化发布,前端自动化
31 前端工程化
32 微信小程序
33 前端架构设计
34 ES6/ES7常用
35 cookie操作
36 函数和变量的预解析
函数和变量声明会置顶,函数声明在变量声明之上。所以即便书写的代码变量声明在函数声明之上,变量声明也不会被覆盖。
以下是个典型的题目:
function Foo() {
// 没有用var,变量提升
bar = function() {
console.log(1);
};
return this;
}
Foo.bar = function() {
console.log(2);
};
Foo.prototype.bar = function() {
console.log(3);
};
var bar = function() {
console.log(4);
};
bar = function() {
console.log(6);
};
function bar() {
console.log(5);
}
Foo.bar(); // 2
bar(); //** 6
Foo().bar(); // 1
bar(); //** 1
new Foo.bar(); // 2
new Foo().bar(); // 3
new new Foo().bar(); // 3
37 CSS3新增伪类
38 HTML5遗弃的元素
39 event对象
40 XMLHttpRequest基础
使用XMLHttpRequest(XHR)对象可以与服务器交互。
对于full-duplex(全双工)通信,WebSockets可以是更好的选择。
-
属性
-
XMLHttpRequest.onreadystatechange
当readyState
属性发生变化时调用的事件。var xhr = new XMLHttpRequest(), method = 'GET', url = 'https://developer.mozilla.org/'; xhr.open(method, url, true); xhr.onreadystatechange = function() { if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { console.log(xhr.responseText); } };
-
XMLHttpRequest.readystate
只读
返回一个无符号短整型(unsigned short),表示请求的状态码。值 状态 描述 0 UNSENT 代理被创建,但尚未调用 open()
方法1 OPENED open()
方法已经调用2 HEADERS_RECEIVED send()
方法已经被调用,并且头部和状态已经可获取3 LOADING 下载中, responseText
属性已经包含部分数据4 DONE 下载操作已完成 -
XMLHttpRequest.response
只读
返回ArrayBuffer
,Blob
,Document
,DOMString
,取决于XMLHttpRequest.responseType
的值。
其中包含响应体body。 -
XMLHttpRequest.responseText
只读
返回一个DOMString
,包含对请求的响应;如果请求失败或未发送,返回null。 -
XMLHttpRequest.responseType
定义响应类型的枚举值。值 描述 ""
默认类型,与 "text"
相同;DOMString
"arraybuffer"
包含二进制数据的JavaScript ArrayBuffer
"blob"
包含二进制数据的 Blob
对象"document"
是一个HTML Document
或XMLXMLDocument
,取决于接收到的数据的MIME类型"json"
是一个JavaScript对象,由JOSN解析 "text"
包含在DOMString对象中的文本 -
XMLHttpRequest.reponseURL
只读
返回响应的序列化URL,如果URL为空,则返回空字符串。 -
XMLHttpRequest.status
只读
返回无符号短整型(unsigned short)的请求响应状态。
请求完成前和XMLHttpRequest出错,status为0。 -
XMLHttpRequest.statusText
只读
返回一个DOMString
,其中包含HTTP服务器返回的响应状态。包括整个文本,比如:"200 OK"
。 -
XMLHttpRequest.timeout
无符号长整型(unsigned long),表示该请求的最大请求时间(毫秒),超过该时间会自动结束。 -
XMLHttpRequest.ontimeout
当请求超时调用的事件。 -
XMLHttpRequest.upload
只读
表示上传过程。 -
XMLHttpRequest.withCredentials
Boolean
,用来指定跨域的请求是否应该使用证书(cookie或授权header头)。 -
XMLHttpRequest.channel
只读
对象在执行请求时使用的通道。 -
XMLHttpRequest.mozAnon
只读
Boolean
,如果为真,请求将在没有cookie和身份验证header头的情况下发送。 -
XMLHttpRequest.mozSystem
只读
Boolean
,如果为真,则在请求时不会强制执行同源策略。 -
XMLHttpRequest.mozBackgoundRequest
Boolean
,它指示对象是否是后台服务器端的请求。
-
-
方法
-
XMLHttpRequest.abort()
如果请求已经被发送,则立刻终止请求。 -
XMLHttpRequest.getAllResponseHeaders()
以字符串的形式返回所有用CRLF分隔的响应头,如果没有收到响应,则返回null。 -
XMLHttpRequest.getResponseHeader()
返回包含指定响应头的字符串,如果响应尚未收到或响应中不存在该报头,则返回null。 -
XMLHttpRequest.open()
初始化一个请求。该方法只能在JavaScript代码中使用,若要在native code中初始化请求,请使用openRequest()
。xhr.open(method, url, async);
method
HTTP方法url
发送请求的URLasync
默认为true
,执行异步操作
-
XMLHttpRequest.overrideMimeType()
重写由服务器返回的MIME type。 -
XMLHttpRequest.send()
发送请求。如果请求是异步的,那么该方法将在请求发送后立即返回。void send(); void send(ArrayBuffer data); void send(ArrayBufferView data); void send(Blob data); void send(Document data); void send(DOMString? data); void send(FormData data);
-
XMLHttpRequest.setRequestHeader()
设置HTTP请求头的值。您必须在open()
之后,send()
之前调用setRequestHeader()
方法。
-
41 Ajax基础
ajax优点
* 改善用户体验,页面无刷新更新数据
* 异步处理服务器通信,减少页面等待时间
* 减轻服务器负担,按需请求数据,减少冗余请求
* 基于标准被广泛支持
ajax缺点
* 无法前进后退(可以通过操作history api来解决),破坏浏览器机制
* SEO问题
* 安全问题
42 src
和href
属性
src用于替代这个元素,而href用于建立这个标签与外部资源之间的关系。
href (Hypertext Reference) 超文本引用href这个属性指定web资源的位置,从而定义当前元素(如锚点a)或当前文档(如链接)与目标锚点或目标资源之间的联系。
src (Source)源这个属性是将资源嵌入到当前文档中元素所在的位置。
43 Web应用实现推送的方式
- Ajax轮询
客户端定时向服务器发送Ajax请求,服务器接收到请求后返回响应信息并关闭连接。- 优点:简单
- 缺点:浪费带宽和服务器资源
- 长轮询
客户端向服务器发送Ajax请求,服务器接收到请求后Hold住链接,直到有新消息才返回响应信息,并关闭链接;客户端处理完响应后再向服务器发起新一轮请求。- 优点:较少耗费资源
- 缺点:仍然会耗费服务器资源,返回数据顺序无法保证,难于管理维护
- 长链接
在页面中嵌入一个隐藏的iframe,将这个iframe的src属性设置为对一个长链接的请求或XHR请求。- 优点:消息即时到达,不发送无用请求。
- 缺点:服务器维护一个长链接会增加开销
- Flash Socket
在页面中嵌入一个使用了Socket类的Flash程序。- 优点:实现真正的即时通信
- 缺点:客户端必须安装Flash插件;非HTTP协议,无法自动穿越防火墙
- WebSocket
HTML5的全双工API。- 优点:事件驱动,异步;使用WS或者WSS协议的客户端Socket;实现真正意义上的推送功能
- 缺点:兼容性
44 CSS盒模型
45 js作用域
for(var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i); // 5 5 5 5 5
}, 200);
};
块级作用域可以解决这个问题:
for(let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i); // 0 1 2 3 4
}, 200);
};
46 js解析
JavaScript代码是先声明后执行,解析的时候js引擎总会从最近的一个域,向外层查找。
以下是个经典题目:
var a = 1;
function b() {
console.log(a); // undefined
var a = 2;
console.log(a); // 2
}
b();
我们来剖析一下:1: 首先声明变量a;2:声明函数b;3:赋值a为1;4:调用函数b;5:进入函数b;6:声明变量a;7:执行第一个console;8:为a赋值为2;9:执行第二个console。
执行第一个console的时候,a已经被声明但是没有赋值,我们知道js中声明一个未赋值的变量其值是undefined;而且由于a已经在b函数作用域声明,引擎也不会去函数作用域外查找。
再比如这个题目:
var foo = 1;
(function() {
var foo = foo || 2; // js先声明后执行;变量被声明了js引擎就不会去当前函数作用域外查找
console.log(foo); // 2
})();
47 多域名存储网页资源
- CDN缓存更方便
- 突破浏览器并发限制
- 减少不必要的cookie,节省带宽
- 对于UGC的内容和主站隔离,防止不必要的安全问题
- 数据作了划分,设置切到了不同的物理集群,方便通过子域名分流
48 NodeJS适用场景
-
高并发
-
I/O密集
-
少量业务逻辑
-
海量长链接推送