前端面试知识点集锦

来源:互联网 发布:木子软件 官网 编辑:程序博客网 时间:2024/05/14 22:20

HTML部分

docType

  • 混杂模式

  • 标准模式

  • 准标准模式

标签语义化

  • 去掉或者丢失样式的时候能够让页面呈现出清晰的结构

  • 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重

  • 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页

  • 便于团队开发和维护,语义化更具可读性,是下一步网页的重要动向,遵循W3C标准的团队都遵循这个标准,可以减少差异化

块级标签,行内标签

  • 块级:div, ul, li, ol, table, th, tbody, tfoot, tr, pre, fieldset, form, h1-6, p等

  • a, abbr, b, br, code, em, img, input, label, select, textarea, strong等

meta标签

  • 如何在不使用JS的情况下刷新页面(http-equiv="refresh", content="time")

  • 设置页面缓存

  • 移动端设置

  • etc.

HTML代码优化

  • 标签嵌套层级不要太深,标签尽量简洁化.如懒加载后将data属性去除

  • 大量图片的懒加载策略,以及一些元素利用ajax在onload后实行延迟加载

  • 对一些js的异步加载

搜索引擎优化SEO


CSS部分

浮动,清除浮动的方法和原理(4种方法)

  • 使用空标签设置clear: both;

  • 为父级元素设置overflow: hidden;(利用BFC的原理)

  • 使用伪元素,为要清除浮动的元素添加.clearfix类(推荐)

  • 使用min-height: contain-floats;(不推荐,兼容性不好)

CSS块级格式化上下文

  • 触发条件

    • position属性不为static或者relative

    • float属性不为none

    • 非块级的块级元素(inline-block, table-cell)

    • overflow不为visible

  • 特性

    • 内部的Box会在垂直方向,从顶部开始一个接一个地放置

    • Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生叠加

    • BFC的区域不会与float box叠加

    • BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然

    • 计算BFC的高度时,浮动元素也参与计算

  • 用处

    • 解决margin边距叠加问题。为元素单独创建一个BFC来防止外边距的折叠

    • 布局

    • 清除浮动。为包含浮动元素的container创建BFC来清除浮动

盒子模型(IE盒子模型的区别)

  • 总宽度 = margin+padding+border+content,IE的盒子模型的宽度不计padding和border

  • css3的box-sizing属性,详见https://developer.mozilla.org/en-US/docs/Web/CSS/box-sizing

    • content-box,border和padding不计算入width之内

    • border-box,border和padding计算入width之内

定位

  • 定位和浮动的区别

  • 什么时候使用定位,什么时候使用浮动

样式继承

  • 可继承的样式

    • font-size font-family color text-indent

z-index属性

  • 理解 CSS 的 z-index 属性

IE浏览器的hack

  • 条件hack

    • <!--[if IE]><![endif]-->

  • 属性hack

    • _ IE6

    • *+IE7

    • +IE6/7

    • .IE8

  • 选择符hack

    • *IE7

    • _IE6

CSS sprite

  • 减少请求

布局模型

  • 双飞翼布局

  • 圣杯布局

CSS优先级

  • 行内样式 > 内联样式 > 外部样式,ID > Class > Element

  • 设置了!important的样式优先级更高

Flexbox

  • A Complete Guide to Flexbox

各个单位的区别(px, em, rem, 百分比)

  • Understanding Font sizing in CSS: em – px – pt – percent – rem

  • REM vs EM – The Great Debate

居中

  • CSS Center Complete

link和@import的区别

  • link属于XHTML标签,而@import是CSS提供的

  • 页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载

  • @import只在IE5以上才能识别,而link是XHTML标签,无兼容问题

  • link方式的样式的权重 高于@import的权重

如何将div与图片设置等宽,inline-block元素之间的空隙如何解决

  • 设置父元素font-size为0,再对里面的文字单独设置font-size

  • 全兼容的样式解决方法

.finally-solve {    letter-spacing: -4px; /*根据不同字体字号或许需要做一定的调整*/    word-spacing: -4px;    font-size: 0;}.finally-solve li {    font-size: 16px;    letter-spacing: normal;    word-spacing: normal;    display:inline-block;    *display: inline;    zoom:1;}

