我们已经了解了原型的基本机制,[[Prototype]]就是存在于对象中的一个内部链接,它会引用其他 对象。

对象关联

之前我们说过Object.create(..),现在我们来用他创建一个对象的关联:

var foo = {sayName: function(){console.log("tom");}
};var bar = Object.create(foo);bar.sayName(); // "tom"
复制代码

我们并不需要通过“类”的方式来实现关联,只需要通过这种委托的方式就能关联两个对象的关系,而且Object.create(..)不包含任何“副作用”,是确定两个对象关联的最佳方式。本例中foo对象关联到bar对象上,这样bar对象就能使用foo中的方法和属性。

看起来对象之间的关联关系是处理“缺失”属性或者方法时的一种备用选项。由于存在[[Prototype]] 机制,这段代码可以正常工作。但是如果这样写只是为了让bar在无法处理属性或者方法时可以使用备用的foo,那么代码就会变得难以理解和维护。

为了符合我们设计软件的思维方式和可以维护理解的角度,我们稍微修改一下代码:

var foo = {sayName: function(){console.log("tom");}
};var bar = Object.create(foo);bar.doneName = function() {this.sayName(); //在bar内部委托
};bar.doneName(); // "tom"
复制代码

这样我们就是直接使用bar对象上的方法,从内部完成了委托,让我们的API设计更加清晰。

行为委托

现在我们试着把思路从类和继承的设计模式转换到行为委托的设计模式。

var foo = {setName: function(id) {this.id = id;},getName: function() {console.log(this.id);}
}var bar = Object.create(foo);bar.setFoo = function(id) {this.setName(id);
}bar.speak = function () {this.getName();
}
复制代码

这段代码中,foobar它们都是对象,bar通过Object.create(..)使[[prototype]]委托到foo对象上。

行为委托意味着某些对象(bar)在找不到属性或方法时,会把这个请求委托给另个对象(foo)。

利用委托来写编写一个控件对象:

var Widget = {init: function(width,height){this.width = width || 50;this.height = height || 50;this.$elem = null;},insert: function($where){if (this.$elem) {this.$elem.css({width: this.width + "px",height: this.height + "px"}).appendTo( $where );}}
};
var Button = Object.create(Widget);Button.setup = function(width,height,label){// 委托调用this.init( width, height );this.label = label || "Default";this.$elem = $( "<button>" ).text(this.label);
};
Button.build = function($where) {// 委托调用this.insert( $where );this.$elem.click(this.onClick.bind( this ));
};
Button.onClick = function(evt) {console.log("Button '" + this.label + "' clicked!");
};
$( document ).ready( function(){var $body = $ document.body);var btn1 = Object.create(Button);btn1.setup(125, 30, "Hello" );var btn2 = Object.create(Button);btn2.setup(150, 40, "World");btn1.build($body);btn2.build($body);
});
复制代码

使用对象关联风格来编写代码时不需要把WidgetButton当作父类和子类。相反,Widget只是一个对象,包含一组通用的函数,任何类型的控件都可以委托,Button同样只是一个对象。从语法角度来说,我们同样没有使用任何构造函数、.prototypenew,实际上也没必要使用它们。对象关联可以更好地支持关注分离原则。

小结

行为委托认为对象之间是兄弟关系,互相委托,而不是父类和子类的关系。JavaScript[[Prototype]]机制本质上就是行为委托机制。对象关联是一种编码风格,它倡导的是直接创建和关联对象,不把它们抽象成类。对象关联可以用基于[[Prototype]]的行为委托非常自然地实现。

参考

  • JavaScript高级程序设计
  • 你不知道的JavaScript

转载于:https://juejin.im/post/5d2dd5ca6fb9a07eb67dc348

