内嵌函数我们还能够在一个函数中嵌套一个函数。下例,我有一个叫做getHalfOf的函数,而在它里面,我有另一个叫做calculate的函数。
Example 7 
Language:javascript, parsed in: 0.015 seconds, using GeSHi 1.0.7.12function getHalfOf(num1, num2, num3)     

  function calculate(number)
  {
    return number/2;
  }  var result="";
  result+=calculate(num1)+" ";
  result+=calculate(num2)+" ";
  result+=calculate(num3);
  return result;
}         
var resultString=getHalfOf(10,20,30);
alert(resultString);         // 输出 "5 10 15"运行示例
你只能在内部调用嵌套的函数。就是说,你不能这么调用:getHalfOf.calculate(10),因为calculate只有当外部函数(getHalfOf())在运行的时候才会存在。这和我们前面的讨论一致(函数会被编译,但只有当你去调用它的时候才会执行)。
调用哪个函数?你也许正在想命名冲突的问题。比如,下面哪一个叫做calculate的函数会被调用?
Example 8 
Language:javascript, parsed in: 0.017 seconds, using GeSHi 1.0.7.12function calculate(number)
{
  return number/3;
}function getHalfOf(num1, num2, num3)     

  function calculate(number)
  {
    return number/2;
  }  var result="";
  result+=calculate(num1)+" ";
  result+=calculate(num2)+" ";
  result+=calculate(num3);
  return result;
}         
var resultString=getHalfOf(10,20,30);
alert(resultString);         // 输出 "5 10 15"运行示例
在这个例子中,编译器会首先搜索局部内存地址,所以它会使用内嵌的calculate函数。如果我们删除了这个内嵌(局部)的calculate函数,这个代码会使用全局的calculate函数。
函数:数据类型及构造函数让我们来看看函数的另一个特殊功能--这让它和其它对象类型截然不同。一个函数能够用来作为一个数据类型的蓝图。这个特性通常被用在面向对象编程中来模拟用户自定义数据类型(user defined data type)。使用用户自定义数据类型创建的对象通常被成为用户自定义对象(user defined object)。
数据类型在定义了一个函数之后,我们也同时创建了一个新的数据类型。这个数据类型能够用来创建一个新对象。下例,我创建了一个叫做Ball的新数据类型。
Example DT1 
Language:javascript, parsed in: 0.004 seconds, using GeSHi 1.0.7.12function Ball()
{
}
var ball0=new Ball(); // ball0 现在指向一个新对象alert(ball0);         // 输出 "Object",因为 ball0 现在是一个对象运行示例
这样看来,ball0=new Ball()作了什么?new关键字创建了一个类型是Object的新对象(叫做ball0)。然后它会执行Ball(),并将这个引用传给ball0(用于调用对象)。下面,你会看到这条消息:“creating new Ball”,如果Ball()实际上被运行的话。
Example DT2 
Language:javascript, parsed in: 0.009 seconds, using GeSHi 1.0.7.12function Ball(message)
{
  alert(message);
}
var ball0=new Ball("creating new Ball");  // 创建对象并输出消息
ball0.name="ball-0";                      // ball0现在有一个属性:name
alert(ball0.name);                        // 输出 "ball-0"运行示例
我们可以把上面这段代码的高亮的一行看做是底下的代码高亮处的一个简写:
Language:javascript, parsed in: 0.010 seconds, using GeSHi 1.0.7.12function Ball(message)
{
  alert(message);
}
var ball0=new Object();
ball0.construct=Ball;
ball0.construct("creating new ball");  // 执行 ball0.Ball("creating..");
ball0.name="ball-0";                      
alert(ball0.name);         运行示例
这行代码ball0.construct=Ball和Example 4中的ptr=myFunction语法一致。
如果你还是不明白这行的含义那就回过头再复习一下Example 4。注意:你也许考虑直接运行ball0.Ball("..."),但是它不会起作用的,因为ball0并没有一个叫做Ball("...")的属性,并且它也不知道你究竟想作些什么。
添加属性当我们象上面那样使用关键字new创建一个对象的时候,一个新的Object被创建了。我们可以在创建之后给这个对象添加属性(就好像我在上面那样添加属性name。而接下来的问题就是如果我们创建了这个对象的另外一个实例,我们得象下面那样再次给这个新对象添加这个属性。)
Example DT3 (creates 3 ball objects) 
Language:javascript, parsed in: 0.013 seconds, using GeSHi 1.0.7.12function Ball()
{
}
var ball0=new Ball(); // ball0 现在指向了类型Ball的一个新实例
ball0.name="ball-0";  // ball0 现在有一个属性"name"var ball1=new Ball();
ball1.name="ball-1";var ball2=new Ball();alert(ball0.name);    // 输出 "ball-0"
alert(ball1.name);    // 输出 "ball-1"
alert(ball2.name);    // 哦,我忘记给ball2添加“name”了!我忘记给ball2添加属性name了,如果在正式的程序中这也许会引发问题。有什么好办法可以自动增加属性呢?嗯,有一个:使用this关键字。this这个词在function中有特别的意义。它指向了调用函数的那个对象。让我们看看下面的另一个示例,这时候我们在构造函数中添加上这些属性:
Example DT4 
Language:javascript, parsed in: 0.010 seconds, using GeSHi 1.0.7.12function Ball(message, specifiedName)
{
  alert(message);
  this.name=specifiedName;                
}
var ball0=new Ball("creating new Ball", "Soccer Ball");  
alert(ball0.name);                   // prints "Soccer Ball"运行示例
请记住:是new关键字最终使得构造函数被执行。在这个例子中,它将会运行Ball("creating new Ball", "Soccer Ball");而关键字this将指向ball0。
因此,这行:this.name=specifiedName变成了ball0.name="Soccer Ball"。
它主要是说:给ball0添加属性name,属性值是Soccer Ball。 
我们现在只是添加了一个name属性给ball0,看起来和上一个例子中所做的很象,但却是一个更好更具扩展性的方法。现在,我们可以随心所欲的创建许多带有属性的ball而无需我们手动添加它们。而且,人们也希望创建的Ball对象能够清晰的看懂它的构造函数并且能够轻松找出Ball的所有属性。让我们添加更多属性到Ball里。
Example DT5
Language:javascript, parsed in: 0.025 seconds, using GeSHi 1.0.7.12function Ball(color, specifiedName, owner, weight)
{
  this.name=specifiedName;                
  this.color=color;
  this.owner=owner;
  this.weight=weight;
}
var ball0=new Ball("black/white", "Soccer Ball", "John", 20);  
var ball1=new Ball("gray", "Bowling Ball", "John", 30);  
var ball2=new Ball("yellow", "Golf Ball", "John", 55);  
var balloon=new Ball("red", "Balloon", "Pete", 10);  alert(ball0.name);                        // 输出 "Soccer Ball"
alert(balloon.name);                      // 输出 "Balloon"
alert(ball2.weight);                      // 输出 "55"运行示例
嘿!使用面向对象术语,你能够说Ball是一个拥有如下属性的对象类型:name, color, owner, weight。 
将对象赋给属性我们并没被限制只能添加形如字符串或者数字之类的简单数据类型作为属性。我们也能够将对象赋给属性。下面,supervisor是Employee的一个属性.
Example DT6 
Language:javascript, parsed in: 0.022 seconds, using GeSHi 1.0.7.12function Employee(name, salary, mySupervisor)
{
  this.name=name;                
  this.salary=salary;
  this.supervisor=mySupervisor;
}
var boss=new Employee("John", 200);var manager=new Employee("Joan", 50, boss);  
var teamLeader=new Employee("Rose", 50, boss);  alert(manager.supervisor.name+" is the supervisor of "+manager.name);
alert(manager.name+"\'s supervisor is "+manager.supervisor.name);  会输出什么呢?运行示例
就像你在上面这个例子中看到的那样,manager和teamLeader都有一个supervisor属性,而这个属性是类型Employee的一个对象。
将函数作为属性任何类型的对象都可以作为一个属性,回忆一下前面的Example 4(不是Example DT4),函数也是一个对象。所以你可以让一个函数作为一个对象的一个属性。下面,我将添加两个函数getSalary和addSalary。