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 年会抽奖程序
Dec 22 Javascript
基于jquery实现页面滚动时顶部导航显示隐藏
Apr 20 Javascript
浏览器环境下JavaScript脚本加载与执行探析之动态脚本与Ajax脚本注入
Jan 19 Javascript
Angular2使用Angular-CLI快速搭建工程(二)
May 21 Javascript
Javascript实现找不同色块的游戏
Jul 17 Javascript
Angular中自定义Debounce Click指令防止重复点击
Jul 26 Javascript
jQuery实现的弹幕效果完整实例
Sep 06 jQuery
JavaScript 中的 this 简单规则
Sep 19 Javascript
JavaScrip关于创建常量的知识点
Dec 07 Javascript
JavaScript实现的拼图算法分析
Feb 13 Javascript
微信小程序select下拉框实现效果
May 15 Javascript
解决VantUI popup 弹窗不弹出或无蒙层的问题
Nov 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使用qr生成二维码的示例分享
2014/01/20 PHP
php实现水仙花数示例分享
2014/04/03 PHP
PHP实现的简单网络硬盘
2015/07/29 PHP
php生成Android客户端扫描可登录的二维码
2016/05/13 PHP
基于jQuery制作迷你背词汇工具
2010/07/27 Javascript
jquery $.ajax各个事件执行顺序
2010/10/15 Javascript
jQuery的初始化与对象构建之浅析
2011/04/12 Javascript
关于jquery css的使用介绍
2013/04/18 Javascript
JavaScript二维数组实现的省市联动菜单
2014/05/08 Javascript
js中定义一个变量并判断其是否为空的方法
2014/05/13 Javascript
JavaScript中的对象与JSON
2015/07/03 Javascript
一不小心就做错的JS闭包面试题
2015/11/25 Javascript
详解jQuery移动页面开发中的ui-grid网格布局使用
2015/12/03 Javascript
Vue.js双向绑定操作技巧(初级入门)
2016/12/27 Javascript
JS正则RegExp.test()使用注意事项(不具有重复性)
2016/12/28 Javascript
express 项目分层实践详解
2018/12/10 Javascript
vue封装一个简单的div框选时间的组件的方法
2019/01/06 Javascript
一篇文章看懂JavaScript中的回调
2021/01/05 Javascript
[00:30]塑造者的传承礼包-戴泽“暗影之焰”套装展示视频
2014/04/04 DOTA
[04:13]2018国际邀请赛典藏宝瓶Ⅱ饰品一览
2018/07/21 DOTA
python使用in操作符时元组和数组的区别分析
2015/05/19 Python
详解python分布式进程
2018/10/08 Python
利用python Selenium实现自动登陆京东签到领金币功能
2019/10/31 Python
python 实现让字典的value 成为列表
2019/12/16 Python
HTML5 File接口在web页面上使用文件下载
2017/02/27 HTML / CSS
初中生期末考试的自我评价
2013/12/17 职场文书
教师评优事迹材料
2014/01/10 职场文书
国贸专业的职业规划书
2014/03/15 职场文书
群众路线教育实践活动批评与自我批评
2014/09/15 职场文书
2014年管理人员工作总结
2014/12/01 职场文书
安全学习心得体会范文
2016/01/18 职场文书
Python3 类型标注支持操作
2021/06/02 Python
MySQL连接查询你真的学会了吗?
2021/06/02 MySQL
如何正确理解python装饰器
2021/06/15 Python
一篇带你入门Java垃圾回收器
2021/06/16 Java/Android
MySQL中EXPLAIN语句及用法
2022/05/20 MySQL