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 相关文章推荐
慎用 somefunction.prototype 分析
Jun 02 Javascript
JavaScript高级程序设计(第3版)学习笔记10 再访js对象
Oct 11 Javascript
详解javascript高级定时器
Dec 31 Javascript
关于cookie的初识和运用(js和jq)
Apr 07 Javascript
js数组与字符串常用方法总结
Jan 13 Javascript
Bootstrap中glyphicons-halflings-regular.woff字体报404错notfound的解决方法
Jan 19 Javascript
微信小程序 实现列表项滑动显示删除按钮的功能
Apr 13 Javascript
Vue的百度地图插件尝试使用
Sep 06 Javascript
SVG实现时钟效果
Jul 17 Javascript
更强大的vue ssr实现预取数据的方式
Jul 19 Javascript
node读写Excel操作实例分析
Nov 06 Javascript
JQuery常用选择器功能与用法实例分析
Dec 23 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
2020年4月放送!《Princess Connect Re:Dive》制作组 & 角色声优公开!
2020/03/06 日漫
使用adodb lite解决问题
2006/12/31 PHP
PHP开发中常用的8个小技巧
2008/08/27 PHP
关于php正则匹配汉字的方法介绍
2013/04/25 PHP
浅谈php错误提示及查错方法
2015/07/14 PHP
Smarty分页实现方法完整实例
2016/05/11 PHP
php+mysql+jquery实现简易的检索自动补全提示功能
2017/04/15 PHP
用javascript父窗口控制只弹出一个子窗口
2007/04/10 Javascript
几款极品的javascript压缩混淆工具
2007/05/16 Javascript
window.location和document.location的区别分析
2008/12/23 Javascript
IE6浏览器下resize事件被执行了多次解决方法
2012/12/11 Javascript
如何判断微信内置浏览器(通过User Agent实现)
2014/09/01 Javascript
jquery UI Datepicker时间控件的使用方法(加强版)
2015/11/07 Javascript
JavaScript小技巧整理
2015/12/30 Javascript
Jquery和angularjs获取check框选中的值的方法汇总
2016/01/17 Javascript
javascript中this指向详解
2016/04/23 Javascript
Listloading.js移动端上拉下拉刷新组件
2016/08/04 Javascript
Bootstrap学习笔记之进度条、媒体对象实例详解
2017/03/09 Javascript
阿里大于短信验证码node koa2的实现代码(最新)
2017/09/07 Javascript
JS和JQuery实现雪花飘落效果
2017/11/30 jQuery
layer弹出的iframe层在执行完毕后关闭当前弹出层的方法
2018/08/17 Javascript
JS+php后台实现文件上传功能详解
2019/03/02 Javascript
js实现简单五子棋游戏
2020/05/28 Javascript
Vue跨域请求问题解决方案过程解析
2020/08/07 Javascript
使用Mock.js生成前端测试数据
2020/12/13 Javascript
python使用正则表达式替换匹配成功的组
2017/11/17 Python
python实现按首字母分类查找功能
2019/10/31 Python
HTML5中5个简单实用的API(第二篇,含全屏、可见性、拍照、预加载、电池状态)
2014/05/07 HTML / CSS
使用phonegap播放音频的实现方法
2017/03/31 HTML / CSS
这76道Java面试题及答案,祝你能成功通过面试
2016/04/16 面试题
初三家长会邀请函
2014/01/18 职场文书
幼儿园门卫制度
2014/01/29 职场文书
会计电算化大学生职业规划书
2014/02/05 职场文书
党员演讲稿
2014/09/04 职场文书
投资意向协议书
2015/01/29 职场文书
自我检讨书怎么写
2015/05/07 职场文书