[Effective JavaScript 笔记]第32条:始终不要修改__proto__属性
__proto__属性很特殊,它提供了Object.getPrototypeOf方法所不具备的额外能力,即修改对象原型链接的能力。
避免修改__proto__属性的最明显的原因是可移植性的问题。并不是所有的平台都支持修改对象原型的特性,所以无法编写可移植的代码。
避免修改__proto__属性的另一个原因是性能问题。所有现代的js引擎都深度优化了获取和设置对象属性的行为,因为这些都是一些常见的js操作。这些优化都是基于引擎对对象结构的认识上。当更改了对象的内部结构(如添加或删除该对象或其原型链中的对象的属性),将会使一些优化失效。修改__proto__属性实际上改变了继承结构本身,这可能是最具破坏性的修改。
避免修改__proto__属性的最大的原因是为了保持行为的可预测性。对象的原型链通过其一套确定的属性及属性值来定义它的行为。修改对象的原型链就像对其进行“大脑移植”,这会交换对象的整个层次结构。在某些情况下这样的操作可能是有用的,但是保持继承层次结构的相对稳定是一个基本的原则。
可以使用ES5中的Object.create函数来创建一个具有自定义原型链的新对象。对于不支持ES5的运行环境,可以使用兼容代码。
if(typeof Object.create === 'undefined'){
Object.create=function(prototype){
function F(){};
F.prototype=prototype;
return new F();
}
}
提示
始终不要修改对象的__proto__属性
使用Object.create函数给新对象设置自定义的原型
附录一:__proto__的语法
浏览器支持情况测试


使用方法
var shape = {};
var circle = new Circle();
in real code.
shape.__proto__ = circle;
console.log(shape.__proto__ === circle); // true
var shape = function () {};
var p = {
a: function () {
console.log('aaa');
}
};
shape.prototype.__proto__ = p;
var circle = new shape();
circle.a();//aaa
console.log(shape.prototype === circle.__proto__);//true
//or
var shape = function () {
};
var p = {
a: function () {
console.log('a');
}
};
var circle = new shape();
circle.__proto__ = p;
circle.a(); // a
console.log(shape.prototype === circle.__proto__);//false
//or
function test() {
}
test.prototype.myname = function () {
console.log('myname');
}
var a = new test()
console.log(a.__proto__ === test.prototype);//true
a.myname();//myname
//or
var fn = function () {
};
fn.prototype.myname = function () {
console.log('myname');
}
var obj = {
__proto__: fn.prototype
};
obj.myname();//myname
[Effective JavaScript 笔记]第32条:始终不要修改__proto__属性的更多相关文章
- [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...
- [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符
“1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- [Effective JavaScript 笔记]第45条:使用hasOwnProperty方法以避免原型污染
之前的43条,44条讨论了属性的枚举,但都没有彻底地解决属性查找中原型污染的问题.看下面关于字典的一些操作 'zhangsan' in dict; dict.zhangsan; dict.zhangs ...
- [Effective JavaScript 笔记]第20条:使用call方法自定义接收者来调用方法
不好的实践 函数或方法的接收者(即绑定到特殊关键字this的值)是由调用者的语法决定的.方法调用语法将方法被查找的对象绑定到this变量,(可参阅之前文章<理解函数调用.方法调用及构造函数调用之 ...
- [Effective JavaScript 笔记]第44条:使用null原型以防止原型污染
第43条中讲到的就算是用了Object的直接实例,也无法完全避免,Object.prototype对象修改,造成的原型污染.防止原型污染最简单的方式之一就是不使用原型.在ES5之前,并没有标准的方式创 ...
- [Effective JavaScript 笔记] 第9条:始终声明局部变量
如果忘记将变量声明为局部变量,该变量将会隐式地转变为全局变量 function swap(a,i,j){ temp=a[i]; a[i]=a[j]; a[j]=temp; } 尽管该程序没有使用var ...
- [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑
构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...
随机推荐
- 自己写了个H5版本的俄罗斯方块
在实习公司做完项目后,实在无聊.就用H5写了几个游戏出来玩一下.从简单的做起,就搞了个经典的俄罗斯方块游戏. 先上效果: 上面的数字是得分,游戏没有考虑兼容性,只在chrome上测试过,不过大部分现代 ...
- Dropbox的可用Hosts文件
108.160.167.203 www.dropbox.com 108.160.167.203 dropbox.com 108.160.165.211 dl-client677.dropbox.com ...
- 怎样提高Windows Azure Cloud Service中的WebRole的文件访问权限
关键字:WebRole 1. 背景 Web应用程序需要读取和写入该项目下的文件的权限. 在默认情况下,W3wp.exe 和WaIISHost.exe的运行账号是Network Service,而Net ...
- 编写高质量代码改善C#程序的157个建议[为泛型指定初始值、使用委托声明、使用Lambda替代方法和匿名方法]
前言 泛型并不是C#语言一开始就带有的特性,而是在FCL2.0之后实现的新功能.基于泛型,我们得以将类型参数化,以便更大范围地进行代码复用.同时,它减少了泛型类及泛型方法中的转型,确保了类型安全.委托 ...
- CSS3——3D效果
1.效果1 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" c ...
- 第二节Unity3D开发环境安装(windows系统)
这一节准备安装开发环境. 1. 首先先下载软件包:http://pan.baidu.com/s/1imYVv 4.2版本2.下载完后,解压会看到两个文件(运行第二个安装包) 3.准备安装,这 ...
- HDU 5115 Dire Wolf 区间dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5115 Dire Wolf Time Limit: 5000/5000 MS (Java/Others ...
- nodeJs抓取网页
var fs = require('fs'); var jquery = require('jquery'); var url = require('url'); var data = { 0 : ' ...
- shiro 与 web 的结合
本次使用的jar包为 shiro-core-.jar shiro-web-.jar 从Shiro 1.2开始引入了Environment/WebEnvironment的概念,即由它们的实现提供相应的S ...
- Tomcat tomcat-users.xml详解
conf/tomcat-users.xml <?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rol ...