《JavaScript语言精粹》之函数化
写在前面
看到好多书评和读书笔记都说《JavaScript语言精粹》字字珠玑,名不虚传。。当然,要看得懂才行
其实个人认为函数化部分不是很好,举的例子不是十分恰当,之前看不懂是因为被成功误导了,就像《Head First》设计模式第一章《策略模式》一样,作者有些偏离章节主题,读者容易被误导
声明:姑且把函数化部分给出的用来创建对象的函数称为“创造函数”吧,为了与“构造函数”区分开。。不是很好听,将就着用吧
一.源码中需要注意的点
很容易就能拿到源码,和中文版书上的代码一样,仔细看了一遍发现了一个很精妙的地方,当然,不是很好理解
P.S.源码有点小问题:“创造函数”cat花括号不匹配,中文版54页,return that;之前少了};
Object的原型函数superior内部有一个很精妙的地方
Object.method('superior', function (name) {
var that = this,
method = that[name];
return function ( ) {
return method.apply(that, arguments);
};
});
亮点就是最后一句的arguments,看似无心,其实是有意为之的,表明用superior调用父类方法时也可以传参。当然,传参的话需要修改调用方式,测试代码如下:
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
var mammal = function (spec) {
var that = {};
that.get_name = function ( ) {
return spec.name;
};
that.says = function ( ) {
return spec.saying || '';
};
return that;
};
var cat = function (spec) {
spec.saying = spec.saying || 'meow';
var that = mammal(spec);
that.purr = function (n) {
var i, s = '';
for (i = 0; i < n; i += 1) {
if (s) {
s += '-';
}
s += 'r';
}
return s;
};
that.get_name = function ( ) {
alert("cat.get_name :" + arguments.length);///
return that.says( ) + ' ' + spec.name +
' ' + that.says( ) + "[" + arguments.length + "]";
};
return that;
};
Object.method('superior', function (name) {
var that = this,
method = that[name];
return function ( ) {
alert("superior :" + arguments.length);///
return method.apply(that, arguments);
};
});
var coolcat = function (spec) {
var that = cat(spec),
super_get_name = that.superior('get_name');
that.get_name = function () {
alert("coolcat.get_name :" + arguments.length);///
return 'like ' + super_get_name.apply(this, arguments) + ' baby';
};
return that;
};
var myCoolCat = coolcat({name: 'Bix'});
var name = myCoolCat.get_name(1, 2, 3);
// 'like meow Bix meow baby'
alert(name); // 'like meow Bix meow[3] baby'
P.S.开始以为superior函数最后的arguments是作者的错误,觉得应该需要把外面的arguments对象传给method而不是里面的,绕了一大圈发现是自己错了,道行不够,没能秒懂道格拉斯大爷的意思。。
二.函数化的初衷
函数化部分开篇就说明了初衷:为了实现私有属性,创建最后提到的“防伪对象”
目的无可厚非,实现私有属性太有必要了。但举的例子mammal -> cat -> coolcat太不合适了,作者想说明用函数化的方式可以实现继承
当然,不是严格意义上的继承,因为函数化方式没有用到自定义类型,子类实例与父类实例的is-a关系也就无从谈起了
P.S.看第一遍的时候cat的例子就把我带到沟里去了,以为函数化就是要抛弃new,完全用函数来实现继承。。自然是在沟里越走越深了
三.函数化的思想
直接看代码,代码自己会说话:
/*
* 函数化的思想:
* 1.创建对象
* 2.添加私有属性
* 3.公开接口(添加公有属性)
* 4.返回该对象
*/
/*
* method: getSuper
* @param spec 规格说明对象,提供创建对象所需的基本数据
* @param my “创造函数”之间共享数据的容器
*/
function getSuper(spec, my){
var obj; // 要返回的对象
var my = my || {}; // 没传入就创建一个 // 私有属性
var attr = spec.value; // 从规格说明对象取数据
var fun = function(){
alert(attr);
} // [可选]把需要与其它“创造函数”共享的数据装入my // 创建对象,可以用任意方式,比如new、字面量、调用其它“创造函数”
obj = {
name: "SuperObject"
}; // 公开接口
obj.fun1 = fun; // 返回obj
return obj;
} /*
* method: getSub
* 参数同上
*/
function getSub(spec, my){
var obj;
var my = my || {}; // 私有属性
var attr = spec.value + 1;
var fun = function(){
alert(attr);
} // [可选]共享 // 创建对象
obj = getSuper(spec, my); // 可以直接传过去,当然也可以改一改再传,或者传别的什么 // 公开接口
obj.fun2 = fun; // 返回obj
return obj;
} // 测试
var spec = {
value: 1
};
var sub = getSub(spec); // 不用传入my,my只应该在“创造函数”之间用
sub.fun1(); // 1
sub.fun2(); // 2
P.S.又是“创建对象 -> 增强 -> 返回新对象”这个套路,不就是尼古拉斯所说的由道格拉斯发明的“模块模式”吗?
四.防伪对象(持久性的对象)
函数化部分的核心就是它了,注意上面例子中公开接口的方式:
// 私有属性
var myFun = function(){/* ... */};
// 公开接口
obj.fun = myFun;
而不直接用:
// 公开接口
obj.fun = function(){/* ... */};
第一种方式更安全,因为即便从外界修改了fun,内部其它调用了myFun的方法仍然可以正常工作,这样的函数对象就是所谓的防伪对象了
完整定义:
防伪对象的属性可以被替换或者删除,但该对象的完整性不会受到损害
也被称为持久性的对象,一个持久性对象就是一个简单功能函数的集合
后话
到这里《JavaScript语言精粹》的学习笔记就告一段落了,补好了[函数化]的空缺,学习笔记的其它部分请查看黯羽轻扬:《JavaScript语言精粹》学习笔记
《JavaScript语言精粹》之函数化的更多相关文章
- JavaScript中对象与函数的某些事[JavaScript语言精粹-N1]
今天在读<JavaScript语言精粹>的时候,关于函数的一个部分,始终觉得有点难以理解,代码如下: 1: var obj = (function(){ 2: var value = 0; ...
- JavaScript语言精粹 笔记02 函数
函数函数对象函数字面量调用参数返回异常给类型增加方法递归作用域闭包回调模块级联套用记忆 函数 1 函数对象 在JS中函数就是对象.对象是“名/值”对的集合并拥有一个连接到原型对象的隐藏连接.对象字 ...
- 《JavaScript语言精粹》小记
一.前言 以下内容均摘自<JavaScript语言精粹>一书,本人在读这本书时,发现作者诠释JavaScript很犀利,特别是数组部分,固记录下来,想和大家分享下. 随笔主要包含两大部分: ...
- javascript语言精粹
内容选自:<javascript语言精粹> 1.6种值会为假(==false),分别是false,null,undefined,' ',0,NaN 2.typeof有6种值,分别是'num ...
- Javascript 语言精粹 代码片段合集
Javascript 语言精粹 代码片段合集 标签:Douglas-Crockford Javascript 最佳实践 原文链接 更好的阅读体验 使用一个method 方法定义新方法 Function ...
- JavaScript语言精粹笔记
JavaScript语言精粹笔记 掌握语言的每个特性可以让你出风头,但是并不推荐,因为一部分的特性带来的麻烦可能远超本身的价值.正如书中所言,坏的材料并不能雕刻出好的作品,要成为一名更好的程序员,要取 ...
- 《JavaScript语言精粹》学习笔记
一.in的用法 for...in 枚举一个对象的所有可枚举属性 检测DOM/BOM属性 if ("onclick" in elem) { // 元素支持onclick } if ( ...
- 《JavaScript语言精粹》【PDF】下载
<JavaScript语言精粹>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382204 内容简介 javascript曾是&q ...
- JavaScript语言精粹 笔记03 继承
继承伪类对象说明符原型函数化部件 继承 JS不是基于类的,而是基于原型的,这意味着对象直接从其他对象继承. 1 伪类 JS提供了一套丰富的代码重用模式,它可以模拟那些基于类的模式,因为JS实际上没有类 ...
随机推荐
- HeartBeat的一些介绍和功能上的一些总结
HeartBeat的作用: 通过HeartBeat,可以将资源(IP以及程序服务等资源)从一台已经故障的计算机快速转移到另一台正常运转的机器上继续提供服务,一般称之为高可用的服务.在实际的生产应用场景 ...
- easyui1.32 各种问题汇总
问题一 场景:tab切换,每个tab里用div放一个dataGrid,默认display:none隐藏,当display:'block'的时候,dataGrid会显示不全,仅显示一条线. 解决方法:切 ...
- 生产者消费者模式--阻塞队列--LOCK,Condition--线程池
1.阻塞队列:http://www.cnblogs.com/dolphin0520/p/3932906.html 2.Condition 生产者消费者实现 :http://www.cnblogs.co ...
- html a tag's href javascript issue
a标签的href中写js中遇到的问题(ie中有问题,chrome没问题) <a class="free" href="javascript:{$('#suiteTy ...
- HDU 5673 Robot ——(卡特兰数)
先推荐一个关于卡特兰数的博客:http://blog.csdn.net/hackbuteer1/article/details/7450250. 卡特兰数一个应用就是,卡特兰数的第n项表示,现在进栈和 ...
- DIOCP之DEMO学习顺序及达到要求
第一个:ECHO,了解基础网络通讯过程也触发事件 第二个:StringDEMO,理解长字符串发送编码过程 第三个:StreamCoderDEMO,理解粘包的理方式,即数据类型+数据长度+数据流 第四个 ...
- Spring MVC 文件上传
1.form的enctype=”multipart/form-data” 这个是上传文件必须的 2.applicationContext.xml中 <bean id=”multipartReso ...
- cell线条前后缩短
[cell setSeparatorInset:UIEdgeInsetsMake(0, 20, 0, 20)];
- hdu4738 Caocao's Bridges
http://acm.hdu.edu.cn/showproblem.php?pid=4738 题目大意:曹操赤壁之战大败,于是卷土重来.为了避免水上作战,他在长江上建立了一些岛屿,这样他的士兵就可以在 ...
- SVN服务器安装
CentOS 6.5 SVN搭建 (YUM安装) 参考文献:http://www.linuxidc.com/Linux/2013-10/91903.htm 安装说明 安装了一下SVN服务器,过程如 ...