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 相关文章推荐
js中巧用cssText属性批量操作样式
Mar 13 Javascript
jQuery EasyUI API 中文文档 - Tabs标签页/选项卡
Oct 01 Javascript
JS实现图片翻书效果示例代码
Sep 09 Javascript
jquery表单验证插件formValidator使用方法
Apr 01 Javascript
JavaScript实现多栏目切换效果
Dec 12 Javascript
js+div+css下拉导航菜单完整代码分享
Dec 28 Javascript
jquery.validate.js 多个相同name的处理方式
Jul 10 jQuery
JavaScript内存泄漏的处理方式
Nov 20 Javascript
浅析Vue.js 中的条件渲染指令
Nov 19 Javascript
JS+HTML5 canvas绘制验证码示例
Dec 05 Javascript
vue.js实现照片放大功能
Jun 23 Javascript
基于脚手架创建Vue项目实现步骤详解
Aug 03 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
php 常用算法和时间复杂度
2013/07/01 PHP
PHP实现求两个字符串最长公共子串的方法示例
2017/11/17 PHP
document 和 document.all 分别什么时候用
2006/06/22 Javascript
asp.net+jquery滚动滚动条加载数据的下拉控件
2010/06/25 Javascript
同一页面多个商品倒计时JS 基于面向对象的javascript
2012/02/16 Javascript
jQuery实现密保互斥问题解决方案
2013/08/16 Javascript
javascript列表框操作函数集合汇总
2013/11/28 Javascript
jquery对ajax的支持介绍
2013/12/10 Javascript
介绍JavaScript的一个微型模版
2015/06/24 Javascript
jQuery弹层插件jquery.fancybox.js用法实例
2016/01/22 Javascript
JavaScript探测CSS动画是否已经完成的方法
2016/08/30 Javascript
详谈Ajax请求中的async:false/true的作用(ajax 在外部调用问题)
2017/02/10 Javascript
基于node.js依赖express解析post请求四种数据格式
2017/02/13 Javascript
Angular.js实现动态加载组件详解
2017/05/28 Javascript
微信小程序使用form表单获取输入框数据的实例代码
2018/05/17 Javascript
Vue组件通信入门之Provide和Inject机制
2019/12/29 Javascript
JS实现简单日历特效
2020/01/03 Javascript
jQuery使用jsonp实现百度搜索的示例代码
2020/07/08 jQuery
简单谈谈python中的Queue与多进程
2016/08/25 Python
浅谈Python中range和xrange的区别
2017/12/20 Python
Python元组拆包和具名元组解析实例详解
2018/03/26 Python
python list是否包含另一个list所有元素的实例
2018/05/04 Python
解决python "No module named pip" 的问题
2018/10/13 Python
对python 合并 累加两个dict的实例详解
2019/01/21 Python
python儿童学游戏编程知识点总结
2019/06/03 Python
Python+OpenCV实现将图像转换为二进制格式
2020/01/09 Python
Matplotlib.pyplot 三维绘图的实现示例
2020/07/28 Python
详解Html5 Canvas画线有毛边解决方法
2018/03/01 HTML / CSS
html5是什么_动力节点Java学院整理
2017/07/07 HTML / CSS
使用Html5中的cavas画一面国旗
2019/09/25 HTML / CSS
美国知名生活购物网站:Goop
2017/11/03 全球购物
Expedia加拿大官方网站:加拿大最大的在线旅游提供商
2017/12/31 全球购物
知名企业招聘广告词大全
2014/03/18 职场文书
倡议书格式范文
2014/04/14 职场文书
2014年重阳节老干部座谈会局领导发言稿
2014/09/25 职场文书
2016学习雷锋精神活动倡议书
2015/04/27 职场文书