1.1 富有表现的JavaScript
//几种不同的写法
//方法一
var Anim = function(){};
Anim.prototype.start = function(){ alert("start");}
Anim.prototype.stop = function(){}
var myAnim = new Anim();
myAnim.start();
//方法二
/*把类封装一下*/
var Anim = function(){};
Anim.prototype = {
start : function(){
alert("start");
},
stop : function(){
}
}
var myAnim = new Anim();
myAnim.start();
Function.prototype.method = function(name,fn){
this.prototype[name] = fn;
return this;
}
var Anim = function(){}
Anim.method("start",function(){
alert("start");
})
var a = new Anim();
a.start()
1.2 弱类型语言
定义变量时不必声明其类型。但这并不意味着变量没有类型。
一个变量可以属于几种类型之一,这取决于其包含的数据。JavaScript中有3种原始类型:布尔型、数值型、字符串型。
对象类型和包含可执行代码的函数类型,前者是一种复合数据类型(数组是一种特殊的对象,它包含着一批值的有序集合。)。
最后还有空类型(null)和未定义类型(undefined)这两种数据类型。原始数据类型按值传送,而其他数据类型则按引用传送。
JavaScript中的变量可以根据所赋的值改变类型。原始类型之间也可以进行类型转换。toString方法可以把数值或布尔值转变成为字符串。parseFloat和parseInt函数可以把字符串转变成数值。
1.3 函数是一等对象
在Javascript中,函数是一等对象。它们可以存储在变量中,可以作为参数传给其它函数。
可以作为返回值从其它函数里面传出,还可以在运行时构造。
可以用
function
(){}这样的语法创建匿名函数。它们没有函数名,但可以被赋给变量。
(function(){
var foo = 10;
var bao = 2;
alert(foo * bar);
})();
函数定义后即立即执行,甚至不用赋给一个变量。
另一种方式:
(function(foo,bar){
alert(foo * bar );
})(10 , 2 );
返回值可以给一个变量
var a = (function(foo,bar){
return foo * bar ;
})(10 , 2 );
//a = 20
匿名函数可以用来创建闭包。闭包是一个受到保护的变量空间,由内部函数生成。
JS有函数级的作用域,意味着函数内部创建的变量不能函数外部访问。
函数运行在定义它的作用域中,而不是在调用它的作用域中。
通过把变量包裹在匿名函数中而对其加以保护,可以这样创建类的私用变量:
var a;
(function(){
var foo = 10;
var bar = 2;
a = function(){
return foo * bar ;
}
})( );
a();
变量foo和bar定义在匿名函数中。因为函数 a定义在这个闭包中,所以它能访问这两个变量,即使是在闭包执行结束后。
在JavaScript中,一切都是对象(除了三种原始数据类型)。即便是这些类型,在必要的时候也会被自动包装为对象。而且所有的对象都是易变的, 这意味着你能使用一些在大多数别的语言中不允许的技能,例如为函数添加属性:
function displayError(msg){
displayError.numTimesExecuted ++;
alert(msg);
}
displayError.numTimesExecuted = 0;
也可以对先前定义的类和实例化的对象进行修改
/*Class Person*/
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype = {
getName : function(){
return this.name;
},
getAge : function(){
return this.age;
}
}
/*Instantiate the Class */
var bill = new Person("Bill", 28 );
var oscar = new Person("Oscar",26);
/* Modify the class*/
Person.prototype.getGreeting = function (){
return 'Hi' + this.getName() + '!'
}
/*Modify the Oscar*/
oscar.displayGreeting = function(){
alert(this.getGreeting());
}
类的getGreeting方法是在已经创建了类的两个实例之后才添加的,但这实例oscar仍然能获得这个方法,原因在于prototype对象的工作机制。对象oscar有displayGreeting 方法,而别的实例没有。
与对象的易变性相关的还有内省(introspection)的概念。你可以在运行时检查对象所具有的属性和方法,还可以使用这种信息动态实例类和执行其方法(这种技术称为反射(reflection)),甚至不需要在开发时知道它们的名称。
小结:
JavaScript的丰富表现力是其力量之源。即使这种语言缺少一些有用的内置特性,拜其灵活性所赐,你也能自己加入这些特性。
JavaScript是弱类型语言。程序员在定义变量时并不指定其类型。函数是一等对象,并可以动态创建,因此你可以创建闭包。所有对象和类都是易变的,可以在运行时修改。可供使用的继承有两种,即原型继承和类式继承。