“每18至24个月,前端都会难一倍”javascript
——赫门 “2015深js大会《前端服务化之路》主题演讲”html
数据类型
、运算
、对象
、function
、继承
、闭包
、做用域
、原型链
、事件
、RegExp
、JSON
、Ajax
、DOM
、BOM
、内存泄漏
、跨域
、异步加载
、模板引擎
、前端MVC
、前端MVVM
、路由
、模块化
、Canvas
、jQuery
、ECMAScript 2015(ES6)
、Node.js
、AngularJS
、React
、CommonJS
、AMD
、CMD
......前端
Undefined、Null、Boolean、Number、String
Object 是 JavaScript 中全部对象的父对象 数据封装类对象:Object、Array、Boolean、Number、String 其余对象:Function、Argument、Math、Date、RegExp、Error
(1)不要在同一行声明多个变量 (2)若是你不知道数组的长度,使用 push (3)请使用 ===/!== 来比较 true/false 或者数值 (4)对字符串使用单引号 ''(由于大多时候咱们的字符串。特别html会出现") (5)使用对象字面量替代 new Array 这种形式 (6)绝对不要在一个非函数块里声明一个函数,把那个函数赋给一个变量。浏览器容许你这么作,可是它们解析不一样 (7)不要使用全局函数 (8)老是使用 var 来声明变量,若是不这么作将致使产生全局变量,咱们要避免污染全局命名空间 (9)Switch 语句必须带有 default 分支 (10)使用 /**...*/ 进行多行注释,包括描述,指定类型以及参数值和返回值 (11)函数不该该有时候有返回值,有时候没有返回值 (12)语句结束必定要加分号 (13)for 循环必须使用大括号 (14)if 语句必须使用大括号 (15)for-in 循环中的变量应该使用 var 关键字明确限定做用域,从而避免做用域污染 (16)避免单个字符名,让你的变量名有描述意义 (17)当命名对象、函数和实例时使用驼峰命名规则 (18)给对象原型分配方法,而不是用一个新的对象覆盖原型,覆盖原型会使继承出现问题 (19)当给事件附加数据时,传入一个哈希而不是原始值,这可让后面的贡献者加入更多数据到事件数据里,而不用找出并更新那个事件的事件处理器
每一个对象都会在其内部初始化一个属性,就是prototype(原型),当咱们访问一个对象的属性时,若是这个对象内部不存在这个属性,那么他就会去prototype里找这个属性,这个prototype又会有本身的prototype,
因而就这样一直找下去,也就是咱们平时所说的原型链的概念。
关系:instance.constructor.prototype = instance.__proto__
// 特色:JavaScript对象是经过引用来传递的,咱们建立的每一个新对象实体中并无一份属于本身的原型副本,当咱们修改原型时,与之相关的对象也会继承这一改变。 // 当咱们须要一个属性时,JavaScript引擎会先看当前对象中是否有这个属性,若是没有的话,就会查找它的prototype对象是否有这个属性,如此递推下去,一致检索到Object内建对象。 function Func(){} Func.prototype.name = "Xiaosong"; Func.prototype.getInfo = function() { return this.name; } var person = new Func(); console.log(person.getInfo()); //"Xiaosong" console.log(Func.prototype); //Func { name = "Xiaosong", getInfo = function() }
栈:原始数据类型(Undefined,Null,Boolean,Number,String) 堆:引用数据类型(对象、数组、函数) 两种类型的区别:存储位置不一样 // 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,因此放入栈中存储; 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,若是存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中得到实体。
(1)构造继承 (2)原型继承 (3)实例继承 (4)拷贝继承 // 原型prototype机制或apply和call方法去实现较简单,建议使用构造函数与原型混合方式。 function Parent() { this.name = 'song'; } function Child() { this.age = 28; } Child.prototype = new Parent(); //经过原型,继承了Parent // var demo = new Child()l; alert(demo.age); alert(demo.name); //获得被继承的属性
javascript建立对象简单的说,无非就是使用内置对象或各类自定义对象,固然还能够用JSON;但写法有不少种,也能混合使用。 // (1)对象字面量的方式 person={firstname:"Mark",lastname:"Yun",age:25,eyecolor:"black"}; (2)用function来模拟无参的构造函数 function Person(){} var person = new Person(); //定义一个function,若是使用new"实例化",该function能够看做是一个Class person.name = "Xiaosong"; person.age = "23"; person.work = function() { alert("Hello " + person.name); } person.work(); (3)用function来模拟参构造函数来实现(用this关键字定义构造的上下文属性) function Person(name,age,hobby) { this.name = name; //this做用域:当前对象 this.age = age; this.work = work; this.info = function() { alert("我叫" + this.name + ",今年" + this.age + "岁,是个" + this.work); } } var Xiaosong = new Person("WooKong",23,"程序猿"); //实例化、建立对象 Xiaosong.info(); //调用info()方法 (4)用工厂方式来建立(内置对象) var jsCreater = new Object(); jsCreater.name = "Brendan Eich"; //JavaScript的发明者 jsCreater.work = "JavaScript"; jsCreater.info = function() { alert("我是"+this.work+"的发明者"+this.name); } jsCreater.info(); (5)用原型方式来建立 function Standard(){} Standard.prototype.name = "ECMAScript"; Standard.prototype.event = function() { alert(this.name+"是脚本语言标准规范"); } var jiaoben = new Standard(); jiaoben.event(); (6)用混合方式来建立 function iPhone(name,event) { this.name = name; this.event = event; } iPhone.prototype.sell = function() { alert("我是"+this.name+",我是iPhone5s的"+this.event+"~ haha!"); } var SE = new iPhone("iPhone SE","官方翻新机"); SE.sell();
它的功能是把对应的字符串解析成JS代码并运行;
应该避免使用eval,由于不安全,很是耗性能(2次,一次解析成js语句,一次执行)。
null 表示一个对象被定义了,值为“空值”; undefined 表示不存在这个值。 // typeof undefined //"undefined" undefined :是一个表示"无"的原始值或者说表示"缺乏值",就是此处应该有一个值,可是尚未定义。当尝试读取时会返回 undefined; 例如变量被声明了,但没有赋值时,就等于undefined。 // typeof null //"object" null : 是一个对象(空对象, 没有任何属性和方法); 例如做为函数的参数,表示该函数的参数不是对象; // 注意: 在验证null时,必定要使用 === ,由于 == 没法分别 null 和 undefined
//Event工具集,from:github.com/markyun markyun.Event = { //页面加载完成后 readyEvent: function(fn) { if (fn == null) { fn = document; } var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = fn; }else{ window.onload = function() { oldonload(); fn(); }; } }, //视能力分别使用 demo0 || demo1 || IE 方式来绑定事件 //参数:操做的元素,事件名称,事件处理程序 addEvent: function(element,type,handler) { if (element.addEventListener) { //事件类型、须要执行的函数、是否捕捉 element.addEventListener(type,handler,false); }else if (element.attachEvent) { element.attachEvent('on' + type, function() { handler.call(element); }); }else { element['on' + type] = handler; } }, //移除事件 removeEvent: function(element,type,handler) { if (element.removeEventListener) { element.removeEventListener(type,handler,false); }else if (element.datachEvent) { element.datachEvent('on' + type,handler); }else{ element['on' + type] = null; } }, //阻止事件(主要是事件冒泡,由于IE不支持事件捕获) stopPropagation: function(ev) { if (ev.stopPropagation) { ev.stopPropagation(); }else { ev.cancelBubble = true; } }, //取消事件的默认行为 preventDefault: function(event) { if (event.preventDefault) { event.preventDefault(); }else{ event.returnValue = false; } }, //获取事件目标 getTarget: function(event) { return event.target || event.srcElemnt; }, //获取event对象的引用,取到事件的全部信息,确保随时能使用event; getEvent: function(e) { var ev = e || window.event; if (!ev) { var c = this.getEvent.caller; while(c) { ev = c.argument[0]; if (ev && Event == ev.constructor) { break; } c = c.caller; } } retrun ev; } };
[1,NaN,NaN] 由于 parseInt 须要两个参数(val,radix),其中 radix 表示解析时用的基数。 map 传了3个(element,index,array),对应的 radix 不合法致使解析失败。
(1)咱们在网页中的某个操做(有的操做对应多个事件)。例如:当咱们点击一个按钮就会产生一个事件。是能够被 JavaScript 侦测到的行为。 (2)事件处理机制:IE是事件冒泡、Firefox同时支持两种事件模型,也就是:捕获型事件和冒泡型事件; (3)ev.stopPropagation();(旧ie的方法 ev.cancelBubble = true;)
闭包是指有权访问另外一个函数做用域中变量的函数,建立闭包的最多见的方式就是在一个函数内建立另外一个函数,经过另外一个函数访问这个函数的局部变量,利用闭包能够突破做用链域,将函数内部的变量和方法传递到外部。
//
闭包特性:
(1)函数内再嵌套函数
(2)内部函数能够引用外层的参数和变量
(3)参数和变量不会被垃圾回收机制回收
//li节点的onclick事件都能正确的弹出当前被点击的li索引
<ul> <li> index = 0 </li> <li> index = 1 </li> <li> index = 2 </li> <li> index = 3 </li> </ul> <script type="text/javascript"> var nodes = document.getElementsByTagName('li'); for(i = 0;i<nodes.length;i+=1) { nodes[i].onclick = function() { console.log(i+1); //不使用闭包的话,值每次都是4 }(4); } </script>
use strict是一种ECMAscript 5 添加的(严格)运行模式,这种模式使得 Javascript 在更严格的条件下运行,使JS编码更加规范化的模式,消除Javascript语法的一些不合理、不严谨之处,减小一些怪异行为。 默认支持的糟糕特性都会被禁用,好比不能用with,也不能在乎外的状况下给全局变量赋值; 全局变量的显示声明,函数必须声明在顶层,不容许在非函数代码块内声明函数,arguments.callee也不容许使用; 消除代码运行的一些不安全之处,保证代码运行的安全,限制函数中的arguments修改,严格模式下的eval函数的行为和非严格模式的也不相同; 提升编译器效率,增长运行速度; 为将来新版本的Javascript标准化作铺垫。
(1)建立一个空对象,而且 this 变量引用该对象,同时还继承了该函数的原型。 (2)属性和方法被加入到 this 引用的对象中。 (3)新建立的对象由 this 所引用,而且最后隐式的返回 this 。 // var obj = {}; obj.__proto__ = Base.prototype; Base.call(obj);
hasOwnProperty
// JavaScript 中 hasOwnProperty 函数方法是返回一个布尔值,指出一个对象是否具备指定名称的属性。此方法没法检查该对象的原型链中是否具备该属性;该属性必须是对象自己的一个成员。 // 使用方法: object.hasOwnProperty(proName) 其中参数object是必选项,一个对象的实例。 proName是必选项,一个属性名称的字符串值。 // 若是 object 具备指定名称的属性,那么JavaScript中hasOwnProperty函数方法返回 true,反之则返回 false。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。 它是基于JavaScript的一个子集。数据格式简单,易于读写,占用带宽小。 如: {"age":"12", "name":"back"}
defer和async、动态建立DOM方式(用得最多)、按需异步载入js
ajax的全称:Asynchronous Javascript And XML。
异步传输+js+xml。
所谓异步,在这里简单地解释就是:向服务器发送请求的时候,咱们没必要等待结果,而是能够同时作其余的事情,等到有告终果它本身会根据设定进行后续操做,与此同时,页面是不会发生整页刷新的,提升了用户体验。
// (1)建立XMLHttpRequest对象,也就是建立一个异步调用对象 (2)建立一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息 (3)设置响应HTTP请求状态变化的函数 (4)发送HTTP请求 (5)获取异步调用返回的数据 (6)使用JavaScript和DOM实现局部刷新
同步的概念应该是来自于操做系统中关于同步的概念:
不一样进程为协同完成某项工做而在前后次序上调整(经过阻塞,唤醒等方式)。同步强调的是顺序性,谁先谁后;异步则不存在这种顺序性。
// 同步:浏览器访问服务器请求,用户看获得页面刷新,从新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操做。 // 异步:浏览器访问服务器请求,用户正常操做,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容。
jsonp、iframe、window.name、window.postMessage、服务器上设置代理页面
ECMAScript 6 是JavaScript语言的下一代标准,已经在2015年6月正式发布了。它的目标,是使得JavaScript语言能够用来编写复杂的大型应用程序,成为企业级开发语言。 标准的制定者有计划,之后每一年发布一次标准,使用年份做为标准的版本。由于当前版本的ES6是在2015年发布的,因此又称ECMAScript 2015。也就是说,ES6就是ES2015
ES6的class能够看做只是一个语法糖,它的绝大部分功能,ES5均可以作到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。 //定义类 class Point { constructor(x,y) { //构造方法 this.x = x; //this关键字表明实例对象 this.y = y; } toString() { return '(' + this.x + ',' + this.y + ')'; } }
(1)defer,只支持 IE (2)async: (3)建立 script,插入到 DOM 中,加载完毕后 callBack
document.write 只能重绘整个页面 innerHTML 能够重绘页面的一部分
(1)建立新节点 createDocumentFragment() //建立一个DOM片断 createElement() //建立一个具体的元素 createTextNode() //建立一个文本节点 (2)添加、移除、替换、插入 appendChild() removeChild() replaceChild() insertBefore() //在已有的子节点前插入一个新的子节点 (3)查找 getElementsByTagName() //经过标签名称 getElementsByName() //经过元素的Name属性的值(IE容错能力较强,会获得一个数组,其中包括id等于name值的) getElementById() //经过元素Id,惟一性
内存泄漏是指任何对象在您再也不拥有或须要它以后任然存在。
垃圾回收器按期扫描对象,并计算引用了每一个对象的其余对象的数量,若是一个对象的引用数量为0(没有其余对象引用过该对象),或对该对象的唯一引用是循环的,那么该对象的内存便可回收。 // setTimeout 的第一个参数使用字符串而非函数的话,会引起内存泄漏。 闭包、控制台日志、循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
jQuery 中没有提供这个功能,因此须要先编写两个 jQuery 的扩展:
$.fn.stringifyArray = function(array) { return JSON.stringify(array) } $.fn.parseArray = function(array) { return JSON.parse(array) } // 而后调用: $("").stringifyArray(array)
基于Class的选择性的性能相对于Id选择器开销很大,由于需遍历全部DOM元素。
// 频繁操做的DOM,先缓存起来再操做。用Jquery的链式调用更好。 好比:var str=$("a").attr("href"); // for (var i = size; i < arr.length; i++) {} for 循环每一次循环都查找了数组 (arr) 的.length 属性,在开始循环的时候设置一个变量来存储这个数字,可让循环跑得更快: for (var i = size, length = arr.length; i < length; i++) {}
`jQuery`是一个js库,主要提供的功能是选择器,属性修改和事件绑定等等。 `jQuery UI`则是在jQuery的基础上,利用jQuery的扩展性,设计的插件。提供了一些经常使用的界面元素,诸如对话框、拖动行为、改变大小行为等等
经过判断 Global 对象是否为 window ,若是不为 window ,当前脚本没有运行在浏览器中
正则 + replace
function commafy(num) { num = num + ''; var reg = /(-?d+)(d{3})/; if (reg.test(num)) { num = num.replace(reg, '$1,$2'); } return num; }
功能检测、userAgent 特征检测
好比:navigator.userAgent //"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
//我的拙见 | CommonJS | AMD | CMD | |--------------|---------|---------| | Node.js |RequireJS| SeaJS |
详细文章:浅析JS中的模块规范(CommonJS,AMD,CMD)、关于 CommonJS AMD CMD UMD模型(Model):数据保存
视图(View):用户界面
控制器(Controller):业务逻辑
(1)View 传送指令到 Controller (2)Controller 完成业务逻辑后,要求 Model 改变状态 (3)Model 将新的数据发送到 View ,用户获得反馈 全部通讯都是单向的。
二、MVVM模型(Model)
视图(View)
视图模型(ViewModel)
(1)各部分间都是双向通讯 (2)View 与 Model 不发生联系,都经过 ViewModel 传递 (3)View 很是薄,不部署任何业务逻辑,称为“被动视图”(Passive View),即没有任何主动性;而 ViewModel 很是厚,全部逻辑都部署在那里 采用双向绑定(data-binding):View 的变更,自动反映在 ViewModel ,反之亦然。