javascript中的面向对象(object

本文原发于我的,经多次修改放到csdn上,主要是做备份用,为了更好的阅读体验,请到我的个人博客上阅读。

最近工作一直在用nodejs做开发,有了nodejs,前端、后端、脚本全都可以用javascript搞定,很是方便。但是javascript的很多语法,比如对象,就和我们常用的面向对象的编程语言不同;看某个javascript开源项目,也经常会看到使用this关键字,而这个this关键字在javascript中因上下文不同而意义不同;还有让人奇怪的原型链。这些零零碎碎的东西加起来就很容易让人不知所措,所以,有必要对javascript这门语言进行一下深入了解。

我这篇文章主要想说说如何在javascript中进行面向对象的编程,同时会讲一些javascript这门语言在设计之初的理念。下面让我们开始吧。 首先强调一下,我们现在广泛使用的javascript都是遵循了标准的,正在制定中的版本为6.0,这个版本变化很大,增加了很多新的语法与函数,大家可以去上查看。

设计理念

javascript1.0 最初是由网景公司的Brendan Eich在1995年5月花了十天搞出来的,Eich的目标是设计出一种即轻量又强大的语言,所以Eich充分借鉴了其他编程语言的特性,比如Java的语法(syntax)、Scheme的函数(function)、Self的原型继承(prototypal inheritance)、Perl的正则表达式等。 其中值得一提的是,为什么继承借鉴了Self语言的原型机制而不是Java的类机制?首先我们要知道: – Self的原型机制是靠运行时的语义 – Java的类机制是靠编译时的类语法

Javascript1.0的功能相对简单,为了在今后不断丰富javascript本身功能的同时保持旧代码的兼容性,javascript通过改变运行时的支持来增加新功能,而不是通过修改javascript的语法,这就保证了旧代码的兼容性。这也就是javascript选择基于运行时的原型机制的原因。 wikipedia这样描述到:JavaScript is classified as a prototype-based scripting language with dynamic typing and first-class functions。这些特性使得javascript是一种多范式的解释性编程语言,支持面向对象,命令式(imperative), 函数式(functional)编程风格。

对象

在javascript中,除了数字、字符串、布尔值(true/false)、undefined这几个简单类型外,其他的都是对象。 数字、字符串、布尔值这些简单类型都是不可变量,对象是可变的键值对的集合(mutable keyed conllections),对象包括数组Array、正则表达式RegExp、函数Function,当然对象Object也是对象。 对象在javascript中说白了就是一系列的键值对。键可以是任何字符串,包括空串;值可以是除了undefined以外的任何值。在javascript中是没有类的概念(class-free)的,但是它有一个原型链(prototype linkage)。javascript对象通过这个链来实现继承关系。

javascript中有一些,像是、、、、、等。

字面量(literal)

javascript中的每种类型的对象都可以采用字面量(literal)的方式创建。 对于Object对象,可以使用对象字面量(Object literal)来创建,例如:

stooge = {“first-name”: “Jerome”,”last-name”: “Howard”};

当然,也可以用new Object()或Object.create()的方式来创建对象。 对于Function、Array对象都有其相应的字面量形式,后面会讲到,这里不再赘述。

原型链(prototype linkage)

javascript中的每个对象都隐式含有一个[[prototype]]属性,这是ECMAScript中的记法,目前各大浏览器厂商在实现自己的javascript解释器时,采用的记法是__proto__,也就是说每个对象都隐式包含一个__proto__属性。举个例子:

var foo = {x: 10,y: 20};

foo这个对象在内存中的存储结构大致是这样的:

当有多个对象时,通过__proto__属性就能够形成一条原型链。看下面的例子:

var a = {x: 10,calculate: .x + this.y + z;}};var b = {y: 20,__proto__: a};var c = {y: 30,__proto__: a};// call the inherited methodb.calculate(30); // 60c.calculate(40); // 80

上面的代码在声明对象b、c时,指明了它们的原型为对象a(a的原型默认指向Object.prototye,Object.prototype这个对象的原型指向null),这几个对象在内存中的结构大致是这样的:

这里需要说明一点,我们如果想在声明对象时指定它的原型,一般采用方法,这样效率更高。 除了我们这里说的__proto__属性,相信大家平常更常见的是prototype属性。比如,Date对象中没有加几天的函数,那么我们可以这么做:

.setDate(this.getDate() + n);}

那么以后所有的Date对象都拥有addDays方法了(后面讲解继承是会解释为什么)。那么__proto__属性与prototype属性有什么区别呢?

javascript的每个对象都有__proto__属性,但是只有函数对象有prototype属性。

那么在函数对象中, 这两个属性的有什么区别呢? 1. __proto__表示该函数对象的原型 2. prototype表示使用new来执行该函数时(这种函数一般成为构造函数,后面会讲解),新创建的对象的原型。例如: var d = new Date(); d.proto === Date.prototype; //这里为true

看到这里,希望大家能够理解这两个属性的区别了。 在javascript,原型和函数是最重要的两个概念,上面说完了原型,下面说说函数对象。

函数对象Function

首先,函数在javascript中无非也是个对象,可以作为value赋值给某个变量,唯一不同的是函数能够被执行。 使用对象字面量方式创建的对象的__proto__属性指向Object.prototype(Object.prototype的__proto__属性指向null);使用函数字面量创建的对象的__proto__属性指向Function.prototype(Function.prototype对象的__proto__属性指向Object.prototype)。 函数对象除了__proto__这个隐式属性外,还有两个隐式的属性: 1. 函数的上下文(function’s context) 2. 实现函数的代码(the code that implements the function’s behavior)

和对象字面量一样,我们可以使用函数字面量(function literal)来创建函数。类似于下面的方式:

{return a + b;};爱情从希望开始,也由绝望结束。死心了,

javascript中的面向对象(object

相关文章:

你感兴趣的文章:

标签云: