Javascript继承(上)——对象构建介绍


Posted in Javascript onNovember 08, 2012

Javascript中存在“类”么?

万物皆对象
Javascript中除了基本数据(Undefined、Null、Boolean、Number、String),其他都是对象(Object)。
实际上,Javascript中的对象是数据与功能的集合。例如我们知道:

var foo = new Function("alert('hello world!')"); 
foo();

可见foo是一个函数,也是一种对象。再比如说:
function foo(){ 
//do something 
} foo.data = 123; 
foo["data2"] = "hello"; 
alert(foo.data); 
alert(foo.data2);

函数也可以像对象一样添加属性。
对象的构建
一般我们用构造函数来构建对象,但如果没有构造函数,我们也有办法构建我们想要的对象:
function creatPerson(__name, __sex, __age){ 
return { 
name: __name, 
sex: __sex, 
age: __age, 
get: function(__key){ 
alert(this[__key]); 
} 
}; 
} var Bob = creatPerson("Bob", "male", 18); 
Bob.get("name"); //Bob 
Bob.get("sex"); //male 
Bob.get("age"); //18

但是这不够,我希望方法是可以共享的。比如我再用该函数创建一个Tom对象,get函数就又被创建了一次,这明显地浪费了我的内存。
导入共享资源
因为我们知道函数也是对象,所以我们可以把需要共享的方法或属性放在放在他“身上”:
function creatPerson(__name, __sex, __age){ 
var common = arguments.callee.common; 
return { 
//自身的属性 
name: __name, 
sex: __sex, 
age: __age, 
//自身的方法 
sayhi: function(){alert("hi");}, 
//共享的方法 
get: common.get, 
getType: common.getType, 
//共享的属性 
type: common.type 
}; 
} 
creatPerson.common = { 
get:function(__key){ 
alert(this[__key]); 
}, 
getType: function(){ 
alert(this.type); 
}, 
type: "Person" 
}; var Bob = creatPerson("Bob", "male", 18); 
Bob.get("name"); //Bob 
Bob.get("sex"); //male 
Bob.getType(); //Person

于是我们就用蹩脚的方法,成功的创建了一个拥有自有属性方法和共享属性方法的对象。但实际上,Javascript就是这么蹩脚地创建对象的。
其实共享属性没有真正实现,因为这个共享属性,依然只是一个副本。这并不是我们真正希望的共享属性。

new关键字
和上面的“对象的构建”相同,new的目的是创建对象的自有属性和方法。例如:

function Person(__name, __sex, __age){ 
this.name = __name; 
this.sex = __sex; 
this.age = __age; 
this.get = function(__key){ 
alert(this[__key]); 
}; 
} var Bob = new Person("Bob", "male", 18); 
Bob.get("name"); //Bob 
Bob.get("sex"); //male 
Bob.get("age"); //18

原型(Prototype)
Javascript的作者用了和上面“导入共享资源”的方法差不多。既然函数也是对象,那么把需要共享的“东东”放在他“身上”吧:
function Person(__name, __sex, __age){ 
this.name = __name; 
this.sex = __sex; 
this.age = __age; 
this.sayhi = function(__key){ 
alert("hi"); 
}; 
} 
Person.prototype = { 
constructor: Person, 
get: function(__key){ 
alert(this[__key]); 
} 
}; var Bob = new Person("Bob", "male", 18); 
Bob.get("name"); //Bob 
Bob.get("sex"); //male 
alert(Bob.constructor); //function Person

Javascript创建对象的模型是简洁的,new来处理自身问题,prototype来处理共享问题。

如果说Java的对象(实例)产生方式是将原材料丢到模子里(类)熔炼而成;那么Javascript的对象产生方式就是给材料给建筑工(构造函数)让他按图纸搭建而成。

实际流程

当然实际流程并不是这样的,新建一个对象先做的是处理共享资源,例如:

function A(){ 
console.dir(this); 
alert(this.type); //A 
} 
A.prototype.type = "A"; 
var a = new A();

通过console.dir将a打印出来我们可以看到:

type "A"
__proto__ A {type = "A"}
type "A"
constructor A()

构造函数新建一个对象以后,立刻将其prototype的引用赋给新建对象的内部属性__proto__,然后再运行构造函数里面的构造语句。

并没有覆盖

function A(){ 
this.type = "B" 
} 
A.prototype.type = "A"; var a = new A(); 
alert(a.type); //B

当我们想得到a.type时,引擎会先去在a对象中查看是否有属性type,如果有则返回该属性,没有则试图在__proto__中查找是否有type属性,如果有则返回该属性。

__proto__并不是标准的,比如IE上没有,但IE上也有类似的内部属性,但我们也无法使用它。

基于这个原因,我们删掉a.type时依然可以返回a.type:

