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写的select支持上下键、首字母筛选以及回车取值的功能
Sep 09 Javascript
键盘 keycode的值 javascript时触发事件时很有用的要素
Nov 02 Javascript
jQuery EasyUI API 中文文档 - NumberBox数字框
Oct 13 Javascript
在js中判断checkboxlist(.net控件客户端id)是否有选中
Apr 11 Javascript
js分页工具实例
Jan 28 Javascript
Bootstrap每天必学之按钮(Button)插件
Apr 25 Javascript
通过JS和PHP两种方法判断用户请求时使用的浏览器类型
Sep 01 Javascript
Vue.js每天必学之构造器与生命周期
Sep 05 Javascript
浅谈jquery中使用canvas的问题
Oct 10 Javascript
Javascript调试之console对象——你不知道的一些小技巧
Jul 10 Javascript
日期时间范围选择插件:daterangepicker使用总结(必看篇)
Sep 14 Javascript
jQuery中使用validate插件校验表单功能
May 24 jQuery
异步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
mysql5详细安装教程
2007/01/15 PHP
无刷新动态加载数据 滚动条加载适合评论等页面
2013/10/16 PHP
destoon在各个服务器下设置URL Rewrite(伪静态)的方法
2014/06/21 Servers
php中将一个对象保存到Session中的方法
2015/03/13 PHP
php随机获取金山词霸每日一句的方法
2015/07/09 PHP
PHP判断文件是否被引入的方法get_included_files用法示例
2016/11/29 PHP
javascript分页代码(当前页码居中)
2012/09/20 Javascript
js中数组(Array)的排序(sort)注意事项说明
2014/01/24 Javascript
jQuery写fadeTo示例代码
2014/02/21 Javascript
打造个性化的功能强大的Jquery虚拟键盘(VirtualKeyboard)
2014/10/11 Javascript
JavaScript实现网站访问次数统计代码
2015/08/12 Javascript
详解jQuery向动态生成的内容添加事件响应jQuery live()方法
2015/11/02 Javascript
javascript基础语法——全面理解变量和标识符
2016/06/02 Javascript
js数据类型检测总结
2018/08/05 Javascript
详解ES6 Fetch API HTTP请求实用指南
2018/11/14 Javascript
解决layer 动态加载select 失效的问题
2019/09/18 Javascript
koa-passport实现本地验证的方法示例
2020/02/20 Javascript
angular *Ngif else用法详解
2020/12/15 Javascript
[02:40]DOTA2殁境神蚀者 英雄基础教程
2013/11/26 DOTA
[02:10]2018DOTA2亚洲邀请赛赛前采访-Liquid
2018/04/03 DOTA
[01:00:12]2018DOTA2亚洲邀请赛 4.7 淘汰赛 VP vs LGD 第一场
2018/04/09 DOTA
Python中类的定义、继承及使用对象实例详解
2015/04/30 Python
浅谈Python 列表字典赋值的陷阱
2019/01/20 Python
python实现自动解数独小程序
2019/01/21 Python
pycharm显示远程图片的实现
2019/11/04 Python
Python 实现将数组/矩阵转换成Image类
2020/01/09 Python
Python list运算操作代码实例解析
2020/01/20 Python
django ObjectDoesNotExist 和 DoesNotExist的用法
2020/07/09 Python
意大利奢侈品多品牌集合店:TheDoubleF
2019/08/24 全球购物
个人先进事迹材料
2014/12/29 职场文书
电影建国大业观后感
2015/06/01 职场文书
大学生暑假实习总结
2015/07/13 职场文书
运动会800米赞词
2015/07/22 职场文书
《自己的花是让别人看的》教学反思
2016/02/19 职场文书
Django实现翻页的示例代码
2021/05/24 Python
nginx结合openssl实现https的方法
2021/07/25 Servers