面向对象的JavaScript——类
来源:互联网 发布:桂林大家庭有淘宝么 编辑:程序博客网 时间:2024/05/17 07:17
http://my.oschina.net/warmcafe/blog/79733
在java里,我们定义类的时候用的是class关键字,但是JavaScript中class是保留字,另有用途,所以我们要采用其他的方法来定义JavaScript中的类。
定义类
利用JavaScript中的function关键字,类名首字母一般采用大写,如:
1
function
Person(id,name,age){
2
this
.id = id;
3
this
.name = name;
4
this
.age = age;
5
}
1
var
per =
new
Person(
"001"
,
"Xiao Wei"
,
"12"
);
上面那个构造函数里的this指针(严格意义上this不是指针,只是我们把它想象为指针会容易理解一些)指向的变量即是Person类的数据成员(或者叫属性),访问权限是public。java的类中,除了有属性之外,还有方法(也就是c里的函数)。下面我们为JavaScript类添加函数。
1
function
Person(id,name,age){
2
this
.id = id;
3
this
.name = name;
4
this
.age = age;
5
this
.getInformation =
function
(){
6
return
"编号:"
+
this
.id+
";姓名:"
+
this
.name+
";年龄:"
+
this
.age;
7
};
8
}
1
function
Person(id,name,age){
2
this
.id = id;
3
this
.name = name;
4
this
.age = age;
5
}
6
Person.prototype.getInformation =
function
(){
7
return
"编号:"
+
this
.id+
";姓名:"
+
this
.name+
";年龄:"
+
this
.age;
8
};
类已经通过function关键字实现了,这是一种实现方式,这种方式实现起来简单、通俗易懂,其实还有一种实现方式,实现起来非常优雅,我们看下面代码:
01
var
Class={
02
create:
function
(){
03
return
function
(){
04
this
.inital.apply(
this
,arguments);
05
};
06
}
07
};
08
/*定义Person类*/
09
var
Person=Class.create();
10
Person.prototype={
11
inital:
function
(id,name,age){
12
this
.id = id;
13
this
.name = name;
14
this
.age = age;
15
},
16
getInformation:
function
(){
17
return
"编号:"
+
this
.id+
";姓名:"
+
this
.name+
";年龄:"
+
this
.age;
18
}
19
};
关键代码在于:this.inital.apply(this,arguments);这样一行,Class本身是一个对象,有一个方法叫做create,此方法返回一个函数指针,其中函数体内执行this.inital.apply(this,arguments);this指向是的是当前对象,在这里就是Person,apply方法是更改initial方法的作用域,arguments是参数列表。关于apply更详细的解释可以参见我之前的学习笔记《JavaScript中call()与apply()有什么区别?》。
this
关于this的详细用法我已在读书笔记《JavaScript中的this如何使用》中有介绍。这里再啰嗦几小句。
在JavaScript中,并没有严格的面向对象概念,自然也没有类的构造函数这样的概念。var o=new Obj();这样的语法,看起来似乎和Java/C++相当类似,但是它背后的执行过程是不同的。首先,解释器会new一个空的Object对象。然后将这个空的Object,作为隐藏的参数传递给function Obj()。在Obj函数中访问到的this,其实就是这个传入的空的Object 对象。这就是所谓:“this关键字关联于执行时的作用域”的含义。
如果你想把一个函数作为“构造函数”,那么就不要在函数的最后加上return语句。因为如果没有return语句,new算符返回的就是那个被操作过以后的this。一旦你通过return返回了别的东西,这个this就被废弃掉了。
匿名类
1
var
class1 = {p1:value1,p2:value2};
这个也可以写成
1
var
class1 = {};
2
class1.p1 = value1;
3
class1.p2 = value2;
首先所有的匿名类都是继承于Object核心对象的,var class1={} 意味着实例化了一个Object对象,它拥有Object对象的原生属性和原生方法。但是不能为匿名类添加原生方法,例如这样写是错误的:
1
class1.prototype.func1 =
function
(){};
你也不能尝试用new() 方法来构造一个新的与class1有相同的属性的新对象,因为它已经实例化了。以下写法也是错的:
1
var
classB =
new
classA();
这是无法构造的,
准确的说,匿名类实际上是继承于Object的某一个实例,相当于C#中的静态类。你可以为它添加方法和属性。例如:
1
class1.func1 =
function
(){};
调用的时候就这样:
1
class1.func1();
//酷似C#中的静态类
但是你可以为Object添加原生函数,这样你的匿名类(实际上是所有的类)都有这个方法。例如:
1
var
class1 = {};
2
class1.p1 = value1;
3
class1.p2 = value2;
4
Object.prototype.func1 =
function
(){ alert(
"1"
) };
5
class1.func1();
是没有问题的,但是这样一来,所有的实例化对象都有了func1()方法。实际应用中应该避免给Object类添加原生方法。
匿名函数
先说说关于Javascript的函数:可以这样说,JavaScript中一切皆是对象,function自然不例外,function可以作为函数,类,也可以当成一个被函数对象返回。
看下面的例子:
01
function
a(){
02
alert(
"Hello Febird!"
);
03
this
.aa =
"aa"
;
04
this
.show =
function
(){
05
alert(
this
.aa);
06
};
07
this
.sayHello =
function
(){
08
return
function
(){alert(
"hello"
);};
09
};
10
}
11
12
var
aaa =
new
a();
13
aaa.show();
14
aaa.sayHello();
其中最外面的一个function是定义了一个类 a ,它有属性aa,方法show(),sayHello();这两个都是匿名函数,而sayHello中的function便是函数作为一个返回值的例子。
实际上可以这样想,匿名函数就是一块没有命名的代码块,当把它赋值给别的变量的时候,那么那个变量就是一个函数,准确的说那是一个函数指针。
在JavaSript中,匿名函数是很有特点的东西了,也是非常有用,也是有些难以理解的。
比如在写Ajax引用的时候,如果不依靠别的JSF,自己写一个通用的Ajax话,一般这样写:
01
var
xhr =
new
XMLHttpRequest();
//已经封装,可以适应不同的浏览器;
02
function
DoAjax(){
03
xhr.onreadystatechange=processFunction;
04
xhr.open(
"GET"
,url,
true
);
05
xhr.send(
null
);
06
}
07
function
processFunction(){
08
//do something with XMLHttpRequest;
09
if
(xhr.readState!=4||xhr.status!=200)
return
false
;
10
alert(xhr.responseText);
11
}
在一般的Ajax引用中,也许只要一个XMLHttpRequest对象,而且onreadystatechange的处理函数必须没有参数,有参数就出错,所以,一般经常会写一个全局变量XMLHttpRequest,再在processFunction中用到这个全局变量,但是如果我要建立几个XMLHttpRequest的并发连接怎么办呢?这个就不能用全局变量了,但是处理函数又不能有参数,怎么搞,可以这样:
01
function
DoAjax(){
02
var
xhr =
new
XMLHttpRequest();
03
xhr.onreadystatechange = processFunction(xhr);
04
xhr.open(
"GET"
,url,
true
);
05
xhr.send(
null
);
06
}
07
function
processFunction(_xhr){
08
return
function
(){
09
//do something with XMLHttpRequest;
10
if
(_xhr.readState!=4||_xhr.status!=200)
return
false
;
11
alert(_xhr.responseText);
12
};
13
}
怎么理解?虽然processFunction函数有参数,但是它返回的函数没有参数!而这两个函数之间是怎么进行的值传递呢?
这里不妨引用一句话:
“为了函数能够正确的执行,需要被函数使用的,词法作用域中的,非全局数据,存在于函数的闭包之中。”
可以这样理解:
当我们把processFunction()返回的函数,在processFunction之外使用的时候,依然要记得自己被定义时的上级作用域中的各种变量的值。这些需要被记住的值,就是“闭包”。
原生对象
原生,即prototype,他提供我们了扩展、改造原有对象的方法。例如我们可以为已知对象,包括JavaScript的核心对象Array,Number,Math,Object,Boolean等和自定义类添加方法或者属性。
例如:
1
Number.prototype.toHexString =
function
() {
2
return
this
.toString(16);
3
};
4
var
num = 10;
5
alert(num.toHexString());
输出A;
你可以为Object对象添加方法,这样,以后任意一个对象都有这个方法,因为其它对象都是从Object继承而来的。
你也可以再造现有函数
1
Function.prototype.toString =
function
() {
2
return
“Function Locked”;
3
};
参考资料:
1. javascript实现类、继承、多态(原创)
2. JavaScript面向对象---匿名函数和匿名类,以及原生类
- 面向对象的JavaScript——类
- JavaScript面向对象编程之——类的概念
- 精通JavaScript —— 面向对象的JavaScript
- Javascript面向对象—继承
- 《JavaScript》——面向对象之对象的创建
- 《JavaScript》——面向对象之对象的创建
- JavaScript面向对象程序设计—创建对象的模式
- JavaScript面向对象程序设计——对象
- 面向对象的javascript
- javascript的面向对象
- JavaScript的面向对象
- 面向对象的JavaScript
- Javascript的面向对象
- 面向对象的JavaScript
- 面向对象的JavaScript
- 面向对象的JavaScript
- 面向对象的Javascript
- 面向对象的JavaScript
- c++ template (总结)
- Java的volatile
- html table中嵌入checkbox实现全选
- Javascript实用代码(1)
- javascript实用代码(2)
- 面向对象的JavaScript——类
- Javascript实用代码(3)
- 关于屏幕适配的学习(support-screens)
- linux 解压命令大全
- Windows7下彻底卸载MySQL5.5.21
- 如何在Eclipse 4.2中安装Baidu BDT?
- windows 下FFMPEG的编译方法 附2012-9-19发布的FFMPEG编译好的SDK下载
- android 手机PC客户端
- 我的关联博客