第二章
1 <script type="text/javascript" async defer src=""></script> defer:延迟脚本到文档完全被解析和显示之后再执行,但立即下载,最好只包含一个 。async :表示应该立即下载脚本,但不应妨碍页面中的其他操作,并不保证按照指定它们的先后顺序执行,异步脚本一定会在页面的 load 事件前执行
2 浏览器解析:在解释器对<script>元素内部的所有代码求值完毕以前,页面中的其余内容都不会被浏览器加载或显示。在解析外部 JavaScript 文件(包括下载该文件)时,页面的处理也会暂时停止。浏览器在遇到<body>标签时才开始呈现内容
第三章
1 ECMAScript 中的一切(变量、函数名和操作符)都区分大小写
2 在 ECMAScript 中,Object 类型是所有它的实例的基础。constructor:保存着用于创建当前对象的函数。hasOwnProperty(propertyName):用于检查给定的属性在当前对象实例中(而不是在实例的原型中)是否存在。isPrototypeOf(object):用于检查传入的对象是否是传入对象的原型
3 for-in 语句是一种精准的迭代语句,可以用来枚举对象的属性。
第四章
1 延长作用域链:try-catch 语句的 catch 块; with 语句。
2 JavaScript 具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中使用的内存。
3 确保占用最少的内存可以让页面获得更好的性能。而优化内存占用的最佳方式,就是为执行中的代码只保存必要的数据。一旦数据不再有用,最好通过将其值设置为 null 来释放其引用——这个做法叫做解除引用(dereferencing) 。
4 基本类型值在内存中占据固定大小的空间,因此被保存在栈内存中;引用类型的值是对象,保存在堆内存中。
第五章
1 数组的 length 属性很有特点——它不是只读的。因此,通过设置这个属性,可以从数组的末尾移除项或向数组中添加新项。
2
every():对数组中的每一项运行给定函数,如果该函数对每一项都返回 true,则返回 true。
filter():对数组中的每一项运行给定函数,返回该函数会返回 true 的项组成的数组。
forEach():对数组中的每一项运行给定函数。这个方法没有返回值。
map():对数组中的每一项运行给定函数,返回每次函数调用的结果组成的数组。
some():对数组中的每一项运行给定函数,如果该函数对任一项返回 true,则返回 true。
3
Date 类型还有一些专门用于将日期格式化为字符串的方法,这些方法如下。
toDateString()——以特定于实现的格式显示星期几、月、日和年;
toTimeString()——以特定于实现的格式显示时、分、秒和时区;
toLocaleDateString()——以特定于地区的格式显示星期几、月、日和年;
toLocaleTimeString()——以特定于实现的格式显示时、分、秒;
toUTCString()——以特定于实现的格式完整的 UTC 日期。
4 arguments 的主要用途是保存函数参数,但这个对象还有一个名叫 callee 的属性,该属性是一个指针,指向拥有这个 arguments 对象的函数。严格模式不可用。
5 每个函数都包含两个非继承而来的方法:apply()和 call()。call()方法与 apply()方法的作用相同,它们的区别仅在于接收参数的方式不同。
第六章
1 ECMAScript 中有两种属性:数据属性和访问器属性 。
2 原型最初只包含 constructor 属性,而该属性也是共享的,因此可以通过对象实例访问。
3 尽管可以随时为原型添加属性和方法,并且修改能够立即在所有对象实例中反映出来,但如果是重写整个原型对象,那么情况就不一样了。
4 创建自定义类型的最常见方式,就是组合使用构造函数模式与原型模式。
5 稳妥构造函数模式 稳妥对象,指的是没有公共属性,而且其方法也不引用 this 的对象。
6 ECMAScript 只支持实现继承, 而且其实现继承主要是依靠原型链来实现的。
7 两种方式来确定原型和实例之间的关系:使用 instanceof 操作符,使用 isPrototypeOf()方法
8 组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为 JavaScript 中最常用的继
承模式。
9 寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。开发人员普遍认为寄生组合式继承是引用类型最理想的继承范式。
第七章
1 递归函数是在一个函数通过名字调用自身的情况下构成的,通过使用 arguments.callee 代替函数名,可以确保无论怎样调用函数都不会出问题
2 闭包是指有权访问另一个函数作用域中的变量的函数。闭包只能取得包含函数中任何变量的最后一个值
3 ,匿名函数的执行环境具有全局性
4 块级作用域:
(function(){
//这里是块级作用域
})();
5如果必须创建一个对象并以某些数据对其进行初始化,同时还要公开一些能够访问这些私有数据的方法,那么就可以使用模块模式。
6函数声明要求有名字,但函数表达式不需要。
第八章
1 一般认为,使用超时调用来模拟间歇调用的是一种最佳模式。
第九章
1 用户代理检测是客户端检测的最后一个选择。只要可能,都应该优先采用能力检测和怪癖检测。
第十章
1 所有浏览器都支持 document.documentElement 和 document.body 属性。
2var doctype = document.doctype; //取得对<!DOCTYPE>的引用
3document.links,包含文档中所有带 href 特性的<a>元素。
4 注释在 DOM 中是通过 Comment 类型来表示的。
5 NodeList 对象都是“动态的” ,这就意味着每次访问NodeList 对象,都会运行一次查询。有鉴于此,最好的办法就是尽量减少 DOM 操作。
第十一章
1 Selectors API Level 1的核心是两个方法:querySelector()和 querySelectorAll(),matchesSelector()? getElementsByClassName()。
2 有了 classList 属性,除非你需要全部删除所有类名,或者完全重写元素的 class 属性,否则也就用不到 className 属性了。
3 document.activeElement和 document.hasFocus()
4document.charset document.defaultCharset?
5 HTML5规定可以为元素添加非标准的属性,但要添加前缀 data-,目的是为元素提供与渲染无关的信息,或者提供语义信息。添加了自定义属性之后,可以通过元素的 dataset 属性来访问自定义属性的值。
6 iscrollIntoView()
第十二章
第十三章
1 DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
2 DOM2级事件” 定义了两个方法, 用于处理指定和删除事件处理程序的操作: addEventListener()(ie9已经开始支持)和 removeEventListener()。使用 DOM2 级方法添加事件处理程序的主要好处是可以添加多个事件处理程序。
3 跨浏览器事件处理程序
var EventUtil = { addHandler: function(element, type, handler){ if (element.addEventListener){ element.addEventListener(type, handler, false); } else if (element.attachEvent){ element.attachEvent("on" + type, handler); } else { element["on" + type] = handler; } }, removeHandler: function(element, type, handler){ if (element.removeEventListener){ element.removeEventListener(type, handler, false); } else if (element.detachEvent){ element.detachEvent("on" + type, handler); } else { element["on" + type] = null; } } };
4要阻止特定事件的默认行为,可以使用 preventDefault()方法。stopPropagation()方法用于立即停止事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡。
5 跨浏览器的事件对象
var EventUtil = { addHandler: function(element, type, handler){ //省略的代码 }, getEvent: function(event){ return event ? event : window.event; }, getTarget: function(event){ return event.target || event.srcElement; }, preventDefault: function(event){ if (event.preventDefault){ event.preventDefault(); } else { event.returnValue = false; } }, removeHandler: function(element, type, handler){ //省略的代码 }, stopPropagation: function(event){ if (event.stopPropagation){ event.stopPropagation(); } else { event.cancelBubble = true; } } };
5 在 JavaScript 中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能。
6 对“事件处理程序过多”问题的解决方案就是事件委托。
第十四章
1 使用<input>或<button>都可以定义提交按钮,只要将其 type 特性的值设置为"submit"即可, 而图像按钮则是通过将<input>的 type 特性值设置为"image"来定义的。
第十六章
第十七章
1 避免错误,建议使用全等和不全等。
2 在可能发生错误的地方使用 try-catch 语句,这样你还有机会以适当的方式对错误给出响应,而不必沿用浏览器处理错误的机制。
第二十章
1 JavaScript 字符串与 JSON 字符串的最大区别在于,JSON 字符串必须使用双引号
2 JSON 对象有两个方法:stringify()和 parse()。
第二十一章
1 在使用 XHR 对象时,要调用的第一个方法是 open();要发送特定的请求,必须像下面这样调用 send()方法。同源策略是对 XHR 的一个主要约束,它为通信设置了“相同的域、相同的端口、相同的协议”这一限制。
2在接收到响应后, 第一步是检查 status 属性, 以确定响应已经成功返回。 一般来说, 可以将 HTTP状态代码为 200 作为成功的标志。
3 调用 XHR 对象的 getResponseHeader()方法并传入头部字段名称,可以取得相应的响应头部信息。而调用 getAllResponseHeaders()方法则可以取得一个包含所有头部信息的长字符串。
4 跨域:jsonp,comet(有两种实现 Comet 的方式:长轮询和流)
5 Web Sockets的目标是在一个单独的持久连接上提供全双工、双向通信。因为 Web Socket 协议不同于 HTTP,所以现有服务器不能用于 Web Socket 通信。
第二十二章
1 作用域安全的构造函数
function Polygon(sides){ if (this instanceof Polygon) { this.sides = sides; this.getArea = function(){ return 0; }; } else { return new Polygon(sides); } }
2 惰性载入
3 防篡改对象 :Object.preventExtensions()方法可以改变这个行为,让你不能再给对象添加属性和方法。使用 Object.istExtensible()方法还可以确定对象是否可以扩展。
密封对象:密封对象不可扩展,而且已有成员的[[Configurable]]特性将被设置为 false。 这就意味着不能删除属性和方法, 因为不能使用 Object.defineProperty()把数据属性修改为访问器属性,或者相反。属性值是可以修改的。 Object.seal() Object.isSealed()
冻结对象:冻结的对象既不可扩展,又是密封的,而且对象数据属性的[[Writable]]特性会被设置为 false。 Object.freeze() Object.isFrozen()
4 高级定时器
setTimeout(function(){ //处理中 setTimeout(arguments.callee, interval); }, interval);
5 函数节流
var processor = { timeoutId: null, //实际进行处理的方法 performProcessing: function(){ //实际执行的代码 }, //初始处理调用的方法 process: function(){ clearTimeout(this.timeoutId); var that = this; this.timeoutId = setTimeout(function(){ that.performProcessing(); }, 100); } }; //尝试开始执行 processor.process();
6 自定义事件
function EventTarget(){ this.handlers = {}; } EventTarget.prototype = { constructor: EventTarget, addHandler: function(type, handler){ if (typeof this.handlers[type] == "undefined"){ this.handlers[type] = []; } this.handlers[type].push(handler); }, fire: function(event){ if (!event.target){ event.target = this; } if (this.handlers[event.type] instanceof Array){ var handlers = this.handlers[event.type]; for (var i=0, len=handlers.length; i < len; i++){ handlers[i](event); } } }, removeHandler: function(type, handler){ if (this.handlers[type] instanceof Array){ var handlers = this.handlers[type]; for (var i=0, len=handlers.length; i < len; i++){ if (handlers[i] === handler){ break; } } handlers.splice(i, 1); } } };
第二十三章
1 除 navigator.onLine 属性之外,为了更好地确定网络是否可用,HTML5 还定义了两个事件:online 和 offline。
2 javascript cookie
var CookieUtil = { get: function (name){ var cookieName = encodeURIComponent(name) + "=", cookieStart = document.cookie.indexOf(cookieName), cookieValue = null; if (cookieStart > -1){ var cookieEnd = document.cookie.indexOf(";", cookieStart); if (cookieEnd == -1){ cookieEnd = document.cookie.length; } cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd)); } return cookieValue; }, set: function (name, value, expires, path, domain, secure) { var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value); if (expires instanceof Date) { cookieText += "; expires=" + expires.toGMTString(); } if (path) { cookieText += "; path=" + path; } if (domain) { cookieText += "; domain=" + domain; } if (secure) { cookieText += "; secure"; } document.cookie = cookieText; }, unset: function (name, path, domain, secure){ this.set(name, "", new Date(0), path, domain, secure); } };
3Web Storage 定义了两种用于存储数据的对象:sessionStorage 和 localStorage。前者严格用于在一个浏览器会话中存储数据,因为数据在浏览器关闭后会立即删除;后者用于跨会话持久化数据并遵循跨域安全策略。
第二十四章
1 可维护的代码
可理解性——其他人可以接手代码并理解它的意图和一般途径,而无需原开发人员的完整解释。
直观性——代码中的东西一看就能明白,不管其操作过程多么复杂。
可适应性——代码以一种数据上的变化不要求完全重写的方法撰写。
可扩展性——在代码架构上已考虑到在未来允许对核心功能进行扩展。
可调试性——当有地方出错时,代码可以给予你足够的信息来尽可能直接地确定问题所在。
2 需要添加注释的地方:函数和方法、大段代码、 Hack、复杂的算法
3 命名规则:变量名应为名词、函数名应该以动词开始
4 较好的方法是将应用逻辑和事件处理程序相分离
5 佳的方法便是永远不修改不是由你所有的对象。
6 提高性能:避免多次使用全局变量(将在一个函数中会用到多次的全局对象存储为局部变量总是没错的。)优化循环
for (var i=values.length -1; i >= 0; i--){ process(values[i]); }
原生方法较快 Switch 语句较快 算数运算可以极大提升复杂计
7 最小化语句数:多个变量声明
8 优化DOM交互 :DOM 操作与交互要消耗大量时间:最小化现成-fragment = document.createDocumentFragment(),
9 谈及 JavaScript 文件压缩,其实在讨论两个东西:代码长度和配重(Wire weight) 。代码长度指的是浏览器所需解析的字节数,配重指的是实际从服务器传送到浏览器的字节数。
第二十五章
1 document.hidden页面是否隐藏
2 地理定位
3 Web 计时机制的核心是 window.performance 对象
严格模式
淘汰了 arguments.callee 和 arguments.caller
严格模式下,函数的 this 值始终是指定的值,无论指定的是什么值。
____________________________________________________________________________________
1 js常用函数:Number(),parseInt(),paseFloat(),toString(),Array.isArray(),join(),push(), pop(),shift(),unshift(),reverse(), sort(),concat(), slice(),splice(),indexOf(),lastIndexOf(),reduce(), reduceRight(),Date.parse(),
Date.UTC(),exec(), test(), toFixed(),toPrecision(),charAt(),charCodeAt(),slice()、substr(),substring(), trim(),toLowerCase()、toLocaleLowerCase()、toUpperCase()和 toLocaleUpperCase(), search(),match(),replace(),localeCompare(),fromCharCode(),encodeURI(),encodeURIComponent(),eval(), min(), max(),Object.defineProperty(),Object.defineProperties(), Object.getOwnPropertyDescriptor(),isPrototypeOf(),Object.getPrototypeOf(),Object.keys(),Object.getOwnPropertyNames(),Object.create(),moveTo(), moveBy(), window.open(),alert()、 confirm()和 prompt(),
window.print();replace(), go(),appendChild()和 insertBefore(),replaceChild(),cloneNode(),normalize(),write()、writeln()、open()和 close(),getAttribute(),setAttribute(),document.createDocumentFragment(),removeAttribute(), document.createTextNode(),splitText(),normalize(), item(), getElementLeft()与 getElementTop(),textInput() oncontextmenu beforeunload DOMContentLoaded pageshow 和 pagehide hashchange orientationchange deviceorientation devicemotion dispatchEvent() createEvent() res
et()submit() select() setSelectionRange() getData()、 setData()和 clearData() add() postMessage()
其他:
1 第六章
设计模式 | 优点 | 缺点 |
工厂模式 | 解决创建多个相似对象的问题 | 没有解决对象识别的问题?? |
构造函数模式 | 解决对象识别 | 构造函数的每个方法都要在实例上重新创造一遍 |
原型模式 | 解决多次在实例上重新创建 | 共享 |
组合构造函数+原型 | 扬长补短 |
|
动态原型模式 | 所有的信息都封装在构造函数中 | 不能使用字面量重写原型 |
寄生构造函数 |
| 不能确定对象类型 |
稳妥构造函数 | 不使用this和new | 不能确定对象类型 |
借用构造函数 | 解决原型中包含引用类型的值 |
|
组合继承 | 原型链+借用构造函数 |
|
原型式继承 | Object.create() |
|
寄生式继承 |
|
|
寄生组合式继承 |
|
|
____________________________________________________________________________________
组合继承和寄生组合式继承,没有看太懂
599页的call方法为什么就能照旧执行了呢?