CSS优化

  • 嵌套层级不要太深,一般三层最多

  • css解析从右向左,所以最右边的应该是相对少一点

  • html用了base64的img的话,并不会缓存起来,可以将这个base64的图片放在css文件里,css会缓存,图片就缓存起来了

  • 尽量不用后代元素选择器,最右边的一层不要是标签,尤其是像div这种非常常用的标签

  • 多使用css的继承,而不是每一次都书写时都全部重写一遍。写多个css属性时,能连在一起写的就连在一起写

预处理器

  • Sass


JS部分

严格模式

  • 'use strict'

  • 不能使用eval()

  • 抑制this的行为

  • 不允许读写evalarguments的值

  • 不允许意外创建全局变量

变量

  • 使用var定义的全局变量不能使用delete删除

  • 无var创建的全局变量可以使用delete删除

  • 隐式类型转换

    • 数字与字符串相加,结果为字符串

    • 数字与字符串相减,结果为数字

    • 比较变量的是否相同时,要采用=====会发生隐式类型转换

    • NaN与任何变量不相等

类型检测

  • typeof

  • instanceof

  • constructor

  • Object.prototype.toString.apply()

作用域

  • 全局作用域

  • 函数作用域

对象

  • hasOwnProperty, isPrototypeOf, propertyIsEnumerable

  • 配置属性(configurable, enumerable, writable, value)

  • 特性

    • 扩展: isExtensiblepreventExtensions(是否可以添加新的属性)

    • 密封: isSealedseal(是否可以删除属性,是否可以配置属性)

    • 冻结: isFrozenfreeze(所有属性是否可读可写)

  • 定义属性

    • definePropertydefineProperties

数组

  • 数组的类型检测

  • 数组的方法

    • slice()

    • map()

    • every()

    • some()

    • filter()

函数

  • 柯里化

    • 概念:部分求值(Partial Evaluation),是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术

function currying( fn ) {    var args = Array.prototype.slice.call(arguments, 1);    return function () {        var newArgs = args.concat(Array.prototype.slice.call(arguments));        return fn.apply(null, newArgs);    }}
  • arguments对象

  • JS函数不存在重载,后定义的函数会覆盖先定义的函数

  • 函数调用模式

    • 方法调用

    • 函数调用

    • 构造器调用

    • apply调用

new操作符的原理

使用new关键字来创建实例的时候,原理如下:

  • 首先,在构造函数内部使用Object.create(constructor.prototype)创建一个对象继承自构造函数

  • 然后,将这个对象引用到this

  • 最后,返回this

闭包

  • 概念

  • 作用

    • 创建匿名执行函数

    • 缓存变量,防止被垃圾回收

    • 实现函数的封装

  • 应用场景

    • 内部函数访问外部函数的变量

    • 使用闭包代替全局变量

    • 封装相关功能

    • 回调函数

    • 创建私有变量和公有变量

  • 特性

  • 经典例子:列表点击,弹出每一个的index

/* 错误做法 */var elems = document.getElementById('links').getElementsByTagName('li');for ( var i = 0; i < elems.length; i++ ) {    elems[i].addEventListener('click', function ( event ) {        event.preventDefault();        alert(i);    }, false);}
/* 正确的做法,使用闭包 */var elems = document.getElementById('links').getElementsByTagName('li');for ( var i = 0; i < elems.length; i++ ) {    (function ( index ) {        elems[i].addEventListener('click', function ( event ) {            event.preventDefault();            alert(index);        }, false);        })( i );}

this

  • 函数的this的值永远绑定在调用此函数的对象上

  • 可以使用applycall或者bind改变this值的指向

对象创建的模式和方法及区别

  • 工厂模式

/* 缺点:无法检测对象的类型 */var createPerson = function ( name, age, job ) {    var o = new Object();    o.name = name;    o.age = age;    o.job = job;    return o;};var person1 = createPerson('Erichain', 21, 'Web');
  • 构造函数模式

/* 缺点:每个方法要在每个实例上重新创建一遍 */var Person = function ( name, age, job ) {    this.name = name;    this.age = age;    this.job = job;}var person1 = new Person('Erichain', 21, 'Web');
  • 原型模式

