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 火狐(firefox)不显示本地图片问题解决
Jul 05 Javascript
javascript 命名规则 变量命名规则
Feb 25 Javascript
javascript中IE浏览器不支持NEW DATE()带参数的解决方法
Mar 01 Javascript
jquery实现邮箱自动填充提示功能
Nov 17 Javascript
js控制TR的显示隐藏
Mar 04 Javascript
微信小程序 标签传入数据
May 08 Javascript
使用jQuery实现页面定时弹出广告效果
Aug 24 jQuery
vue.js的手脚架vue-cli项目搭建的步骤
Aug 30 Javascript
微信小程序实现语音识别转文字功能及遇到的坑
Aug 02 Javascript
node.js文件操作系统实例详解
Nov 05 Javascript
使用Vue 自定义文件选择器组件的实例代码
Mar 04 Javascript
利用Vue实现简易播放器的完整代码
Dec 30 Vue.js
异步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
PHP empty函数报错解决办法
2014/03/06 PHP
php异步多线程swoole用法实例
2014/11/14 PHP
PHP使用数组实现矩阵数学运算的方法示例
2017/05/29 PHP
PHP创建自己的Composer包方法
2018/04/09 PHP
扩展String功能方法
2006/09/22 Javascript
JavaScript 全面解析各种浏览器网页中的JS 执行顺序
2009/02/17 Javascript
利用javascript实现一些常用软件的下载导航
2009/08/03 Javascript
Firefox下提示illegal character并出现乱码的原因
2010/03/25 Javascript
jquery表单验证使用插件formValidator
2012/11/10 Javascript
基于javascipt-dom编程 table对象的使用
2013/04/22 Javascript
分享10个原生JavaScript技巧
2015/04/20 Javascript
纯javascript移动优先的幻灯片效果
2015/11/02 Javascript
基于canvas实现的绚丽圆圈效果完整实例
2016/01/26 Javascript
使用jquery提交form表单并自定义action的实现代码
2016/05/25 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
2016/07/25 Javascript
JS前端知识点总结之页面加载事件,数组操作,DOM节点操作,循环和分支
2019/07/04 Javascript
JS实现json数组排序操作实例分析
2019/10/28 Javascript
python实现的希尔排序算法实例
2015/07/01 Python
PythonWeb项目Django部署在Ubuntu18.04腾讯云主机上
2019/04/01 Python
如何获取Python简单for循环索引
2019/11/21 Python
python绘制规则网络图形实例
2019/12/09 Python
Python连接字符串过程详解
2020/01/06 Python
使用Python打造一款间谍程序的流程分析
2020/02/21 Python
解决django无法访问本地static文件(js,css,img)网页里js,cs都加载不了
2020/04/07 Python
详解Django中views数据查询使用locals()函数进行优化
2020/08/24 Python
Python fileinput模块如何逐行读取多个文件
2020/10/05 Python
HTML5实现视频直播功能思路详解
2017/11/16 HTML / CSS
存储过程的优点有哪些
2012/09/27 面试题
桥梁与隧道工程专业本科生求职信
2013/10/08 职场文书
广告学专业推荐信范文
2013/11/23 职场文书
财务会计求职信范文
2015/03/20 职场文书
员工离职证明范本
2015/06/12 职场文书
护士医德医风心得体会
2016/01/25 职场文书
导游词之麻姑仙境
2019/11/18 职场文书
python 安全地删除列表元素的方法
2022/03/16 Python
MySQL索引失效十种场景与优化方案
2023/05/08 MySQL