学习JavaScript原型应用相关推荐

  1. javascript原型_JavaScript原型初学者指南

    javascript原型 You can't get very far in JavaScript without dealing with objects. They're foundational ...

  2. 重学前端学习笔记(五)-JavaScript原型

    JavaScript原型 中文中有个成语叫做"照猫画虎",这里的猫看起来就是虎的原型. 最为成功的流派是使用"类"的方式来描述对象,这诞生了诸如 C++.Jav ...

  3. 深入解析JavaScript 原型继承

    JavaScript 原型继承,学习js面向对象的朋友可以看看.十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. Object.prototype Ja ...

  4. 学习javascript 的一点感想

    原文:学习javascript 的一点感想 //动态性是指,在一个Javascript对象中,要为一个属性赋值,我们不必事先创建一个字段,只需要在使用的时候做赋值操作即可,如下例: var obj=n ...

  5. 使用Firebug或chrome-devToolBar深入学习javascript语言核心

    使用Firebug和chrome-devToolBar调试页面样式或脚本是前端开发每天必做之事.这个开发神器到底能给我们带来哪些更神奇的帮助呢?这几天看的一些资料中给了我启发,能不通过Firebug和 ...

  6. 深入理解javascript原型和闭包(16)——完结

    之前一共用15篇文章,把javascript的原型和闭包. 首先,javascript本来就"不容易学".不是说它有多难,而是学习它的人,往往都是在学会了其他语言之后,又学java ...

  7. JavaScript 原型中的哲学思想

    欢迎来我的博客阅读:「JavaScript 原型中的哲学思想」 记得当年初试前端的时候,学习JavaScript过程中,原型问题一直让我疑惑许久,那时候捧着那本著名的红皮书,看到有关原型的讲解时,总是 ...

  8. 如何理解并学习javascript中的面向对象(OOP)

    本文不适合javascript初学者看(javascript水平还停留在函数级别的朋友,看了会觉得很晕的).如果你想让你的javascript代码变得更加优美,性能更加卓越.或者,你想像jQuery的 ...

  9. java原型链_深入总结Javascript原型及原型链

    本篇文章给大家详细分析了javascript原型及原型链的相关知识点以及用法分享,具有一定的参考价值,对此有需要的朋友可以参考学习下.如有不足之处,欢迎批评指正. 我们创建的每个函数都有一个 prot ...

  10. javascript原型_在JavaScript中冻结原型时会发生什么

    javascript原型 Have you wondered what happens when you freeze the prototype of an object? Let's find o ...

最新文章

  1. zabbix自动发现规则实现批量监控主机的TCP监听端口
  2. java rmi反序列化漏洞 简介
  3. [小改进]在个人Blog页面显示文章阅读数
  4. 操作 神通数据库_国产数据库最好的时代
  5. 编译apache过程中出现如下错误及解决办法
  6. Python数据库编程pymysql
  7. 详解 height 和 width 属性
  8. C#通用权限管理-程序安全检查,这些你一定要考虑到位
  9. linux命令怎么查看文件时间排序,linux中ls命令按照文件大小排...-ls命令按大小与时间排序文件...-ls按时间排序输出文件列表的实例分析_169IT.COM...
  10. java 拆箱 类型不对,Java基本类型于对象类型的拆箱和装箱
  11. 【Alpha版本】冲刺随笔汇总
  12. JavaScript:正则表达式 分组
  13. efsframe java_EfsFrame(java开发框架)
  14. 回归分析中,证明:总离差平方和=回归平方和+误差平方和。
  15. c语言的typedef struct 对应java参数类型,JNA实战系列:02JNA与C语言中的数据类型映射以及复杂结构体传参示例...
  16. amd显卡用黑苹果输出黑屏_黑苹果AMD NVIDIA Intel显卡咋驱动?速戳这里
  17. python实现12306查询火车票
  18. xml与json格式互转
  19. 类继承和依赖注入的关系_管理类依赖关系:依赖关系注入,服务定位符和工厂简介,第1部分...
  20. 【游戏精粹】模拟群体行为:Flocking算法

热门文章

  1. CountDownLatch详解
  2. 什么是Code Review(转)
  3. 【linux】16进制格式查看命令hexdump
  4. 拿到一份陌生数据我们应该怎么办
  5. jquery基础使用!
  6. linux dhcp服务器配置及小实验
  7. OleDb驱动调用Oracle存储过程出错:ORA-06502
  8. 10个有用的网站访问分析工具
  9. Java获取浏览器请求头(User-Agent),分析浏览器信息,系统信息的几种办法
  10. InnoDB与Myisam的六大区别