var Person = function () {};Person.prototype = {    constructor: Person, // 如果这个属性十分重要的话    name: 'Erichain',    age: 21,    job: 'web'};var person1 = new Person();
  • 组合构造函数原型模式

  • 动态原型模式

var Person = function ( name, age, job ) {    this.name = name;    this.age = age;    this.job = job;    if ( typeof this.sayName !== 'function' ) {        Person.prototype.sayName = function () {            alert( this.name );        }    }};
  • 寄生构造函数模式

    • 除了使用new来实例化外,与工厂模式没区别

    • 不能依赖instanceof来确定对象类型,一般不建议使用

  • 稳妥构造函数模式

原型和继承

  • 原型链

  • 借用构造函数

function Person( name ) {    this.name = name;}function man() {    // 继承自Person,可以选择是否传入参数    Person.call(this, 'Erichain');}
  • 组合继承

  • 原型式继承

  • 寄生式继承

  • 寄生组合式继承

  • new Object()Object.create()的区别

    • Object.create创建的对象直接从他的第一个参数继承,而new Object所创建的对象是从对象的原型上继承

    • 使用Object.create,可以创建一个不继承于任何东西的对象,但是,如果设置someConstructor.prototype = null,那么,这个新创建的对象会继承自Object.prototype

回调函数

变量提升,函数声明提升

  • 函数声明优于变量声明

  • 函数声明会覆盖变量声明,但是不会覆盖变量赋值

IIFE(立即执行函数)

  • 在闭包中保存变量状态

  • 模块化

  • IIFE和自执行函数的区别

  • IIFE的几种表示方法

(function () {})();(function () {}());!function () { /* code */ } ();~function () { /* code */ } ();-function () { /* code */ } ();+function () { /* code */ } ();

事件

  • 事件流

    • 事件捕获

    • 处于目标

    • 事件冒泡

  • 事件对象(IE的区别)

  • 跨浏览器事件处理函数

var EventUtil = {    getEvent: function ( event ) {        return event ? event : window.event;    },    getTarget: function ( event ) {        return event.target || event.srcElement;    },    addHandler: function ( elem, type, handler ) {        if ( elem.addEventListener ) {            elem.addEventListener(type, handler, false);        }        else if ( elem.attachEvent ) {            elem.attachEvent('on' + type, handler);        }        else {            elem['on' + type] = handler;        }    },    preventDefault: function ( event ) {        if ( event.preventDefault ) {            event.preventDefault();        }        else {            event.returnValue = false;        }    },    stopPropagation: function ( event ) {        if ( event.stopPropagation ) {            event.stopPropagation();        }        else {            event.cancelable = true;        }    }};
  • 事件广播

  • 事件委托

<ul id="links">    <li id="link1">Link1</li>    <li id="link2">Link2</li>    <li id="link3">Link3</li></ul>
var links = document.getElementById('links');// 使用之前定义的跨浏览器事件处理程序EventUtil.addHandler(links, 'click', function ( event ) {    var target = EventUtil.getTarget(event);    event = EventUtil.getEvent(event);    switch ( target.id ) {        case 'link1':            // do something            break;        case 'link2':            // do something            break;        case 'link3':            // do something            break;    }});
  • 事件函数的参数(注意addEventListener()的最后一个参数,如果为false表示在冒泡阶段获取事件,如果为true,表示在事件捕获阶段获取事件)

call, apply, bind(手动实现)

  • call(obj, args)apply(obj, array)

  • callapply支持低版本浏览器,bind只支持高版本浏览器

  • bind原生代码实现

if ( !Function.prototype.bind ) {    Function.prototype.bind = function ( oThis ) {        if ( typeof this !== 'function') {            throw new Error('What is trying to be bound is not callable');        }        var aArgs = Array.prototype.slice.call(arguments, 1),            fToBound = this,            fNOP = function () {},            fBound = function () {                return fToBound.apply(                    this instanceof fNOP ? this : oThis,                    aArgs.concat(Array.prototype.slice.call(arguments))                )            };        if ( this.prototype ) {            fNOP.prototype = this.prototype;        }        fBound.prototype = new fNOP();        return fBound;    };}

能力检测

BOM

  • window对象

  • location对象

  • screen对象

  • navigator对象

    • 检测插件navigator.plugins

    • 检测用户代理navigator.userAgent

  • history对象

promise

  • Javascript Promise 迷你书

  • JavaScript Promise API

DOM 操作

  • 查找

    • document.getElementById

    • document.getElementsByTagName

    • document.getElementsByName

    • document.getElementsByClassName

    • document.querySelector

    • document.querySelectAll

  • 节点关系

    • element.childNodes

    • element.firstChild

    • element.lastChild

    • element.previousSibling

    • element.nextSibling

    • element.parentNode

    • element.appendChild()

    • element.insertBefore()

    • element.removeChild()

    • element.replaceChild()

  • 属性操作

    • element.getAttribute()

    • element.setAttribute()

  • 样式操作

    • element.style[PROPERTY_NAME]

    • element.classList

    • element.classList.add

    • element.classList.remove

    • element.classList.contains

    • element.classList.toggle

  • 元素遍历

    • childElementCount子元素数量

    • firstElementChild第一个子元素: firstChild的元素版

    • lastElementChild最后一个子元素: lastChild的元素版

    • previousElementSibling->previousSibling的元素版

    • nextElementSibling->nextSibling的元素版

    • 遍历方法

      • document.createNodeIterator(root, whatToShow, filter)参见https://developer.mozilla.org/en-US/docs/Web/API/NodeIterator

      • document.createTreeWalker(root, whatToShow, filter, expandEntityReferences, currentNode)参见https://developer.mozilla.org/en-US/docs/Web/API/TreeWalker

性能优化

  • 操作DOM的时候一定要缓存变量,避免发生大量的重排重绘

  • 异步加载Javascript文件

    • 使用document.write()

    • 动态改变已有script标签的src属性

    • 使用DOM方法动态创建script元素

    • 使用Ajax获取脚本内容再加载

    • 在script标签中使用defer以及async属性

    • 按需加载

  • 合并文件

  • 合理使用二进制

  • CDN加速,原理

  • 图片懒加载

    • 懒加载——网页图片的加载技术

    • Lazy Load Plugin for jQuery

  • 预加载

    • 3 Ways to Preload Images with CSS, JavaScript, or Ajax

    • Prefetching, preloading, prebrowsing

  • prefetch

    • HTML5 Prefetch

  • 函数节流

    • 浅谈函数节流

垃圾回收

  • 引用计数

/* 出现循环引用的例子 */function () {    var objectA = {},        objectB = {};    objectA.someOtherObject = objectB;    objectB.anotherObject = objectA;}
  • 标记清除

内存泄漏

  • setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏

  • 循环引用

优雅降级和渐进增强

  • 优雅降级:Web站点在所有新式浏览器中都能正常工作,如果用户使用的是老式浏览器,则代码会检查以确认它们是否能正常工作。由于IE独特的盒模型布局问题,针对不同版本的IE的hack实践过优雅降级了,为那些无法支持功能的浏览器增加候选方案,使之在旧式浏览器上以某种形式降级体验却不至于完全失效

  • 渐进增强:从被所有浏览器支持的基本功能开始,逐步地添加那些只有新式浏览器才支持的功能,向页面增加无害于基础浏览器的额外样式和功能的。当浏览器支持时,它们会自动地呈现出来并发挥作用

JSON

  • JSON.stringify() json序列化为字符串

  • JSON.parse() 将类JSON的字符串转化为JSON对象

XMLHttpRequest对象

  • 一段比较完整的使用原生Javascript实现ajax请求方法

function createRequestObject() {    if ( window.XMLHttpRequest ) {        return new XMLHttpRequest();    }    // 针对IE    else if ( window.ActiveXObject ) {        return new ActiveXObject('Microsoft.XMLHTTP');    }}// 请求的回调函数function requestCallBack() {    if ( request.readyState === 4 && request.status === 200 ) {        console.log(request.responseText);    }}var request = createRequestObject();request.onreadystatechange = requestCallBack;// open函数的三个参数分别是请求的方法, 请求的地址, 是否异步(true表示异步)request.open('POST', url, true);request.send(null);

使用Javascript计算两个日期的时间差

  • JavaScript: DateDiff & DateMeasure: Calculate days, hours, minutes, seconds between two Dates

性能测试工具

  • Performance Tools

代码审查工具

  • JSHint

  • JSLint

  • ESLint(针对ECMAScript 2015)

代码压缩

  • JSMin

  • YUI Compressor

  • Gzip

Javascript原生函数使用

  • You-Dont-Need-jQuery

Array.prototype.slice.call()原理

  • how does Array.prototype.slice.call() work?

RESTful


浏览器部分

各个浏览器内核

  • IE: Trident

  • Chrome: Webkit, Blink(now)

  • Firefox: Gecko

  • Opera: Presto

sessionStorage,cookie,localStorage

  • cookie 由服务器生成,可设置失效时间。如果是浏览器端生成的cookie,则在浏览器关闭之后失效;而localStorage除非被清除,否则永久保存,sessionStorage则在关闭浏览器或者页面之后清除

  • cookie的大小为4k左右,localStorage和sessionStorage的大小一般为5MB

  • 与服务器痛心的时候,cookie每次都会携带在http头中,但是其他两个不参与服务器通信

  • cookie中最好不要放置任何的明文的东西,其他两个的数据如果提交到服务器一定要校验

浏览器的多个标签页之间如何通信

  • Javascript communication between browser tabs/windows

关于浏览器缓存

  • 浅谈Web缓存


前端安全

  • 防止XSS(跨站点脚本)攻击

  • 防止CSRF(跨站点伪造请求攻击)

  • 防止跨iframe攻击


自动化

npm与bower的区别

  • bower与npm的不同点

gulp流与管道的概念

  • Unix流

  • 管道

    • 管道是一个固定大小的缓冲区

    • 从管道读数据是一次性操作,数据一旦被读,它就从管道中被抛弃,释放空间以便写更多的数据

    • 可以把一个进程的标准输出流与另一个进程的标准输入流连接起来

打包后静态资源路径的修改

gulp和grunt的区别

  • 前端工程的构建工具对比 Gulp vs Grunt

测试工具

  • Mocha

  • Karma

  • Jasmine


网络知识部分

Ajax

同源策略

  • 同源策略指的是:协议,域名,端口相同,同源策略是一种安全协议。 指一段脚本只能读取来自同一来源的窗口和文档的属性

跨域处理(方法和区别)

  • JSONP

  • document.domain

  • window.name

  • HTML5的window.postMessagewindow.onmessage

HTTP基本知识

  • 前端进阶--让你升级的网络知识

  • 三次握手

    • 客户端发起连接试探

    • 服务端接收到试探请求,向客户端发送确认消息

    • 客户端得到服务端的确认消息之后,再次向服务端发送确认消息

  • 一次完整的http请求是怎么样的

    • 域名解析

    • TCP三次握手

    • 发起http请求

    • 服务器端响应http请求,客户端得到html代码

    • 浏览器解析html代码,并请求html代码中的资源

    • 浏览器对页面进行渲染呈现给用户


框架相关知识

jQuery

  • jQuery Tips Everyone Should Know

  • 如何组织jQuery项目的代码结构

    • Best Practice to Organize Javascript Library & CSS Folder Structure

Bootstrap,插件原理

  • 栅格布局实现原理

  • .img-responsive实现原理

  • 内联表单实现原理

  • Bootstrap组件实现原理

AngularJS

  • 双向绑定

    • $digest循环

    • dirty checking

    • $watch

  • MVC

  • 独立作用域

  • 依赖注入

  • 循环监听

  • ng-ifng-hide/show的区别

    • ng-iftrue的时候节点才会存在于DOM中

    • ng-show/hide只是控制节点的显示和隐藏

  • factoryserviceprovider的区别和关系

    • 使用factory创建的服务,是一个对象,然后,将方法和属性定义在这个对象上,在返回这个对象,就可以供外部controller调用了

    • 使用service创建的服务,是使用new进行实例化的,所以,方法和属性要定义在this上,并且这个服务会自动返回this

    • 使用provider创建的服务,是唯一可以注入到config()函数的服务,可以用来提供模块化的配置。并且,定义在this上的属性和方法,在config函数里才可以访问,从this.$get()函数里返回的属性和方法,才能被控制器所访问

  • ng-click是否可以使用原生函数

    • 不可以,因为对应的方法不存在于其控制器中,除非在控制器中声明

  • ng-repeat数组中有相同元素的解决办法

    • 可以添加track by $index

  • $emit$broadcast$on

    • $emit由子级向父级广播,$broadcast由父级向子级广播

  • controllerAs$scope的区别

  • AngularJS的缺点

    • 强约束,学习成本高

    • 不利于SEO

    • 性能问题

      • 减少监控项

      • 主动设置索引

      • 降低渲染的数据数量

      • 数据扁平化


算法

数组降维

  • 优雅的数组降维——Javascript中apply方法的妙用

数组去重

  • 最简单的方法

function removeDuplicate( arr ) {    var len = arr.length,        temp = [];    for ( var i = 0; i < len; i+=1 ) {        if ( temp.indexOf(arr[i]) === -1 ) {            temp.push(arr[i]);        }    }    return temp;}

对象深度复制

function clone( Obj ) {           var buf;           if ( Obj instanceof Array ) {               buf = [];  //创建一个空的数组             var i = Obj.length;               while ( i-- ) {                   buf[i] = clone(Obj[i]);               }               return buf;           }        else if ( Obj instanceof Object ) {               buf = {};  //创建一个空对象             for ( var k in Obj ) {  //为这个对象添加新的属性                 buf[k] = clone(Obj[k]);               }               return buf;           }        else {               return Obj;           }       }  

各个类型的复制

function clone( obj ) {    var dest;        switch( typeof obj ) {        case 'undefined':            break;                    case 'number':            dest = +obj;            break;                    case 'string':            dest = obj + '';            break;                    case 'boolean':            dest = obj;            break;                case 'object':            if ( obj instanceof Array ) {                dest = [];                for ( var i = 0; i < obj.length; i++ ) {                    dest[i] = obj[i];                }            }            else {                dest = {};                for ( var i in obj ) {                    dest[i] = obj[i];                }            }                default:            break;    }    return dest;}

排序

  • 快速排序

function quickSort( arr ) {    var left = [],        right = [],        len = arr.length,        breakPoint = arr[0];    if ( len === 1 || len === 0 ) {        return arr;    }    for ( var i = 1; i < len; i++ ) {        if ( arr[i] < breakPoint ) {            left.push(arr[i]);        }        else {            right.push(arr[i]);        }    }    return quickSort(left).concat(breakPoint, quickSort(right));}
  • 冒泡排序

function bubbleSort( arr ) {    var len = arr.length,        temp;    for ( var i = 0; i < len - 1; i ++ ) {        for ( var j = 0; j < len - 1 - i; j++ ) {            if ( arr[j] > arr[j+1] ) {                temp = arr[j];                arr[j] = arr[j+1];                arr[j+1] = temp;            }        }    }    return arr;}
  • 插入排序

function insertSort( arr ) {    var len = arr.length,        temp;    for ( var i = 1; i < len; i++ ) {        var j;        temp = arr[i];        j = i;        while ( j > 0 && arr[j-1] > temp ) {            arr[j] = arr[j-1];            j--;        }        arr[j] = temp;    }    return arr;}

去除首尾空格

function removePlace( str ) {    var reg = /(^s*)|(s*)$/;    if ( str && typeof str === 'string' ) {        return str.replace(reg, '');    }}

统计字符数量

function charCount( str ) {    var obj = {},        len = str.length,        i = 0;    for ( ; i < len; i++ ) {        var val = str.charAt(i);        if ( obj[val] && obj[val].value === val ) {            obj[val].count++;        }        else {            obj[val] = {};            obj[val].count = 1;            obj[val].value = val;        }    }    for ( var key in obj ) {        console.log( key + ' is ' + obj[key].count );    }    return obj;}

插件编写

关于插件编写,可参考:jQuery插件库

焦点轮播图

弹窗效果

多级菜单

tab切换

Lightbox


Javascript模块化

CommonJS

  • 同步的方式加载模块,服务器优先

  • 使用require加载模块,使用module.exports定义模块

AMD

  • 浏览器优先的方式,通过异步加载的方式完成任务

  • 使用define(['module'], function ( module ) {})加载模块

  • 不兼容 io、文件系统(filesystem)和其它通过 CommonJS 实现的面向服务器的功能

  • 推崇依赖前置

  • 对于依赖的模块提前执行

CMD

  • 推崇依赖就近

  • 对于依赖的模块延迟执行

  • 使用define(function ( require, exports, module ) {})加载模块

UMD(通用模块定义,Universal Module Definition)

  • 同时支持 AMD 和 CommonJS 特性


Javascript设计模式

  • Learning JavaScript Design Patterns


NodeJS

HTML5

CSS3

Websocket

Canvas


原文链接:https://segmentfault.com/a/1190000004996857#articleHeader14
原创粉丝点击