function A(){ 
this.type = "B" 
} 
A.prototype.type = "A"; var a = new A(); 
alert(a.type); //B 
delete a.type; 
alert(a.type); //A

到底有没有类?

严格地讲,Javascript并没有类(class)这种东西。
但有时候我们会用构造函数的名字作为利用该构造函数创建的对象们的“类型(type not class)名”,以方便我们用Javascript进行面向对象编程时的交流。
名字只是一个代号,一个方便理解的工具罢了。

参考文献

Javascript继承机制的设计思想

Javascript 相关文章推荐
JavaScript CSS修改学习第一章 查找位置
Feb 19 Javascript
jQuery 定时局部刷新(setInterval)
Nov 19 Javascript
什么是MEAN?JavaScript编程中的MEAN是什么意思?
Dec 18 Javascript
js实现每日自动换一张图片的方法
May 04 Javascript
浅析Bootstrap缩略图组件与警示框组件
Apr 29 Javascript
Javascript函数中的arguments.callee用法实例分析
Sep 16 Javascript
jQuery中 $ 符号的冲突问题及解决方案
Nov 04 Javascript
EasyUI Combobox设置默认值 获取text的方法
Nov 28 Javascript
JQuery获取鼠标进入和离开容器的方向
Dec 29 Javascript
js自定义QQ菜单效果
Jan 10 Javascript
angular 实时监听input框value值的变化触发函数方法
Aug 31 Javascript
electron制作仿制qq聊天界面的示例代码
Nov 26 Javascript
异步javascript的原理和实现技巧介绍
Nov 08 #Javascript
找出字符串中出现次数最多的字母和出现次数精简版
Nov 07 #Javascript
jquery 如何动态添加、删除class样式方法介绍
Nov 07 #Javascript
探索Emberjs制作一个简单的Todo应用
Nov 07 #Javascript
关于使用 jBox 对话框的提交不能弹出问题解决方法
Nov 07 #Javascript
seajs1.3.0源码解析之module依赖有序加载
Nov 07 #Javascript
Javascript引用指针使用介绍
Nov 07 #Javascript
You might like
Discuz 5.0 中读取纯真IP数据库函数分析
2007/03/16 PHP
Memcache 在PHP中的使用技巧
2010/02/08 PHP
php 日期和时间的处理-郑阿奇(续)
2011/07/04 PHP
PHP实现UTF-8文件BOM自动检测与移除实例
2014/11/05 PHP
浅谈php冒泡排序
2014/12/30 PHP
PHP实现的超长文本分页显示功能示例
2018/06/04 PHP
Laravel框架生命周期与原理分析
2018/06/12 PHP
PHP切割汉字的常用方法实例总结
2019/04/27 PHP
Laravel解决nesting level错误和隐藏index.php的问题
2019/10/12 PHP
JavaScript 继承的实现
2009/07/09 Javascript
js或者jquery判断图片是否加载完成实现代码
2013/03/20 Javascript
jquery三个关闭弹出层的小示例
2013/11/05 Javascript
JavaScript基础教程之alert弹出提示框实例
2014/10/16 Javascript
jquery实现弹出层效果实例
2015/05/19 Javascript
JS操作COOKIE实现备忘记录的方法
2016/04/01 Javascript
js阻止浏览器默认行为的简单实例
2016/05/15 Javascript
JS验证图片格式和大小并预览的简单实例
2016/10/11 Javascript
JS实现的相册图片左右滚动完整实例
2016/11/23 Javascript
基于JS代码实现简单易用的倒计时 x 天 x 时 x 分 x 秒效果
2017/07/13 Javascript
vue 项目地址去掉 #的方法
2018/10/20 Javascript
使用vscode快速建立vue模板过程详解
2019/10/10 Javascript
JS document对象简单用法完整示例
2020/01/14 Javascript
vue 动态组件用法示例小结
2020/03/06 Javascript
[01:24:09]Ti4 冒泡赛第二轮DK vs C9 1
2014/07/14 DOTA
Python中使用动态变量名的方法
2014/05/06 Python
Python实现根据指定端口探测服务器/模块部署的方法
2014/08/25 Python
Numpy的简单用法小结
2019/08/28 Python
如何使用PyCharm将代码上传到GitHub上(图文详解)
2020/04/27 Python
python使用re模块爬取豆瓣Top250电影
2020/10/20 Python
如何用 Python 制作一个迷宫游戏
2021/02/25 Python
CSS3实现酷炫的3D旋转透视效果
2019/11/21 HTML / CSS
财务与信息服务专业推荐信
2013/11/28 职场文书
暑期社会实践感言
2014/02/25 职场文书
计算机科学与技术专业求职信
2014/09/03 职场文书
整改报告怎么写
2014/11/06 职场文书
2019如何书写演讲稿?
2019/07/01 职场文书