另外这篇文章是一篇入门文章,我也是才开始学习Javascript,有一点心得,才想写一篇这样文章,文章中难免有错误的地方,还请各位不吝吐槽指正
吐槽Javascript
初次接触Javascript,这门语言的确会让很多正规军感到诸多的不适,这种不适来自于Javascript的语法的简练和不严谨,这种不适也来自Javascript这个悲催的名称,我在想网景公司的Javascript设计者在给他起名称那天一定是脑壳进水了,让Javascript这么多年来受了这么多不白之冤,人们都认为他是Java的附属物,一个WEB玩具语言。因此才会有些人会对Javascript不屑,认为Javascript不是一门真正的语言,但是这此他们真的错了。Javascript不仅是一门语言,是一门真真正正的语言,而且他还是一门里程碑式的语言,他独创多种新的编程模式原型继承,闭包(作者注:闭包不是JS首创,应该Scheme首创,prototypal inheritance 和 dynamic objects 是self语言首创,Javascript的首创并不精彩,谢谢网友的指正。),对后来的动态语言产生了巨大的影响。做为当今最流行的语言(没有之一),看看git上提交的最多的语言类型就能明白。随着HTML5的登场,浏览器将在个人电脑上将大显身手,完全有替换OS的趋势的时候,Javascript做为浏览器上的一门唯一真真的语言,如同C之于 unix/linux,java之于JVM,Cobol之于MainFrame,我们也需要来重新的认真地认识和审视这门语言。另外Javascript的正式名称是:ECMAScript,这个名字明显比Javascript帅太多了!
言归正传,我们切入主题——Javascript的面向对象编程。要谈Javascript的面向对象编程,我们第一步要做的事情就是忘记我们所学的面向对象编程。传统C++或Java的面向对象思维来学习Javascript的面向对象会给你带来不少困惑,让我们先忘记我们所学的,从新开始学习这门特殊的面向对象编程。既然是OO编程,要如何来理解OO编程呢,记得以前学C++,学了很久都不入门,后来有幸读了《Inside The C++ Object Model》这本大作,顿时豁然开朗,因此本文也将以对象模型的方式来探讨的Javascript的OO编程。因为Javascript 对象模型的特殊性,所以使得Javascript的继承和传统的继承非常不一样,同时也因为Javascript里面没有类,这意味着Javascript里面没有extends,implements。那么Javascript到底是如何来实现OO编程的呢?好吧,让我们开始吧,一起在Javascript的OO世界里来一次漫游
首先,我们需要先看看Javascript如何定义一个对象。下面是我们的一个对象定义:
复制代码 代码如下:var o = {};
还可以这样定义一个对象
复制代码 代码如下: function f() { }
对,你们没有看错,在Javascript里面,函数也是对象。
当然还可以
复制代码 代码如下:var array1= [ 1,2,3];
数组也是一个对象。
其他关于对象的基本的概念的描述,还是请各位亲们参见陈皓《Javascript 面向对象编程》文章。
对象都有了,唯一没有的就是class,因为在Javascript里面是没有class关键字的,算好还有function,function的存在让我们可以变通的定义类,在扩展这个主题前,我们还需要了解一个Javascript对象最重要的属性,__proto__成员。
__proto__成员
严格的说这个成员不应该叫这个名字,__proto__是Firefox中的称呼,__proto__只有在Firefox浏览器中才能被访问到。做为一个对象,当你访问其中的一个成员或方法的时候,如果这个对象中没有这个方法或成员,那么Javascript引擎将会访问这个对象的__proto__成员所指向的另外的一个对象,并在那个对象中查找指定的方法或成员,如果不能找到,那就会继续通过那个对象的__proto__成员指向的对象进行递归查找,直到这个链表结束。
好了,让我们举一个例子。
比如上上面定义的数组对象array1。当我们创建出array1这个对象的时候,array1实际在Javascript引擎中的对象模型如下:
array1对象具有一个length属性值为3,但是我们可以通过如下的方法来为array1增加元素:
复制代码 代码如下:array1.push(4);
push这个方法来自于array1的__proto__成员指向对象的一个方法(Array.prototye.push())。正是因为所有的数组对象(通过[]来创建的)都包含有一个指向同一个具有push,reverse等方法对象(Array.prototype)的__proto__成员,才使得这些数组对象可以使用push,reverse等方法。
那么这个__proto__这个属性就相当于面向对象中的”has a”关系,这样的的话,只要我们有一个模板对象比如Array.prototype这个对象,然后把其他的对象__proto__属性指向这个对象的话就完成了一种继承的模式。不错!我们完全可以这么干。但是别高兴的太早,这个属性只在FireFox中有效,其他的浏览器虽然也有属性,但是不能通过__proto__来访问,只能通过getPrototypeOf方法进行访问,而且这个属性是只读的。看来我们要在Javascript实现继承并不是很容易的事情啊。
函数对象prototype成员
首先我们先来看一段函数prototype成员的定义,
When a function object is created, it is given a prototype member which is an object containing a constructor member which is a reference to the function object
当一个函数对象被创建时,这个函数对象就具有一个prototype成员,这个成员是一个对象,这个对象包含了一个构造子成员,这个构造子成员会指向这个函数对象。
例如:
复制代码 代码如下: function Base() {
this.id = "base"
}
Base这个函数对象就具有一个prototype成员,关于构造子其实Base函数对象自身,为什么我们将这类函数称为构造子呢?原因是因为这类函数设计来和new 操作符一起使用的。为了和一般的函数对象有所区别,这类函数的首字母一般都大写。构造子的主要作用就是来创建一类相似的对象。
上面这段代码在Javascript引擎的对象模型是这样的
new 操作符 在有上面的基础概念的介绍之后,在加上new操作符,我们就能完成传统面向对象的class + new的方式创建对象,在Javascript中,我们将这类方式成为Pseudoclassical。
基于上面的例子,我们执行如下代码
复制代码 代码如下:var obj = new Base();
这样代码的结果是什么,我们在Javascript引擎中看到的对象模型是:
new操作符具体干了什么呢?其实很简单,就干了三件事情。
复制代码 代码如下: var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);
第一行,我们创建了一个空对象obj
第二行,我们将这个空对象的__proto__成员指向了Base函数对象prototype成员对象
第三行,我们将Base函数对象的this指针替换成obj,然后再调用Base函数,于是我们就给obj对象赋值了一个id成员变量,这个成员变量的值是”base”,关于call函数的用法,请参看陈皓《Javascript 面向对象编程》文章
如果我们给Base.prototype的对象添加一些函数会有什么效果呢?
例如代码如下:
复制代码 代码如下:Base.prototype.toString = function() {
return this.id;
}
那么当我们使用new创建一个新对象的时候,根据__proto__的特性,toString这个方法也可以做新对象的方法被访问到。于是我们看到了:
构造子中,我们来设置‘类'的成员变量(例如:例子中的id),构造子对象prototype中我们来设置‘类'的公共方法。于是通过函数对象和Javascript特有的__proto__与prototype成员及new操作符,模拟出类和类实例化的效果。
Pseudoclassical 继承
我们模拟类,那么继承又该怎么做呢?其实很简单,我们只要将构造子的prototype指向父类即可。例如我们设计一个Derive 类。如下
复制代码 代码如下: function Derive(id) {
this.id = id;
}
Derive.prototype = new Base();
Derive.prototype.test = function(id){
return this.id === id;
}
var newObj = new Derive("derive");
这段代码执行后的对象模型又是怎么样的呢?根据之前的推导,应该是如下的对象模型
这样我们的newObj也继承了基类Base的toString方法,并且具有自身的成员id。关于这个对象模型是如何被推导出来的就留给各位同学了,参照前面的描述,推导这个对象模型应该不难。
Pseudoclassical继承会让学过C++/Java的同学略微的感受到一点舒服,特别是new关键字,看到都特亲切,不过两者虽然相似,但是机理完全不同。当然不关什么样继承都是不能离不开__proto__成员的。
Prototypal继承 这是Javascript的另外一种继承方式,这个继承也就是之前陈皓文章《Javascript 面向对象编程》中create函数,非常可惜的是这个是ECMAScript V5的标准,支持V5的浏览器目前看来也就是IE9,Chrome最新版本和Firefox。虽然看着多,但是做为IE6的重灾区的中国,我建议各位还是避免使用create函数。好在没有create函数之前,Javascript的使用者已经设计出了等同于这个函数的。例如:我们看看Douglas Crockford的object函数。
复制代码 代码如下:function object(old) {
function F() {};
F.prototype = old;
return new F();
}
var newObj = object(oldObject);
例如如下代码段
复制代码 代码如下:var base ={
id:"base",
toString:function(){
return this.id;
}
};
var derive = object(base);
上面函数的执行后的对象模型是:
如何形成这样的对象模型,原理也很简单,只要把object这个函数扩展一下,就能画出这个模型,怎么画留给读者自己去画吧。
这样的继承方式被称为原型继承。相对来说要比Pseudoclassical继承来的简单方便。ECMAScript V5正是因为这原因也才增加create函数,让开发者可以快速的实现原型继承。
上述两种继承方式是Javascript中最常用的继承方式。通过本文的讲解,你应该对Javascript的OO编程有了一些‘原理'级的了解了吧
参考:
《Prototypes and Inheritance in JavaScript Prototypes and Inheritance in JavaScript》
Advance Javascript (Douglas Crockford 大神的视频,一定要看啊)题外话:
web2.0后,web应用可谓飞速发展,如今在HTML5发布之际,浏览器的功能被大大强化,我感觉Browser远远在不是一个Browser那么简单了。记得C++之父曾经这样说过JAVA,JAVA不是跨平台,JAVA本身就是一个平台。如今的Browser也本身就是一个平台了,好在这个平台是基于标准的。如果Browser是平台,由于Browser安全沙箱的限制,个人电脑的资源被使用的很少,感觉Browser就是一个NC(Network Computer)?我们居然又回到了Sun最初提出的构想,Sun是不是太强大了些?
相关推荐:
SEO课:让你从小白变成搜索引擎优化高手,推广自媒体营销计划
seo进阶买什么书运营,seo入门难吗 ,没有ai软件怎么打开ai图片
360排名优化价格:打造高效网络营销的制胜法宝,ai换脸刘浩存自wei
SEO更多-让你的企业站点在搜索引擎中脱颖而出,如何结交seo大神
ChatGPT安装包Windows版:让AI助力你的工作与生活,人工智能ai不是梦在线
什么是seo艺术,什么是seo seo有何价值 ,ai写作生成器 推荐
ChatGPT:引领人工智能对话新时代的智能助手,Ai shiang
OpenAI网站崩溃原因:背后的技术与挑战,千牛Ai智投在哪里找
在线AI生成文章:智能写作的未来趋势
ChatGPT登录界面都不显示了?可能是这些原因导致的!,上海小学ai智能课
SEO站群:打造强大网络营销引擎,助力企业快速提升排名与流量,seo网站排名案例
ChatGPT一经发布,便受到了用户的狂热追捧,引爆人工智能热潮,十代ai达人办公本
SEO优化做什么的?揭秘SEO优化的核心价值与实战应用,ai做金色
ChatGPT网络故障报告从协调世界时(UTC)晚上1107左右开始激增,15分钟内引发广泛关注,ai无视进化
SEO在广告领域的深度解析:如何利用SEO提升广告效果,网文写作ai工具
Chatttst:开启智能沟通新时代的无限可能,上海联通ai
ChatGPTO1免费:突破智能聊天的极限,体验AI无限可能,糯米ai唱歌
提升写作效率,释放创意潜力文章生成AI软件的未来
为什么seo推广那么多,seo推广难吗 ,东莞ai听译平台
为什么“蜘蛛弛查询”能成为提升网站排名的秘密武器?,惠州网站推广v1戈seo24
SEO招标:如何通过专业SEO服务助力企业脱颖而出,牡丹江关键词排名怎么样
ChatGPT免费版下载:智能对话助手带来的全新体验,电脑怎么下载Ai微认证
ChatGPT崩一次多久修复?揭秘背后的技术与保障,ai1818818
AI网页版本:开启智能时代的新篇章,拼音标调ai
Bing搜索的注意事项-提高搜索效率与准确性,轻松获取所需信息,最近ai写作软件推荐
SEO优化知识全解析:提升网站排名的秘密武器,ai出错合集
如何用AI写公众号文章?让创作更高效、更轻松
SEO优化与SEM广告:提升品牌曝光与流量的双重利器,ai接回头
AI的两个主要发展阶段:从起步到突破,如何重塑未来,wps ai写作去哪里
seo网站关键字排名优化,网站seo关键词 ,运动ai
SEO关键词推广软件官网-助力企业实现高效精准的网络营销,圈圈ai
SEO目标:让您的网站轻松登顶搜索引擎,优化购物网站的搜索
SEO首选:如何通过优化网站提升排名和流量,简单的网站优化软件
SEO刷:让你的网站一夜之间登顶搜索引擎!,独特seo技巧
SEO更好,让你的网站从此脱颖而出,渝中的知名网站建设
SEO广告:如何借助SEO提升品牌曝光与销售业绩?,网站推广怎么选择
ChatGPT故障:科技背后的秘密与应对策略,华为什么手机带ai功能
SEO找出网站流量提升的终极策略,带你走向搜索引擎巅峰!,朝阳模板网站建设价格
亚马逊中什么是seo,亚马逊sop ,ai临摹中国名画
seo网站排名优化哪家好,seo网站优化平台 ,ai斗蟋
AI写作技巧,让创作事半功倍!
WPJVX:开启数字化未来的智慧平台,关键词排名技术咨询乐云seo
为什么选择老域名注册,打造品牌价值的秘密武器,网站建设服务费用多少
SEO开发:数字营销的核心驱动力,园区网站建设
SEO全站优化:打造强大网站排名的必备利器,AI论文写作的优点
ChatGPT启动时遇到问题?快速解决方案让你畅享智能对话体验,ai如何保存logo
怎么用AI生成文章?全新写作方式的揭秘与应用指南
Chatget免费网站版无需登录,畅享无限对话体验!,工业 Ai 视觉检测
SEO搜索关键词是什么意思?让你轻松网站流量的秘密!,ai颜色不对
SEO目的:如何通过精准优化提高网站流量与转化率,百度推广网站关键词