JavaScript 基础优化(读书笔记)
1、带有 src 属性的<script>元素不应该在其<script>和</script>标签之间再包含额外的 JavaScript 代码。如果包含了嵌入的代码,则只会下载并执行外部脚本文件,嵌入的代码会被忽略。一般都把全部 JavaScript 引用放在<body>元素中页面内容的后面。
2、循环引用:对象 A 中包含一个指向对象 B 的指针,而对象 B 中也包含一个指向对象 A 的引用:
var element = document.getElementById("some_element"); var myObject = new Object(); myObject.element = element; element.someObject = myObject;
IE8及以前版本中有一部分对象并不是原生 JavaScript 对象,而是使用 C++以 COM(Component Object Model,组件对象模型)对象的形式实现的的,而 COM 对象的垃圾收集机制由于采用了引用计数策略,所以会有循环引用的问题,而循环引用会导致即使将例子中的 DOM 从页面中移除,它也永远不会被回收,因此会导致内存泄露。所以一旦数据不再有用,最好通过将其值设置为 null 来释放其引用:
myObject.element = null; element.someObject = null;
3、未初始化的变量会自动被赋予 undefined 值,但显式地初始化变量依然是明智的选择,当 typeof 操作符返回"undefined"值时,我们就知道被检测的变量还没有被声明,而不是尚未初始化。
4、创建对象推荐组合使用构造函数模式和原型模式:
function Person(name, age, job){this.name = name;this.age = age;this.job = job;this.friends = ["Shelby", "Court"]; } Person.prototype = {constructor : Person,sayName : function(){alert(this.name);} } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); person1.friends.push("Van"); alert(person1.friends); //"Shelby,Count,Van" alert(person2.friends); //"Shelby,Count" alert(person1.friends === person2.friends); //false alert(person1.sayName === person2.sayName); //true
组合使用构造函数模式和原型模式中构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。
其他模式的缺点:
工厂模式:虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型);
构造函数模式:每个方法都要在每个实例上重新创建一遍;
原型模式:原型中所有属性是被很多实例共享的,这种共享对于函数非常合适,然而对于包含引用类型值的属性来说问题比较大。
5、JavaScript中的继承可以使用组合继承(也叫伪经典继承):
function SuperType(name){this.name = name;this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){alert(this.name); }; function SubType(name, age){//继承属性SuperType.call(this, name);this.age = age; } //继承方法 SubType.prototype = new SuperType(); SubType.prototype.constructor = SubType; SubType.prototype.sayAge = function(){alert(this.age); }; var instance1 = new SubType("Nicholas", 29); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29 var instance2 = new SubType("Greg", 27); alert(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge(); //27
组合继承使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承,从而避免了原型链和借用构造函数的缺陷。但是组合继承也有不足,即无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候(new SuperType()),另一次是在子类型构造函数内部(SuperType.call(this, name)),寄生组合式继承克服了这个缺点,基本模式如下:
function object(o){function F(){}F.prototype = o;return new F(); }function inheritPrototype(subType, superType){var prototype = object(superType.prototype); //创建对象prototype.constructor = subType; //增强对象subType.prototype = prototype; //指定对象 }
所谓寄生组合式继承,即通过借用构造函数来继承属性,通过原型链的混成形式来继承方法。其背后的基本思路是:不必为了指定子类型的原型而调用超类型的构造函数,我们所需要的无非就是超类型原型的一个副本而已。本质上,就是使用寄生式继承来继承超类型的原型,然后再将结果指定给子类型的原型。我们就可以用调用 inheritPrototype()函数的语句,去替换前面例子中为子类型原型赋值的语句,例如:
function SuperType(name){this.name = name;this.colors = ["red", "blue", "green"]; } SuperType.prototype.sayName = function(){alert(this.name); }; function SubType(name, age){SuperType.call(this, name);this.age = age; } inheritPrototype(SubType, SuperType); SubType.prototype.sayAge = function(){alert(this.age); };
6、由于耦合的问题,在编写递归调用时,使用 arguments.callee 总比使用函数名更保险:
function factorial(num){if (num <= 1){return 1;} else {return num * arguments.callee(num-1); //不要使用return num * factorial(num-1); } }
7、由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存,过度使用闭包可能会导致内存占用过多。
8、由于 JavaScript 没有块级作用域,因此可以使用匿名函数来模仿块级作用域:
(function(){//这里是块级作用域 })();
这种做法可以减少闭包占用的内存问题,因为没有指向匿名函数的引用。这种技术也经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数。
9、尽量不要使用间歇调用,因为在不加干涉的情况下,间歇调用将会一直执行到页面卸载,而且后一个间歇调用可能会在前一个间歇调用结束之前启动,最好使用超时调用来模拟间歇调用,对比如下两段代码:
间歇调用: var num = 0; var max = 10; var intervalId = null; function incrementNumber() {num++;//如果执行次数达到了 max 设定的值,则取消后续尚未执行的调用if (num == max) {clearInterval(intervalId);alert("Done");} } intervalId = setInterval(incrementNumber, 500);
超时调用模拟间歇调用: var num = 0; var max = 10; function incrementNumber() {num++;//如果执行次数未达到 max 设定的值,则设置另一次超时调用if (num < max) {setTimeout(incrementNumber, 500);} else {alert("Done");} } setTimeout(incrementNumber, 500);
10、为了确保跨浏览器兼容,最好还是将 nodeType 属性与数字值进行比较,因为IE无法访问 Node 类型。
11、使用cloneNode()方法时在复制之前最好先移除事件处理程序,因为IE 在此存在一个 bug,它会复制事件处理程序。
12、尽量减少访问 NodeList 的次数。因为每次访问 NodeList,都会运行一次基于文档的查询。
13、由于老版本的浏览器不支持,因此在有特殊需要时再使用事件捕获,可以放心地使用事件冒泡。
14、因为HTML 与 JavaScript 代码紧密耦合,因此不要使用 HTML 事件处理程序,可以使用 JavaScript 指定事件处理程序。
15、使用事件委托,在DOM 树中尽量最高的层次上添加一个事件处理程序,不必给每个可单击的元素分别添加事件处理程序,因为事件委托利用了事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。最适合采用事件委托技术的事件包括 click、mousedown、mouseup、keydown、keyup 和 keypress。
16、调用 submit()方法的形式提交表单时,不会触发 submit 事件,因此要记得在调用此方法之前先验证表单数据。与调用 submit()方法不同,调用 reset()方法会像单击重置按钮一样触发 reset 事件。
17、读取或设置文本框的值时不建议使用标准的 DOM 方法,而是使用 value 属性:
var textbox = document.forms[0].elements["textbox1"]; textbox.value = "Some new value";
换句话说,不要使用 setAttribute()设置<input>元素的 value 特性,也不要去修改<textarea>元素的第一个子节点。原因很简单:对 value 属性所作的修改,不一定会反映在 DOM 中。因此,在处理文本框的值时,最好不要使用 DOM 方法。
18、不建议使用常规的 DOM 功能来访问 option 元素的数据,因为效率比较低,最好是使用特定于选项的属性,因为所有浏览器都支持这些属性:
var selectbox = document.forms[0].elements["location"]; //不推荐 var text = selectbox.options[0].firstChild.nodeValue; //选项的文本 var value = selectbox.options[0].getAttribute("value"); //选项的值//推荐 var text = selectbox.options[0].text; //选项的文本 var value = selectbox.options[0].value; //选项的值
转载于:https://www.cnblogs.com/crucify-lee/p/4516117.html
JavaScript 基础优化(读书笔记)相关推荐
- 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(上)
索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 一.SQL Server体系结构 1.1 数据库 ...
- 《高性能JavaScript》(读书笔记)
这次主要是对<高性能JavaScript>一书的读书笔记,记录下自己之前没有注意到或者需要引起重视的地方 第一章 加载和执行 js代码在执行过程中会阻塞浏览器的其他进程,比如用户界面的绘制 ...
- 《JavaScript模式》读书笔记一:基本技巧
<JavaScript模式>的读书笔记,个人向! 更新进度随我的阅读进度 基本技巧 尽量少用全局变量 防止变量污染 注意JS变量提升问题 尽量使用单一var模式,只使用一个var在函数顶部 ...
- 【读书笔记】实战JAVA虚拟机JVM故障诊断与性能优化 读书笔记
文章目录 1.概述 1.1 **第一章:初探java虚拟机** 1.2 认识java虚拟机的基本结构 1.3 常用Java虚拟机参数 1.4 垃圾回收器 1.5 垃圾收集器以及内存分配 1.6 性能监 ...
- JavaScript(基础、高级)笔记汇总表【尚硅谷JavaScript全套教程完整版】
目 录 前言 JavaScript(基础+高级)配套资料下载 JavaScript 基础 学习地址 学习笔记 day 05(P001-P006)[2016.11.22] day 06(P007-P ...
- 嵌入式Linux基础教程-读书笔记
waiting to be fixed. coming soon. +读书笔记: +linux kernel <Linux内核完全剖析基于0.12内核>.pdf 嵌入式Linux基础教程第 ...
- Unity性能优化读书笔记-简介
这边阅读的书本是Chris Dickinson的Unity 2017 Game Optimization 第二版英文原版.书本的内容我会根据翻译工具和我自己的理解进行翻译.尽可能保证内容的准确,如有错 ...
- 【Javascript 基础】课堂笔记1
计算机编程基础 计算机语言,总的来说分为三类:机器语言.汇编语言.高级语言. 标记语言(HTML)被读取的,编程语言有逻辑&行为能力. JavaScript&基础使用 JS 是运行在客 ...
- 《JavaScript 模式》读书笔记
简介 在软件开发过程中,模式是指一个通用问题的解决方案.一个模式不仅仅是一个可以用来复制粘贴的代码解决方案,更多地是提供了一个更好的实践经验.有用的抽象化表示和解决一类问题的模板. 对象有两大类: 本 ...
最新文章
- 普华永道报告:区块链不只是比特币!将改变这8大领域|附下载
- 如何理解Return的返回值?
- SpringMVC(三)——JSON
- 牛客 - 拿物品(贪心)
- 实战演示 Go 反射的使用方法和应用场景
- C++开发WPF,Step by Step
- mysql数据库 day06
- 点击按钮刷新_Chrome扩展推荐:抢票太累?后台监视网页,页面自动刷新和提醒...
- python信道仿真_Hanlp在Python环境中安装及使用.md
- java jtextfield 输入_【java】JTextField与JComboBox结合动态匹配输入信息
- 树分类、线性回归和树回归的感性认知
- 【自撰】Redis客户端Jedis
- Windows下LimeSDR Mini使用说明
- Windows操作系统注册表registry
- 用python把pdf文件转换为word文件
- Cocos Creator三消小游戏(TS 01版)
- Orge在VS2008的配置方法
- 笔记本 GTX1050ti 安装win10 Ubuntu18.04 显卡问题
- 如何利用会员积分体系提高用户活跃留存
- FDE之默认密码开机流程
热门文章
- node.js+mysql实现分库分表存查数据:
- 算法与数据结构+LeetCode题解-Js版
- Oracle之数据排序
- ChatGPT开源平替——OpenChatKit(前OpenAI团队打造)
- 电脑上的软件卸载不了怎么办
- 关于Spring容器中定时器到时执行会出现两个线程同时执行的问题
- java 商品评价_java 商品评价计算算法
- linux中数据库的4种状态,数据库的数据持久有几种方案_数据库_数据管理_数据结构_课课家...
- python使用xlwings库操作Excel常见操作
- windows 环境MySQL 安装启动 、重新安装