Effective JavaScript Item 31 优先使用Object.getPrototypeOf,而不是__proto__

本系列作为Effective JavaScript的读书笔记。

在ES5中引入了Object.getPrototypeOf作为获取对象原型对象的标准API。可是在非常多运行环境中。也提供了一个特殊的__proto__属性来达到相同的目的。

由于并非全部的环境都提供了这个__proto__属性,且每一个环境的实现方式各不同样,因此一些结果可能不一致:

// 在某些环境中
var empty = Object.create(null); // object with no prototype
"__proto__" in empty; // false (in some environments)

// 在某些环境中
var empty = Object.create(null); // object with no prototype
"__proto__" in empty; // true (in some environments)

所以当环境中支持Object.getPrototypeOf方法时,优先使用它。

即使不支持。也能够为了实现一个:

if (typeof Object.getPrototypeOf === "undefined") {
	Object.getPrototypeOf = function(obj) {
		var t = typeof obj;
		if (!obj || (t !== "object" && t !== "function")) {
			throw new TypeError("not an object");
		}
		return obj.__proto__;
	};
}

上述代码首先会对当前环境进行检查,假设已经支持了Object.getPrototypeOf,就不会再反复定义。

另外,在使用__proto__时会导致一些错误,在Item
45中会进行讨论。

总结:

  1. 优先使用标准方法Object.getPrototypeOf。而不是非标准的__proto__属性。
  2. 为非ES5环境实现一个Object.getPrototypeOf方法。从而保持代码的一致性。
时间: 2024-10-14 12:03:31

Effective JavaScript Item 31 优先使用Object.getPrototypeOf,而不是__proto__的相关文章

Effective JavaScript Item 46 优先使用数组而不是Object类型来表示有顺序的集合

本系列作为Effective JavaScript的读书笔记. ECMAScript标准并没有规定对JavaScript的Object类型中的属性的存储顺序. 但是在使用for..in循环对Object中的属性进行遍历的时候,确实是需要依赖于某种顺序的.正因为ECMAScript没有对这个顺序进行明确地规范,所以每个JavaScript执行引擎都能够根据自身的特点进行实现,那么在不同的执行环境中就不能保证for..in循环的行为一致性了. 比如,以下代码在调用report方法时的结果就是不确定的

Effective JavaScript Item 50 优先使用遍历方法而非循环

优先使用遍历方法而非循环 在使用循环的时候,很容易违反DRY(Don't Repeat Yourself)原则.这是因为我们通常会选择复制粘贴的方法来避免手写一段段的循环语句.但是这样做回让代码中出现大量重复代码,开发人员也在没有意义地"重复造轮子".更重要的是,在复制粘贴的时候很容易忽视循环中的那些细节,比如起始索引值,终止判断条件等. 比如以下的for循环就存在这个问题,假设n是集合对象的长度: for (var i = 0; i <= n; i++) { ... } //

Effective JavaScript Item 30 理解prototype, getPrototypeOf和__proto__的不同

本系列作为Effective JavaScript的读书笔记. prototype,getPropertyOf和__proto__是三个用来访问prototype的方法.它们的命名方式很类似因此很容易带来困惑. 它们的使用方式如下: prototype: 一般用来为一个类型建立它的原型继承对象.比如C.prototype = xxx,这样就会让使用new C()得到的对象的原型对象为xxx.当然使用obj.prototype也能够得到obj的原型对象. getPropertyOf: Object

Effective JavaScript Item 32 绝不要修改__proto__

本系列作为Effective JavaScript的读书笔记. 和Object.getPrototypeOf相比,__proto__的特殊之处还体现在它能够修改一个对象的原型继承链.因为它是一个属性,除了执行获取它的操作外,还能够对它进行设置. 但是,绝不要修改__proto__.原因如下: 首先,最显而易见的原因就是便携性.因为不是所有的JavaScript执行环境都支持这一属性,所以使用了__proto__之后,代码就不能在那些不支持__proto__的环境中运行了. 其次,是性能上的考虑.

Effective C++ Item 31 降低文件间编译依存关系

本文为senlie原创,转载请保留此地址:http://blog.csdn.net/zhengsenlie 经验:支持"编译依存性最小化"的一般构想是:相依于声明式,不要相依于定义式. 基于此构想的两个手段是 Handle classes 和 Interface classes. 示例:相依于定义式 #include <string> #include "date.h" #include "address.h" class Perso

Effective JavaScript Item 47 绝不要向Object.prototype中添加可列举的(Enumerable)属性

本系列作为Effective JavaScript的读书笔记. 如果你的代码中依赖于for..in循环来遍历Object类型中的属性的话,不要向Object.prototype中添加任何可列举的属性. 但是在对JavaScript执行环境进行增强的时候,往往都需要向Object.prototype对象添加新的属性或者方法.比如可以添加一个方法用于得到某个对象中的所有的属性名: Object.prototype.allKeys = function() { var result = []; for

Effective JavaScript Item 49 对于数组遍历,优先使用for循环,而不是for..in循环

本系列作为Effective JavaScript的读书笔记. 对于下面这段代码,能看出最后的平均数是多少吗? var scores = [98, 74, 85, 77, 93, 100, 89]; var total = 0; for (var score in scores) { total += score; } var mean = total / scores.length; mean; // ? 通过计算,最后的结果应该是88. 但是不要忘了在for..in循环中,被遍历的永远是ke

Effective JavaScript Item 40 避免继承标准类型

本系列作为Effective JavaScript的读书笔记. ECMAScript标准库不大,但是提供了一些重要的类型如Array,Function和Date.在一些场合下,你也许会考虑继承其中的某个类型来实现特定的功能,但是这种做法并不被鼓励. 比如为了操作一个目录,可以让目录类型继承Array类型如下: function Dir(path, entries) { this.path = path; for (var i = 0, n = entries.length; i < n; i++

Effective JavaScript Item 27 使用闭包而不是字符串来封装代码

本系列作为Effective JavaScript的读书笔记. 对于代码封装,在JavaScript中有两种方式可以办到.第一种就是使用function,第二种则是利用eval()函数,传入到该函数的字符串参数可以是一段代码. 当对使用哪种方式犹豫不决时,使用function.因为使用字符串的一个重要缺点是,传入的字符串并不是一个闭包,而function则可以代表一个闭包.关于闭包的特点,在Item 11中进行了描述. 下面是一段使用字符串来封装代码的例子: function repeat(n,