关键词:
六、行为委托:
? 总结第五章,JS中的[[Prototype]]机制就是 对象之间的关联关系。
一)、面向委托的设计:
? 想要学习更直观的使用[[Prototype]],必须认识到它代表了一种 不同于类的设计模式。
1、类理论:
? 类设计模式鼓励你在继承时使用方法重写(和多态),子类的许多行为可以先“抽象”到父类然后再用子类进行特殊化(重写)。
? 例:
? 父类Task,定义所有任务都有的行为。子类XYZ、ABC继承Task,并添加一些特殊的行为来处理对应的任务。
2、委托理论:
? 相比面向类(面向对象,OOP),这种编码风格称为对象关联,(OLOO, objects linked to other objects)。
? 例:
? 定义一个Task对象,包含所有任务都可以使用的具体行为。接着对于每个任务(XYZ、ABC)都定义一个对象来存储对应的数据和行为。你会把特定的任务对象都关联到Task功能对象上,让它们在需要的时候进行委托。
-
在[[Prototype]]委托中最好把状态保存在委托者(XYZ、ABC)而不是委托目标(Task)上。
-
该设计模式要求尽量少使用容易被重写的通用方法名,提倡使用更有描述性的方法名,尤其是要写清相应对象行为的类型。
-
在API接口的设计中,委托最好在内部实现,不要直接暴露出去。
? 委托行为意味着某些对象(XYZ)在找不到属性或者方法引用时会把这个请求委托给另一个对象(Task)。这是一种极其强大的设计模式,和父类、子类、继承、多态等概念完全不同。在你的脑海中 对象并不是按照父类到子类的关系垂直组织的,而是通过任意方向的委托关联并排组织的。
1)、互相委托(禁止):
? 你无法在两个或两个以上互相(双向)委托的对象之间创建循环委托。
2)、调试:
? 对象关联风格的代码中,不需要关注谁“构造了”对象,浏览器调试中“构造函数名称”的跟踪没有意义。
3、比较思维模型:
(“原型”)面向对象风格:
function Foo(who)
this.me = who;
Foo.prototype.identify = function ()
return "I am " + this.me;
;
function Bar(who)
Foo.call(this, who);
Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.speak = function ()
alert("Hello," + this.identify() + ".");
;
var b1 = new Bar("b1");
var b2 = new Bar("b2");
b1.speak();
b2.speak();
对象关联风格:
Foo =
init: function (who)
this.me = who;
,
identify: function ()
return "I am " + this.me;
;
Bar = Object.create(Foo);
Bar.speak = function ()
alert("Hello, " + this.identify() + ".");
;
var b1 = Object.create(Bar);
b1.init("b1");
var b2 = Object.create(Bar);
b2.init("b2");
b1.speak();
b2.speak();
? 可以明显看出,下面的代码更加简洁。我们只是把对象关联起来,并不需要那些既复杂又令人困惑的模仿类的行为(构造函数、原型以及new)。
二)、类与对象:
? 以Web开发中非常典型的前端常见:创建UI控件为例。
1、控件“类”:
? ES6中的语法糖“class”可以极大地改善丑陋地显式伪多态。
2、委托控件对象:
- 使用类构造函数,需要在同一个步骤中实现构造和初始化。在许多情况下依照对象关联模式,把这两步分开更灵活。
三)、更简洁的设计:
四)、更好的语法:
? ES6中引入class关键字,可以更简洁地定义类方法。同时在ES6中可以在任意对象的字面形式中使用 简洁方法声明。但是有一个缺点:自我引用(递归、事件(解除)绑定,等等)更难。
五)、内省:
? 内省就是检查实例的类型。类实例的自省主要目的是通过创建方式来判断对象的结构和功能。
JS中可以使用instanceof进行自省,也可以利用 鸭子类型:
if (a1.something)
a1.something();
- 当判断a1具有something()方法后,就可以调用该方法。
- ES6的Promise就是典型的“鸭子类型”。
六)、小结:
? 行为委托是一种设计模式,认为对象之间是兄弟关系,互相委托,而不是父类和子类的关系。
? 对象关联是一种编码风格,它倡导的是直接创建和关联对象,不把它们抽象成类。
《你不知道的js(中卷)》对象(代码片段)
三、对象:一)、语法:对象有两种形式定义:声明(文字)形式:varmyObj=key:value//...;构造形式:varmyObj=newObject();myObj.key=value;在声明形式中可以添加多个键/值对,但是在构造形式中必须逐个添加属性。1、类型:? 对象是JS的基... 查看详情
《你不知道的js(中卷)》关于this(代码片段)
一、关于this:一)、为什么要用this?functionidentity() returnthis.name.toUpperCase();varme= name:"Kyle";varyou= name:"Reader";identity.call(me);//Kyleidentity.call(you);//Reader? 观察上面的代码,使 查看详情
《你不知道的js(中卷①)》语法(代码片段)
五、语法:? 语法(grammar)与词法(syntax)不同。后者强调语言的运算符、关键字等。而语法定义了此法规则是如何构成可运行的程序代码的。一)、语句和表达式:语句(statement)与表达式(expression),举例说明:vara=3*6;a=3*6... 查看详情
你不知道的js-行为委托
1、面向委托的设计2、委托理论Task={setID:function(ID){this.id=ID;},outputID:function(){console.log(this.id)};};//让XYZ委托TaskXYZ=object.create(Task);XYZ.prepareTask=function(ID,Label){this.setID(ID);this.label=Label; 查看详情
《你不知道的javascript[中卷]》——类型&值
类型定义了值的行为特征 &nb 查看详情
《你不知道的javascript[中卷]》14——asynquence附录
《你不知道的JavaScript[中卷]》【14】——asynquence附录 查看详情
你不知道的javascript(中卷)笔记
<!DOCTYPEhtml><html><head><metacharset="utf-8"><title>你不知道的javascript(中卷)</title></head><body><scripttype="text/javascript">/*//封装对象包装vara=newBool 查看详情
你不知道的js系列上(45)-显式混入(代码片段)
JS的对象机制并不会自动执行复制行为,由于其他语言中表现出来的复制行为,因此JS开发者也想出了一个方式来模拟类的复制行为,这个方法就是混入。我们先看第一种,显式混入。//非常简单的mixin()例子functionmixin(sourceObj,targe... 查看详情
读书笔记《你不知道的javascript(上卷)》——第二部分this和对象原型(代码片段)
文章目录第6章行为委托6.1面向委托的设计6.1.1类理论6.1.2委托理论1.互相委托(禁止)2.调试6.1.3比较思维模型6.2类与对象6.2.1控件“类”ES6的class语法糖6.2.2委托控件对象6.3更简洁的设计反类6.4更好的语法反词法6... 查看详情
《你不知道的javascript[中卷]》13——程序性能
&n 查看详情
你不知道的javascript(中卷)pdf
下载地址:网盘下载 内容简介 · · · · · ·JavaScript这门语言简单易用,很容易上手,但其语言机制复杂微妙,即使是经验丰富的JavaScript开发人员,如果没有认真学习的话也无法真正理解... 查看详情
《你不知道的javascript[中卷]》12——生成器
双向消息系统: 应该是花了很长的篇幅来举例交替执行——-->有点像coding的regularexpression那后面应该会有更牛逼的语法糖出来? &nbs 查看详情
你不知道的js系列(33)-对象复制(代码片段)
JS初学者最常见的问题之一就是如何复制一个对象。看起来应该有一个内置的copy()方法,实际上比想象中的更复杂,我们无法选择一个默认的复制算法functionanotherFunction()/**...*/;varanotherObject=c:true;varanotherArray=[];varmyObject= a:2, ... 查看详情
《你不知道的js》提升(代码片段)
四、提升:一)、声明与赋值:? 在JS引擎中,我们一般认为的变量或函数声明,实际上分为两个部分。声明赋值//变量提升a=2;vara;console.log(a);//函数提升foo();functionfoo() console.log(1);? vara=2;? 这句声明实际上会被看为vara;a=2;两个部分... 查看详情
你不知道的js来聊聊this(代码片段)
为什么要使用this?什么是this?来看一段代码functionidentify()returnthis.name.toUpperCase();functionspeak()vargreeting="Hello,I‘m"+identify.call(this);console.log(greeting);varme=name:"Kyle";varyou=name:"Reader" 查看详情
你不知道的js(代码片段)
作用域LHSRHS区别如果RHS查询在所有嵌套的作用域中遍寻不到所需的变量,引擎就会抛出ReferenceError异常。值得注意的是,ReferenceError是非常重要的异常类型。相较之下,当引擎执行LHS查询时,如果在顶层(全局作用域)中也无法找到目标... 查看详情
这些javascript细节,你未必知道(代码片段)
...关注我并设为星标哦前言本文主要给大家带来一些我读《你不知道的JavaScript(中卷)》中遇到的一些有意思的内容,可以说是打开新世界的大门的感觉。希望能在工作之余,给大家带来一点乐趣。JavaScript是一门... 查看详情
你不知道的js(代码片段)
1、作用域 块级作用域let只在函数内部自己的作用域内有效 全局作用域var 函数作用域 找不到作用域抛出ReferenceError变量有了则抛出TypeError 先声明后赋值 函数提升变量提升函数优先,函数声明提升在普通变量之前 函数表达... 查看详情