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 substr、substring和slice使用说明小记
Sep 15 Javascript
JS刷新框架外页面七种实现代码
Feb 18 Javascript
JQuery中阻止事件冒泡几种方式及其区别介绍
Jan 15 Javascript
js二维数组定义和初始化的三种方法总结
Mar 03 Javascript
jQuery实现有动画淡出效果的二级折叠菜单代码
Oct 17 Javascript
学习使用grunt来打包JavaScript和CSS程序的教程
Jan 04 Javascript
Bootstrap实现的经典栅格布局效果实例【附demo源码】
Mar 30 Javascript
JS实现禁止高频率连续点击的方法【基于ES6语法】
Apr 25 Javascript
Vue中的$set的使用实例代码
Oct 08 Javascript
JS实现集合的交集、补集、差集、去重运算示例【ES5与ES6写法】
Feb 18 Javascript
基于vue-cli3创建libs库的实现方法
Dec 04 Javascript
解决Antd Table组件表头不对齐的问题
Oct 27 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
ThinkPHP中实例Model方法的区别说明
2010/08/21 PHP
PHP按行读取、处理较大CSV文件的代码实例
2014/04/09 PHP
PHP模拟asp.net的StringBuilder类实现方法
2015/08/08 PHP
通过修改Laravel Auth使用salt和password进行认证用户详解
2017/08/17 PHP
PHP创建自己的Composer包方法
2018/04/09 PHP
PHP+redis实现的限制抢购防止商品超发功能详解
2019/09/19 PHP
jquery.cookie.js 操作cookie实现记住密码功能的实现代码
2011/04/27 Javascript
js导航栏单击事件背景变换示例代码
2014/01/13 Javascript
jQuery替换textarea中换行的方法
2015/06/10 Javascript
JavaScript组合模式学习要点
2016/08/26 Javascript
javascript表单控件实例讲解
2016/09/13 Javascript
AngularJS实现ajax请求的方法
2016/11/22 Javascript
zTree异步加载展开第一级节点的实现方法
2017/09/05 Javascript
在小程序中使用腾讯视频插件播放教程视频的方法
2018/07/10 Javascript
JavaScript函数、闭包、原型、面向对象学习笔记
2018/09/06 Javascript
js计算两个时间差 天 时 分 秒 毫秒的代码
2019/05/21 Javascript
如何在JavaScript中谨慎使用代码注释
2019/06/21 Javascript
使用Phantomjs和Node完成网页的截屏快照的方法
2019/07/16 Javascript
通过实例了解Nodejs模块系统及require机制
2020/07/16 NodeJs
Vue Object.defineProperty及ProxyVue实现双向数据绑定
2020/09/02 Javascript
[00:36]DOTA2风云人物相约完美“圣”典 12月17日不见不散
2016/11/30 DOTA
Python、Javascript中的闭包比较
2015/02/04 Python
Python Django简单实现session登录注销过程详解
2019/08/06 Python
关于Python 中的时间处理包datetime和arrow的方法详解
2020/03/19 Python
django执行数据库查询之后实现返回的结果集转json
2020/03/31 Python
css3旋转木马_动力节点Java学院整理
2017/07/12 HTML / CSS
html5使用Canvas绘图的使用方法
2017/11/21 HTML / CSS
德国原装品牌香水、化妆品和手表网站:BRASTY.DE
2016/10/16 全球购物
澳大利亚香水在线:Price Rite Mart
2017/12/28 全球购物
英语专业学子个人的自我评价
2013/10/02 职场文书
加拿大探亲邀请信
2014/01/28 职场文书
收费员岗位职责
2015/02/14 职场文书
简历自荐信范文
2015/03/09 职场文书
中学生清明节演讲稿
2015/03/18 职场文书
跳高加油稿
2015/07/21 职场文书
Python常遇到的错误和异常
2021/11/02 Python