[Effective JavaScript 笔记]第41条:将原型视为实现细节
对象原型链
一个对象给其使用者提供了轻量、简单、强大的操作集。使用者与一个对象最基本的交互是获取其属性值和调用其方法。这些操作不是特别在意属性存储在原型继承结构的哪个位置。随着时间推移,实现对象时可能会将一个属性实现在对象原型链的不同位置,但是只要其值保持不变,那么这些基本操作的行为也不变。原型是一种对象行为的实现细节。
内省机制
js提供了便利的内省机制来检查对象的细节。Object.prototype.hasOwnProperty方法确定一个属性是否为对象"自己的"属性(即一个实例的属性),而完全忽略原型继承结构。Object.getPrototypeOf和__proto__特性,允许程序员遍历对象的原型链并单独查询其原型对象。
抽象边界
优秀程序员知道什么时候考虑抽象边界。检查实例细节(即使没有修改它们)也会在程序的组件之间创建依赖。如果对象的生产者修改了实现细节,那么依赖于这些对象的使用者就会被破坏。很难诊断出这类BUG,因为它们构成了超距作用(action at a distance),即一个作者修改了一个组件的实现,导致另一个组件被破坏。
文档和约束
js并不区分对象的公有属性和私有属性。取而代之的是,你的责任是依靠文档和约束。如果一个程序库提供的对象的属性没有文档化或者明文标注为内部属性,对于使用者来说,最好不要干涉那些属性。
提示
对象是接口,原型是实现
避免检查你无法控制的对象的原型结构
避免检查实现在你无法控制的对象内部的属性
[Effective JavaScript 笔记]第41条:将原型视为实现细节的更多相关文章
- [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象
js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...
- [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法
js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...
- [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符
“1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...
- [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...
- [Effective JavaScript 笔记]第42条:避免使用轻率的猴子补丁
41条对违反抽象原则行为的讨论之后,下面聊一聊终极违例.由于对象共享原型,因此每一个对象都可以增加.删除或修改原型的属性.这个有争议的实践通常称为猴子补丁. 猴子补丁示例 猴子补丁的吸引力在于其强大. ...
- [Effective JavaScript 笔记]第45条:使用hasOwnProperty方法以避免原型污染
之前的43条,44条讨论了属性的枚举,但都没有彻底地解决属性查找中原型污染的问题.看下面关于字典的一些操作 'zhangsan' in dict; dict.zhangsan; dict.zhangs ...
- [Effective JavaScript 笔记]第44条:使用null原型以防止原型污染
第43条中讲到的就算是用了Object的直接实例,也无法完全避免,Object.prototype对象修改,造成的原型污染.防止原型污染最简单的方式之一就是不使用原型.在ES5之前,并没有标准的方式创 ...
- [Effective JavaScript 笔记]第34条:在原型中存储方法
js中完全有可能不借助原型进行编程.不用在其原型中定义任何的方法. 创建对象 构造函数法 所有属性和方法都在构造函数中定义 function User(name,pwd){ this.name=nam ...
- [Effective JavaScript 笔记]第68条:使用promise模式清洁异步逻辑
构建异步API的一种流行的替代方式是使用promise(有时也被称为deferred或future)模式.已经在本章讨论过的异步API使用回调函数作为参数. downloadAsync('file.t ...
随机推荐
- lei
upstream pap_backend_conf { keepalive 128; server 127.0.0.1:9221 max_fails=2 fail_timeout=5 weight=1 ...
- 项目笔记---C#异步Socket示例
概要 在C#领域或者说.net通信领域中有着众多的解决方案,WCF,HttpRequest,WebAPI,Remoting,socket等技术.这些技术都有着自己擅长的领域,或者被合并或者仍然应用于某 ...
- jquery.validate.js常用扩展函数
$(function () { // 判断整数value是否等于0 jQuery.validator.addMethod("isIntEqZero", function (valu ...
- Oracle中新增表代码
create table userinfo ( id varchar2(36) primary key, username varchar2(50) not null, password varcha ...
- Spring-如何实现事物管理的
事务的实现方式 实现方式共有两种:编码方式:声明式事务管理方式.基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后在目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况 ...
- Java异常-一般异常和运行时异常的区别
Java提供了两类主要的异常:runtime exception和checked exception.checked 异常也就是我们经常遇到的IO异常,以及SQL异常都是这种异常.对于这种异常, JA ...
- javaEE规范和SSH三大框架到底有什么关系
转自博客:http://blog.csdn.net/bingjing12345/article/details/20641891 1994-2000 年是互联网的大航海时代. 请注意,下面的时间点及其 ...
- Yii2请求,报400错误
出现400错误是yii2.0的csrf防范策略导致 在components里面添加request配置如下: 'request' => [ // !!! insert a secret key i ...
- android 6.0 SDK中删除HttpClient的相关类的解决方法
一.出现的情况 在eclipse或 android studio开发, 设置android SDK的编译版本为23时,且使用了httpClient相关类的库项目:如android-async-http ...
- [NOIP2011] 普及组
数字反转 小模拟 #include<cstdio> #include<iostream> #include<cstring> using namespace std ...