JavaScript中的引用类型
引用类型通常叫做类(class),也就是遇到引用值或者处理的对象。但是从严格意义上讲JavaScript并不是面向对象的,而是基于对象(object)的。之所以说是基于面向对象的原因是JavaScript中并没有类似Java中的多态,抽象,重载等面向对象语言中的概念。但是JavaScript中定义了"对象定义",在逻辑上等价于其他面向对象语言中的"类"的概念。 例如我们可以使用下面的代码创建Object对象的一个实例:
var obj = new Object() ;
JavaScript中的对象
在JavaScript中的Object对象类似于Java中的java.lang.Object对象,所有的对象都是由这个对象继承而来,也即是说Object中的所有属性和方法都会出现在其他对象中。
1 Object 对象的属性和方法
- constructor : 对创建对象的函数的引用
- Prototype : 对该对象的对象原型的引用。对于所有的对象,它默认返回 Object 对象的一个实例。
- ToString() : 返回对象的原始字符串表示
- ValueOf() : 返回最适合该对象的原始值。对于许多对象,该方法返回的值都与 {{{ToString?() 的返回值相同
- javascript中定义属性和方法 在javascript中定义属性和其他语言类似:如下面的例子:
function person(name){
this.setName= function(newName){name = newName};
this.getName= function(){
return name;
}
}
var p = new person("Lily");
p.setName("Lucy");
p.getName();
注: 除了上面的定义方式之外,在js中有一种比较重要的定义对象属性方法的常见的写法就是使用JSON对象。定义一个JSON对象,同时定义它的一些属性和方法。
2 JavaScript中一切都是对象
当我们了解了Object类的时候就可以理解为什么JavaScript中一切都是对象了。我们来看下面的代码
<script type="text/javascript">
function car(){}
var c = new car() ;
/*证明c就是Object*/
alert(c instanceof car) ;
alert(car instanceof Function) ;
alert(Function instanceof Object) ;
/*证明一切都是Object*/
alert(c instanceof Object) ;
alert(car instanceof Object) ;
alert(Function instanceof Object) ;
</script>
上面alert中的内容都是true,那么也就是我们声明出来的c就是一个Object,并且所有的一切都是Object。但是这里就又存在了一个疑问:JavaScript不是基于对象的么?从上面的例子可以发现类似java中的继承的概念:c是Object的子类。那这又是怎么回事呢?
3 JavaScript中内置对象(了解即可,这里就不举例说明了)
- Global对象:也即window对象,它没有construct属性,所以不能用new进行构造,没有call属性,所以也无法像函数一样进行调用
- Object对象:它是所有对象的基础,任何其它对象都是从object对象原型扩展而来。如果Object对象使用原型扩展了其它属性,那么所有对象将都具有此扩展属性
- Function对象:使用function可以定义一个函数,在系统内部进行调用
- Error对象:可以在发生错误的时候作为参数传递给catch子句,也可以使用new关键字构造自定义的error对象
继承机制的实现
现在我们来说明上面提出的疑问:JavaScript是基于面向对象,但是怎么存在继承呢?首先我们知道子类将继承所有父类的公共的属性和方法,包括构造和方法的实现。同时子类还可以添加父类中不存在的新的属性和方法,也可以覆盖父类中的属性和方法。
在Java中我们可以使用extends轻松的实现继承,JavaScript并没有提供。但是我们可以模拟继承,而且在JavaScript中的继承并非只有一种形式。
1 call()方法
基本用法
<script type="text/javascript">
function sayColor(sPrefix,sSuffix) {
alert(sPrefix + this.color + sSuffix); // 输出The color is blue,a very nice color.
};
var obj = new Object();
obj.color = "blue";
sayColor.call(obj, "The color is ", ",a very nice color.");
</script>
说明:
- 1. call()方法中的第一个参数用作this对象,其他的参数都是直接传递给函数自身。(this并不一定是执行该函数时的真正的this值,如果this的值是null或者是undefined,那么this就会自动指向全局变量,如果是浏览器,那么当然是window了。此时this会指向原始值的自动包装对象)
- 2. sayColor在对象之外定义,显然它不属于任何对象,当时也可以使用关键字this。因为一个function也是一个对象。(javascript中函数即为对象)
- 3. call()方法中的第一个参数是obj,也就是在sayColor中的this是obj。所以sayColor中的this.color就是blue。
- 4. 另外的两个参数就是sayColor中的sPrefix和sSuffix。
使用继承
0. <script type="text/javascript">
1. function ClassA(sColor) {
2. this.color = sColor;
3. console.log(this) ;
4. this.sayColor = function () {
5. alert(this.color);
6. };
7. }
8. function ClassB(sColor, sName) {
9. ClassA.call(this, sColor);
10. this.name = sName;
11. this.sayName = function () {
alert(this.name);
12. };
13. }
14. var objA = new ClassA("blue");
15. var objB = new ClassB("red", "John");
16. objA.sayColor(); //输出 "blue"
17. objB.sayColor(); //输出 "red"
18. objB.sayName(); //输出 "John"
19. </script>
说明:
- 1. objB本身并没有sayColor函数,这是因为通过call方式继承而来。在其中第9行的this是ClassB,第3行的this也是ClassB,所以第2行的this.colo就是ClassB中的 color,即red。这一特点和继承相符合:子类继承父类的方法,并拥有父类的所有属性。
- 2.ClassB同时可以拥有新的属性和方法。在第10,11行。
- 3.call相当于连接另一个对象的构造方法,类似于java中的super关键字的含义,在这里,相当于是在ClassB作用域下调用ClassA函数,很好的体现了继承。(call还能实现多继承)
2 prototype
在JavaScript中的继承是基于原型链的。看下面的例子
<script type="text/javascript"> 1 function ClassA() { 2 } 3 4 ClassA.prototype.color = "blue"; 5 ClassA.prototype.sayColor = function () { 6 alert(this.color); 7 }; 8 9 function ClassB() { 10 } 11 12 ClassB.prototype = new ClassA(); 13 ClassB.prototype.name = ""; 14 ClassB.prototype.sayName = function () { 15 alert(this.name); 16 }; 17 var objA = new ClassA(); 18 var objB = new ClassB(); 19 objA.color = "blue"; 20 objB.color = "red"; 21 objB.name = "John"; 22 objA.sayColor(); 23 objB.sayColor(); 24 objB.sayName(); </script>
说明:
- 1.和上面的例子不同的是,第一行ClassA的构造函数中没有参数,这个是使用原型链的标准。此外在函数体中没有定义属性和方法,都是在CalssA的构造函数之外通过ClassA.prototye.Xxx的方式定义的。
- 2. 第12行就是继承的关键,我们需要使用ClassA中的全部属性和方法。当然我们可以通过ClassB.prototye.Xxx的方式逐个定义,使其相等。但是我们可以使用ClassB.prototype = new Xxx()的方式,将ClassA的实例赋予给ClassB,这样就更好了。第20和23也证明了ClassB继承了ClassA的属性和方法。
- 3.我们从第一行中可以发现ClassA是一个Function,但是同时Function也是一个Object,而之前讲过,Object对象的属性:Prototype默认返回Object对象的一个实例。也就是说prototype实际上是Object的属性。
- 4.从4,5行可以看出我们既可以使用prototype定义属性也可以定义方法,而且完全取决于你自己。因为prototype返回一个Object实例,自然就可以添加任意你喜欢的属性和方法了。
- 5.类的实例可以通过"."的方式访问prototype定义过的属性方法,第19 - 24行
javaScript对象体系结构
JavaScript中的this
- this是javascript中理解类和继承的重要基础。this属性代表当前对象。如果用在全局变量中,那么它代表当前页面对象window,我们可以通过使用call和apply方法来改变this指针,(注意:this指针是在函数调用时改变的,并不是函数定义时)如下面的例子:
function hello(){
alert(this.say);
}
var say = "你好";
hello();
var test = {
say:"欢迎访问",
hello:hello
}
test.hello();
- 1.开始时执行hello方法是全局的,相当于window.hello(),输出的是"你好",在下面调用的时候this指向了当前对象test,所以输出的是"欢迎访问"。
- 2.在函数定义时,this指向的是window对象,在第一次执行的时候this指针不变,但是在第二次执行的时候this指针变成了test对象。this指针发生了变化。
- this指针可以是全局对象、当前对象或者任意对象,这个要取决于函数的调用方式:在javascript中,函数有几种不同的调用方式:作为对象方法调用、作为函数调用、作为构造函数调用、使用apply和call进行调用。以下分别是这几种调用方式下的this指针:
- 1.作为函数对象调用
由于函数也是对象,因此函数也可以作为对象的一个属性,此时函数就是该对象的方法,当使用该对象调用这个方法时,this当然指的是该对象 例子:
var hello = { say:"welcome", test:function(name){ this.say = name + " say:" + this.say; } }; hello.test("jack");
此时的this就被绑定到hello对象中
- 2.作为函数调用
在函数体内也可以直接调用,此时的this指的是全局对象window。例子:
var say = "welcome"; function hello(say){ this.say = say; }
此时的this指的是全局对象。
- 3.作为构造函数调用
Hello.js function Hello(say){ this.say = say }
this被绑定到新创建的对象上面。
- 4.使用call或者apply调用(同上面的call方法中的举例)
JavaScript匿名函数
1 定义一个函数方式
首先需要说明的是在JavaScript中定义一个函数一般存在如下三种方式:
- 1. 使用关键字function
funtion sayHello(){alert("hello"); }
这种方式定义的函数,函数声明在整个程序执行之前的预处理就完成了。只要同处于一个作用域就可以访问到。
- 2. 使用Function类
var myFunction = new Function("x","alert(x)") ;
Function类中前面的参数就是在最后一个参数中需要传递的参数,也就是最后一个参数是函数的主体。使用Function类定义的函数中的参数必须都是字符串。
- 3. 使用匿名对象
var myFunction = function(x){alert(x) ;}
这种方式定义的函数,只能按照程序流程执行到定义的那一行才可以被声明,所以只能在定义之后才可以调用。
2 变量的作用域
变量的作用域无非就是两种:全局变量和局部变量。 在JavaScript中支持在函数的内部直接访问全局变量,同时在函数的外部自然就无法访问到函数内的局部变量了。 另外需要说明的是在函数的内部声明变量时候,一定要使用var关键字,否则的话,实际上你声明了一个全局的变量!!
3 示例
<html>
<head>
<title>匿名对象</title>
</head>
<body>
<script type="text/javascript">
// 测试函数作用域
var NUM = 999 ; // 全局变量
function testNum(){
alert(NUM) ;
var count = 100 // 局部变量
TEST_NUM = 1 ; // 全局变量
}
testNum() ; // 999
alert(count) ; // error
alert(TEST_NUM) ; // 1
// 测试匿名函数
var testFunction;
testFunction(); //error
testFunction=function(){
sayHello(); //sayHello works
alert("testFunction works");
return false; // 虽然已经return,说明程序流程并没有执行,但是sayHello已经在预处理中处理了
function sayHello(){
alert("hello");
}
}
testFunction(); // 先输出hello , 再输出testFunction works , 这是因为sayHello程序的执行流程之前被调用。
</script>
</body>
</html>
4 匿名函数和this结合
<html>
<head>
<title>匿名对象</title>
</head>
<body>
<script type="text/javascript">
// 不使用this关键字
objA={
Calculate : function(num){
return num > 2 ? objA.Calculate(num-1) : num ; // 将objA替换成this即可
}
}
objB={
Calculate : objA.Calculate
}
alert(objB.Calculate(5)) ; // 2
objA = {} ; // 将objA清空
alert(objB.Calculate(5)) ; // error
</script>
</body>
</html>
说明:在上面的代码中objA中定义了一个递归,直到num的值为2。然后将objA = {}进行了清空,那么下面的输出就会出现错误了。
这个时候我们的this就可以派上用场了。将递归函数中的objA替换成this,这样的话将objA = {} 清空,但是并不会将objB进行清空。
JavaScript闭包
闭包在js中是一个难点,本人也只是懂得其中的一点基础,希望以下的介绍能够对初学者起到入门的作用
1变量的作用域
要理解闭包的概念,首先应该理解一下变量的作用域,它分为两种:全局变量和局部变量,在js中,函数内部可以直接访问函数外部的变量,例如:
var say = "hello";
function test(){
alert(say);
}
test();
当然外部不能访问内部的变量,如下的访问时错误的:
function test(){
var say = "hello";
//
}
alert(say);
注意:在函数内部定义变量的时候需要加var,否则默认的声明的是全局变量
2.从外部获取局部变量
上面说了,在一般情况下是不能访问的,但是如果改变一下思路,这个问题就会迎刃而解了,就是在函数内部定义函数:
function test1(){ var say = "hello"; function test2(){ alert(say); } return test2; } var test = test1(); test();
以上就是在函数test1的内部定义了函数test2,在test2中访问局部变量。这样就在函数外部访问到了局部变量。
3.闭包的概念
闭包,通俗的讲,其实就是能够访问其他函数内部变量的函数
4.闭包的用途
闭包主要有两大用途:一个是前面提到的可以访问函数内部的变量,二是让这些变量的值始终保存在内存中。
function test1(){
var say = 1;
add = function(){
say += 1;
}
function test2(){
alert(say);
}
return test2;
}
var result=test1();
result();
add();
result();
以上函数中,result实际上就是一个闭包函数,它一共执行了两次,这说明test1的变量say一直在内存中。并没有在调用test1以后自动清除。这里面有一个add方法,因为在定义它的时候前面没有var关键字,所以它是一个全局变量,并且它又是一个匿名函数,它实际上也是一个闭包,所以能够改变局部变量的值。
5.闭包的运行机制,你理解了吗?看下面两个例子:
var name = "Lily";
var test = {
name = "Lucy";
getName:function(){
return function(){
return this.name;
}
}
};
console.log(test.getName()());
输出 "Lily";
var name = "Lily";
var test = {
name = "Lucy";
getName:function(){
var Dthis = this;
return function(){
return Dthis.name;
}
}
};
console.log(test.getName()());
输出 "Lucy".
还有几个闭包的例子,看这里http://www.cnblogs.com/zhangle/archive/2010/07/02/1770206.html
JavaScript脚本化Java
1什么是脚本化
脚本化可以使宿主程序具有脚本所描述的能力,比如JavaScript技术,JavaScript可以让原本是静态的HTML代码的页面变活、具有局部刷新等更高级的功能。应用程序一般是以二进制的形式发布的,用户很难根据自己的需求对其进行定制。脚本化是通过用户自己设计脚本,然后将其注入到应用中,使得应用的行为得到改变。
2看这里简单的例子
http://han2000lei.iteye.com/blog/353253