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 相关文章推荐
ie支持function.bind()方法实现代码
Dec 27 Javascript
jquery获得keycode的示例代码
Dec 30 Javascript
js判断上传文件类型判断FileUpload文件类型代码
May 20 Javascript
JS实现的表头列头固定页面功能示例
Jan 10 Javascript
基于JS实现仿京东搜索栏随滑动透明度渐变效果
Jul 10 Javascript
vue2.0移除或更改的一些东西(移除index key)
Aug 28 Javascript
基于vue实现web端超大数据量表格的卡顿解决
Apr 02 Javascript
vue router导航守卫(router.beforeEach())的使用详解
Apr 19 Javascript
微信公众号服务器验证Token步骤图解
Dec 30 Javascript
BootStrap前端框架使用方法详解
Feb 26 Javascript
图解JS原型和原型链实现原理
Sep 15 Javascript
JS操作JSON常用方法(10w阅读)
Dec 06 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
日本十大科幻动漫 宇宙骑士垫底,第一已成经典
2020/03/04 日漫
PHP中Date获取时间不正确怎么办
2008/06/05 PHP
探讨PHP调用时间格式的参数详解
2013/06/06 PHP
ThinkPHP公共配置文件与各自项目中配置文件组合的方法
2014/11/24 PHP
php统计数组元素个数的方法
2015/07/02 PHP
利用PHP判断是手机移动端还是PC端访问的函数示例
2017/12/14 PHP
Ajax+PHP实现的分类列表框功能示例
2019/02/11 PHP
jQuery实现长文字部分显示代码
2013/05/13 Javascript
jquery fancybox ie6不显示关闭按钮的解决办法
2013/12/25 Javascript
Jquery $.getJSON 在IE下的缓存问题解决方法
2014/10/10 Javascript
node.js中的path.delimiter方法使用说明
2014/12/09 Javascript
jquery加载图片时以淡入方式显示的方法
2015/01/14 Javascript
JavaScript中计算网页中某个元素的位置
2015/06/10 Javascript
jQuery Ztree行政地区树状展示(点击加载)
2016/11/09 Javascript
详解Nodejs之静态资源处理
2017/06/05 NodeJs
基于jQuery实现的Ajax 验证用户名唯一性实例代码
2017/06/28 jQuery
使用JS中的Replace()方法遇到的问题小结
2017/10/20 Javascript
vue解决弹出蒙层滑动穿透问题的方法
2018/09/22 Javascript
[36:02]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第一局
2016/02/28 DOTA
使用beaker让Facebook的Bottle框架支持session功能
2015/04/23 Python
分享Python开发中要注意的十个小贴士
2016/08/30 Python
Python玩转Excel的读写改实例
2019/02/22 Python
在Python中COM口的调用方法
2019/07/03 Python
Python matplotlib绘制图形实例(包括点,曲线,注释和箭头)
2020/04/17 Python
python 在sql语句中使用%s,%d,%f说明
2020/06/06 Python
浅谈优化Django ORM中的性能问题
2020/07/09 Python
CSS3制作日历实现代码
2012/01/21 HTML / CSS
基于Modernizr 让网站进行优雅降级的分析
2013/04/21 HTML / CSS
AmazeUI的下载配置与Helloworld的实现
2020/08/19 HTML / CSS
消防安全宣传标语
2014/06/07 职场文书
离职证明标准格式
2014/09/15 职场文书
报表员工作失误检讨书范文
2014/09/19 职场文书
2014年幼儿园班级工作总结
2014/12/17 职场文书
大学生学生会工作总结2015
2015/05/26 职场文书
2015年中学团委工作总结
2015/07/22 职场文书
参加招聘会后的感想
2015/08/10 职场文书