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 相关文章推荐
基于jQuery的弹出消息插件 DivAlert之旅(一)
Apr 01 Javascript
鼠标移到导航当前位置的LI变色处于选中状态
Aug 23 Javascript
JavaScript原型链示例分享
Jan 26 Javascript
Javascript高级技巧分享
Feb 25 Javascript
全面兼容的javascript时间格式化函数(比较实用)
May 14 Javascript
jquery实现将获取的颜色值转换为十六进制形式的方法
Dec 20 Javascript
javascript正则表达式之search()用法实例
Jan 19 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
Jul 05 Javascript
js实现鼠标拖拽多选功能示例
Aug 01 Javascript
面试题:react和vue的区别分析
Apr 08 Javascript
JavaScript async/await原理及实例解析
Dec 02 Javascript
吃通javascript正则表达式
Apr 21 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写的MySQL数据库用户认证系统代码
2007/03/22 PHP
使用php来实现网络服务
2009/09/15 PHP
php Rename 更改文件、文件夹名称
2011/05/24 PHP
php实现用手机关闭计算机(电脑)的方法
2015/04/22 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
javascript优先加载笔记代码
2008/09/30 Javascript
cument.execCommand()用法深入理解
2012/12/04 Javascript
纯js实现瀑布流展现照片(自动适应窗口大小)
2013/04/08 Javascript
JS小功能(onmouseover实现选择月份)实例代码
2013/11/28 Javascript
Firefox下无法正常显示年份的解决方法
2014/09/04 Javascript
jQuery使用模式窗口实现在主页面和子页面中互相传值的方法
2016/03/01 Javascript
全面解析JavaScript中的valueOf与toString方法(推荐)
2016/06/14 Javascript
微信小程序 后台登录(非微信账号)实例详解
2017/03/31 Javascript
Vue侧滑菜单组件——DrawerLayout
2017/12/18 Javascript
vue axios数据请求及vue中使用axios的方法
2018/09/10 Javascript
在vue中高德地图引入和轨迹的绘制的实现
2019/10/11 Javascript
微信小程序webSocket的使用方法
2020/02/20 Javascript
Vue +WebSocket + WaveSurferJS 实现H5聊天对话交互的实例
2020/11/18 Vue.js
JS如何实现在弹出窗口中加载页面
2020/12/03 Javascript
[03:22]DSPL第一期精彩集锦:酷炫到底!
2014/11/07 DOTA
[02:03]DOTA2亚洲邀请赛 HGT战队出场宣传片
2015/02/07 DOTA
python利用装饰器进行运算的实例分析
2015/08/04 Python
Python设计模式编程中Adapter适配器模式的使用实例
2016/03/02 Python
Python的Tkinter点击按钮触发事件的例子
2019/07/19 Python
python实现的爬取电影下载链接功能示例
2019/08/26 Python
Python3显示当前时间、计算时间差及时间加减法示例代码
2019/09/07 Python
python zip()函数使用方法解析
2019/10/31 Python
浅谈pytorch卷积核大小的设置对全连接神经元的影响
2020/01/10 Python
开启Django博客的RSS功能的实现方法
2020/02/17 Python
女子锻炼服装和瑜伽服装:Splits59
2019/03/04 全球购物
汽车销售求职自荐信
2013/10/01 职场文书
各营销点岗位职责范本
2014/03/05 职场文书
2014年办公室文秘工作总结
2014/12/09 职场文书
营销计划书范文
2015/01/17 职场文书
幼儿教师小班个人总结
2015/02/05 职场文书
nginx中封禁ip和允许内网ip访问的实现示例
2022/03/17 Servers