【高性能JavaScript】读书笔记
来源:互联网 发布:彩虹六号推荐 知乎 编辑:程序博客网 时间:2024/05/31 13:14
【简介】对象因其数据类型的缘故,天生比其他数据类型存取慢,这一点我们无法改变,所以对于对象成员的优化,着重在减少重复调用和将对象成员缓存到局部变量中。
对象成员(Object Members)
1. 原型(Prototypes)
JavaScript中的对象是基于原型的,这一概念完全不同于传统面向对象编程语言中「类」的概念,「类」定义了创建新对象的过程,「原型」对象则为所有对象实例所共享。
对象通过一个内部属性(_ _ proto _ _)绑定到它的原型。因此,对象可以有两种成员类型:实例成员(也称「own成员」)和原型成员。实例成员直接存储在对象实例中,而原型成员则从对象原型继承而来。
var person = { name: "Tom", age: 23};alert(person.toString());
对于 person 对象,有两个实例成员:name 和 age;而下面调用的 toString() 方法,则是从原型对象中继承过来的。
person 对象的实例成员和原型成员我们可以用下面这个图来表示:
在开发的时候,我们可以通过 hasOwnProperty() 方法来判断对象是否包含某个实例成员:
// hasOwnProperty() 判断对象是否包含特定的实例成员(包括成员变量和成员方法)// 不包括原型成员console.log(person.hasOwnProperty("name")); // trueconsole.log(person.hasOwnProperty("toString")); // false
而通过 in 操作符,我们可以判断对象是否包含特定的属性(包括实例属性和原型属性):
// in 判断成员是否在对象中 // 包括实例成员和原型成员console.log("name" in person); // trueconsole.log("toString" in person); // true
2. 原型链(Prototype Chains)
对象的原型决定了实例的类型。我们可以使用 instanceof 操作符来检测某个对象是否是另一个对象的实例对象,从而探索原型链。
function Person(name, age) { this.name = name; this.age = age;}Person.prototype.sayName = function() { alert(this.name);};var person = new Person("Tom", 23);// 判断person对象是否是 Person 和 Object 的实例对象console.log(person instanceof Person); // trueconsole.log(person instanceof Object); // trueperson.sayName();person.toString();
使用构造函数 Person 来创建一个新的 Person 实例,所以 person 的原型 _ _ proto_ _ 是 Person.prototype,而「Person.prototype」 的原型 _ _ proto_ _ 是 Object。所以,person 的原型链为 person -> Peroson -> Obejct。其中 sayName() 方法在 Person 中, toString() 方法在 Object 中。自然,原型链也和作用域链一样,方法在原型链中的位置越深,找到它就越慢,所带来的性能的消耗就越大。
总结一下原型链所带来的性能的问题,这个问题来自两方面。一个是搜索实例成员会比从字面量或局部变量中读取数据代价更高,另一个则是遍历原型链所带来的开销。
3. 缓存对象成员值(Caching Object Member Values)
无论是原型还是原型链,所带来的性能问题,都与对象成员有关,所以我们的优化思路就是减少使用对象成员。如果在一个函数中多次读取同一个对象属性,最佳做法是将属性值保存到存到局部变量中,因为局部变量的读取速度要更快。局部变量能用来代替属性以避免多次查找带来的性能开销,特别是在处理嵌套对象成员时。
// 一段雅虎的代码function toggle(element) { if (YAHOO.util.Dom.hasClass(element, "selected")) { YAHOO.util.Dom.removeClass(element, "selected"); return false; } else { YAHOO.util.Dom.addClass(element, "selected"); return true; }}
这段代码中重复读取 YAHOO.util.Dom 3 次来读取 3 个不同的方法。我们可以使用一个局部变量将 YAHOO.util.Dom 保存起来,然后访问这个局部变量:
// 优化 将 3 次读取变成 1 次function toggle(element) { var Dom = YAHOO.util.Dom; if (Dom.hasClass(element, "selected")) { Dom.removeClass(element, "selected"); return false; } else { Dom.addClass(element, "selected"); return true; }}
将 3 次读取变成 1 次,优化了查找。
参考博客
[1] 深入理解javascript原型和闭包(完结)附: 欢迎大家关注我的新浪微博 - 一点编程,了解最新动态 。
- 高性能javaScript读书笔记
- 《高性能JavaScript》读书笔记
- 《高性能JavaScript》读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 【高性能JavaScript】读书笔记
- 高性能Javascript 读书笔记
- 高性能 JavaScript 编程 读书笔记
- 《高性能javascript编程》读书笔记
- IntelliJ IDEA快捷键大全
- 数学类
- 【高性能JavaScript】读书笔记
- JavaScript-函数表达式
- webpack热模块替换(HMR)/热更新
- 【高性能JavaScript】读书笔记
- stanford_CS231n_learning note_Lec_06 Training Neural Networks, Part2
- [CF677E] Vanya and Balloons
- CSS之【动画模块】
- idea翻译插件translation
- 多线程_生产者消费者之等待唤醒机制思路图解
- SSH连接池配置使用username出错
- 学习BLAS库 -- COPY
- 二叉树的面试题(二)