请选择 进入手机版 | 继续访问电脑版
收藏本站腾讯微博新浪微博
点点网模板设计大赛 phpchina

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 用悬赏 三天解决问题 解决访问速度慢 论坛支持农历生日 - 给官方提建议

论坛活动及任务 归纳网站最新活动 地图任务 邮件更新任务:保护帐号安全

积分换实物,来参加蓝色理想积分兑换吧! 联系招聘客服 蓝色理想帮你找工作! 万元奖励等你拿——点点网模板设计大赛

查看: 27482|回复: 32

[翻]javascript的函数 [复制链接]

Sheneyan 楼主

子虚乌有

荣誉管理 手机认证 

帖子
8391
体力
26707
威望
187
居住地
江苏省 苏州市
发表于 2006-7-26 01:39:26 |显示全部楼层
javascript的函数

作者:F. Permadi
译者:Sheneyan(子乌)
时间:2006.01.03
英文原文: INTRODUCTION TO JavaScript Functions
中文译文(包括示例):javascript的函数
子乌注:一篇相当不错的function入门文章,个人感觉相当经典。

词语翻译列表
function:函数(Function未翻译)
declare:定义
assign:指派,分配
functionbody:函数体(就是函数的内容)
object:对象
property:属性
unnamed:匿名(在这里没翻译成未命名)
object oriented programming:面向对象编程
class:类(比如后面的class data type我翻译成类数据类型)
pointer:指针
reassign:重新分配
nest:嵌套
feature:功能,特性
local/global:局部/全局
blueprint:蓝图(?)
user defined:用户自定义
instance:实例
prototype:原型(除了标题都不翻译)
internal:内部
constructor:构造器
duplication:

函数:定义

  有以下这些方法可以定义一个函数。所有这些都是有效的,但是它们在后台如何实现的则有一些差别。

  一般大家都用这个写法来定义一个函数:

  1. functionName([parameters]){functionBody};
复制代码


Example D1:
  1. function add(a, b)
  2. {                     
  3.   return a+b;
  4. }                     
  5. alert(add(1,2));        // 结果 3
复制代码


  当我们这么定义函数的时候,函数内容会被编译(但不会立即执行,除非我们去调用它)。而且,也许你不知道,当这个函数创建的时候有一个同名的对象也被创建。就我们的例子来说,我们现在有一个对象叫做“add”(要更深入了解,看底下函数:对象节。)
  我们也可以通过指派一个变量名给匿名函数的方式来定义它。

Example D2
  1. var add=function(a, b)
  2. {                     
  3.   return a+b;
  4. }                     
  5. alert(add(1,2));        // 结果 3
复制代码


  这个代码和前一个例子做了同样的事情。也许语法看起来比较奇怪,但它应该更能让你感觉到函数是一个对象,而且我们只是为这个对指派了一个名称。可以把它看做和 var myVar=[1,2,3]一样的语句。以这种方式声明的函数内容也一样会被编译。
  当我们指派一个这样的函数的时候,我们并不一定要求必须是匿名函数。在这里,我作了和ExampleD2一样的事情,但我加了函数名“theAdd”,而且我可以通过调用函数名或者是那个变量来引用函数。

Example D2A
  1. var add=function theAdd(a, b)
  2. {                     
  3.   return a+b;
  4. }                     
  5. alert(add(1,2));           // 结果 3
  6. alert(theAdd(1,2));        // 结果也是 3
复制代码


  使用这种方式来定义函数在面向对象编程中是很有用的,因为我们能像底下这样使一个函数成为一个对象属性

  1. var myObject=new Object();
  2. myObject.add=function(a,b){return a+b};  
  3. // myObject 现在有一个叫做“add”的属性(或方法)
  4. // 而且我能够象下面这样使用它
  5. myObject.add(1, 2);
复制代码


  我们也能够通过使用运算符new来定义一个函数。这是一个最少见的定义函数的方式并且并不推荐使用这种方式除非有特殊的理由(可能的理由见下)。语法如下:
  1. varName=new Function([param1Name, param2Name,...paramNName], functionBody);
复制代码


Example D3:
  1. var add=new Function("a", "b", "return a+b;");
  2. alert(add(3,4));        // 结果 7
复制代码


  我在这里有两个参数叫做ab,而函数体返回ab的和。请注意new Function(...)使用了大写F,而不是小写f。 这就告诉javascript,我们将要创建一个类型是Function的对象。 还要注意到,参数名和函数体都是作为字符串而被传递。我们可以随心所欲的增加参数,javascript知道函数体会是右括号前的最后一个字符串(如果没有参数,你能够只写函数体)。你没必要将所有东西都写在一行里(使用\或者使用字符串连接符+来分隔长代码)。\标记告诉JavaScript在下一行查找字符串的其余部分。例子如下:

Example D4
  1. // 注意 "+"
  2. // 和 "\"的不同用法
  3. var add=new Function("a", "b",
  4.   "alert" +                     
  5.   "('adding '+a+' and ' +b);\
  6.    return a+b;");
  7. alert(add(3,4));        // 结果 7
复制代码


  采用这种方式定义函数会导致函数并没被编译,而且它有可能会比用其它方式定义的函数要慢。至于为什么,看一下这个代码:

Example D5
  1. function createMyFunction(myOperator)
  2. {
  3.   return new Function("a", "b", "return a" + myOperator + "b;");
  4. }

  5. var add=createMyFunction("+");                // 创建函数 "add"
  6. var subtract=createMyFunction("-");           // 创建函数 "subtract"
  7. var multiply=createMyFunction("*");           // 创建函数 "multiply"
  8. // test the functions
  9. alert("加的结果="+add(10,2));                  // 结果是 12
  10. alert("减的结果="+subtract(10,2));             // 结果是 8
  11. alert("乘的结果="+multiply(10,2));             // 结果是 20
  12. alert(add);
复制代码


  这个有趣的例子创建了三个不同的function,通过实时传递不同的参数来创建一个新Function。因为编译器没法知道最终代码会是什么样子的,所以new Function(...)的内容不会被编译。那这有什么好处呢?嗯,举个例子,如果你需要用户能够创建他们自己的函数的时候这个功能也许很有用,比如在游戏里。我们也许需要允许用户添加“行为”给一个“player”。但是,再说一次,一般情况下,我们应该避免使用这种形式,除非有一个特殊的目的。


函数:对象
  函数是javascript中的一种特殊形式的对象。它是第一个类数据类型(class data type)。这意味着我们可以给它增加属性。这里有一些需要注意的有趣观点:

  就像刚才提及的,当我们定义一个函数时,javascript实际上在后台为你创建了一个对象。这个对象的名称就是函数名本身。这个对象的类型是function。在下面的例子,我们也许不会意识到这一点,但我们实际上已经创建了一个对象:它叫做Ball

Example 1
  1. function Ball()       // 也许看起来有点奇怪,但是这个声明
  2. {                     // 创建了一个叫做Ball的对象
  3.   i=1;
  4. }                     
  5. alert(typeof Ball);     // 结果 "function"
复制代码


  我们甚至能将这个对象的内容打印出来而且它会输出这个函数的实际代码,Example 2: 点击 alert(Ball);来看看Ball的内容。
  我们可以给Object添加属性,包括对象function。因为定义一个函数的实质是创建一个对象。我们可以“暗地里”给函数添加属性。比如,我们这里定义了函数Ball,并添加属性callsign

  1. function Ball()       // 也许看起来有点奇怪,但是这个声明
  2. {                     // 创建了一个叫做Ball的对象,而且你能够
  3. }                     // 引用它或者象下面那样给它增加属性
  4. Ball.callsign="The Ball"; // 给Ball增加属性
  5. alert(Ball.callsign); // 输出 "The Ball"
复制代码


  因为function是一个对象,我们可以为一个function分配一个指针。如下例,变量ptr指向了对象myFunction

  1. function myFunction(message)
  2. {
  3.   alert(message);
  4. }
  5. var ptr=myFunction;  // ptr指向了myFunction
  6. ptr("hello");             // 这句会执行myFunction:输出"hello"
复制代码


  我们可以运行这个函数,就好像这个函数名已经被指针名代替了一样。所以在上面,这行ptr("hello"); myFunction("hello");的意义是一样的。
  指向函数的指针在面向对象编程中相当有用。例如:当我们有多个对象指向同一个函数的时候(如下):

Example 4A
  1. function sayName(name)
  2. {
  3.   alert(name);
  4. }
  5. var object1=new Object();      // 创建三个对象
  6. var object2=new Object();
  7. var object3=new Object();
  8. object1.sayMyName=sayName;       // 将这个函数指派给所有对象
  9. object2.sayMyName=sayName;
  10. object3.sayMyName=sayName;
  11.   
  12. object1.sayMyName("object1");    // 输出 "object1"
  13. object2.sayMyName("object2");    // 输出 "object2"
  14. object3.sayMyName("object3");    // 输出 "object3"
复制代码




  因为只有指针被保存(而不是函数本身),当我们改变函数对象自身的时候,所有指向那个函数的指针都会发生变化。我们可以在底下看到:

Example 5:
  1. function myFunction()
  2. {
  3.   alert(myFunction.message);
  4. }
  5. myFunction.message="old";
  6. var ptr1=myFunction;                 // ptr1 指向 myFunction
  7. var ptr2=myFunction;                 // ptr2 也指向 myFunction

  8. ptr1();                                     // 输出 "old"
  9. ptr2();                              // 输出 "old"

  10. myFunction.message="new";

  11. ptr1();                                     // 输出 "new"
  12. ptr2();                              // 输出 "new"
复制代码


  我们可以在一个函数创建之后重新分配它,但是我们需要指向函数对象本身,而不是指向它的指针。在下例中,我将改变myfunction()的内容。

Example 6:
  1. function myFunction()
  2. {
  3.   alert("Old");
  4. }
  5. myFunction(); // 输出 "Old"
  6. myFunction=function()
  7. {
  8.   alert("New");
  9. };
  10. myFunction(); // 输出 "New"
复制代码


  旧函数哪里去了??被抛弃了。


  如果我们需要保留它,我们可以在改变它之前给它分配一个指针。

Example 6A:
  1. function myFunction()
  2. {
  3.   alert("Old");
  4. }
  5. var savedFuncion=myFunction;
  6. myFunction=function()
  7. {
  8.   alert("New");
  9. };
  10. myFunction();    // 输出 "New"
  11. savedFuncion();  // 输出 "Old"
复制代码




  不过要小心,象下面这样的例子并不会有作用,因为是创建了另一个叫做myFunctionPtr的函数而不是修改它。

Example 6B:
  1. function myFunction()
  2. {
  3.   alert("Old");
  4. }
  5. var savedFunc=myFunction;
  6. savedFunc=function()
  7. {
  8.   alert("New");
  9. };
  10. myFunction();            // 输出 "Old"
  11. savedFunc();             // 输出 "New"
复制代码


  我们还能够在一个函数中嵌套一个函数。下例,我有一个叫做getHalfOf的函数,而在它里面,我有另一个叫做calculate的函数。

Example 7
  1. function getHalfOf(num1, num2, num3)     
  2. {
  3.   function calculate(number)
  4.   {
  5.     return number/2;
  6.   }

  7.   var result="";
  8.   result+=calculate(num1)+" ";
  9.   result+=calculate(num2)+" ";
  10.   result+=calculate(num3);
  11.   return result;
  12. }         
  13. var resultString=getHalfOf(10,20,30);
  14. alert(resultString);         // 输出 "5 10 15"
复制代码


  你只能在内部调用嵌套的函数。就是说,你不能这么调用:getHalfOf.calculate(10),因为calculate只有当外部函数(getHalfOf())在运行的时候才会存在。这和我们前面的讨论一致(函数会被编译,但只有当你去调用它的时候才会执行)。
  你也许正在想命名冲突的问题。比如,下面哪一个叫做calculate的函数会被调用?

Example 8
  1. function calculate(number)
  2. {
  3.   return number/3;
  4. }

  5. function getHalfOf(num1, num2, num3)     
  6. {
  7.   function calculate(number)
  8.   {
  9.     return number/2;
  10.   }

  11.   var result="";
  12.   result+=calculate(num1)+" ";
  13.   result+=calculate(num2)+" ";
  14.   result+=calculate(num3);
  15.   return result;
  16. }         
  17. var resultString=getHalfOf(10,20,30);
  18. alert(resultString);         // 输出 "5 10 15"
复制代码


  在这个例子中,编译器会首先搜索局部内存地址,所以它会使用内嵌的calculate函数。如果我们删除了这个内嵌(局部)的calculate函数,这个代码会使用全局的calculate函数。

函数:数据类型及构造函数

  让我们来看看函数的另一个特殊功能--这让它和其它对象类型截然不同。一个函数能够用来作为一个数据类型的蓝图。这个特性通常被用在面向对象编程中来模拟用户自定义数据类型(user defined data type)。使用用户自定义数据类型创建的对象通常被成为用户自定义对象(user defined object)

  在定义了一个函数之后,我们也同时创建了一个新的数据类型。这个数据类型能够用来创建一个新对象。下例,我创建了一个叫做Ball的新数据类型。

Example DT1
  1. function Ball()
  2. {
  3. }
  4. var ball0=new Ball(); // ball0 现在指向一个新对象

  5. alert(ball0);         // 输出 "Object",因为 ball0 现在是一个对象
复制代码


  这样看来,ball0=new Ball()作了什么?new关键字创建了一个类型是Object的新对象(叫做ball0)。然后它会执行Ball(),并将这个引用传给ball0(用于调用对象)。下面,你会看到这条消息:“creating new Ball”,如果Ball()实际上被运行的话。

Example DT2
  1. function Ball(message)
  2. {
  3.   alert(message);
  4. }
  5. var ball0=new Ball("creating new Ball");  // 创建对象并输出消息
  6. ball0.name="ball-0";                      // ball0现在有一个属性:name
  7. alert(ball0.name);                        // 输出 "ball-0"
复制代码


  我们可以把上面这段代码的第6行看做是底下的代码6-8行的一个简写:
  1. function Ball(message)
  2. {
  3.   alert(message);
  4. }
  5. var ball0=new Object();
  6. ball0.construct=Ball;
  7. ball0.construct("creating new ball");  // 执行 ball0.Ball("creating..");
  8. ball0.name="ball-0";                     
  9. alert(ball0.name);         
复制代码


  这行代码ball0.construct=BallExample 4中的ptr=myFunction语法一致。
  如果你还是不明白这行的含义那就回过头再复习一下Example 4。注意:你也许考虑直接运行ball0.Ball("..."),但是它不会起作用的,因为ball0并没有一个叫做Ball("...")的属性,并且它也不知道你究竟想作些什么。
  当我们象上面那样使用关键字new创建一个对象的时候,一个新的Object被创建了。我们可以在创建之后给这个对象添加属性(就好像我在上面那样添加属性name。而接下来的问题就是如果我们创建了这个对象的另外一个实例,我们得象下面那样再次给这个新对象添加这个属性。)

Example DT3 (creates 3 ball objects)
  1. function Ball()
  2. {
  3. }
  4. var ball0=new Ball(); // ball0 现在指向了类型Ball的一个新实例
  5. ball0.name="ball-0";  // ball0 现在有一个属性"name"

  6. var ball1=new Ball();
  7. ball1.name="ball-1";

  8. var ball2=new Ball();

  9. alert(ball0.name);    // 输出 "ball-0"
  10. alert(ball1.name);    // 输出 "ball-1"
  11. alert(ball2.name);    // 哦,我忘记给ball2添加“name”了!
复制代码


  我忘记给ball2添加属性name了,如果在正式的程序中这也许会引发问题。有什么好办法可以自动增加属性呢?嗯,有一个:使用this关键字。this这个词在function中有特别的意义。它指向了调用函数的那个对象。让我们看看下面的另一个示例,这时候我们在构造函数中添加上这些属性:

Example DT4
  1. function Ball(message, specifiedName)
  2. {
  3.   alert(message);
  4.   this.name=specifiedName;               
  5. }
  6. var ball0=new Ball("creating new Ball", "Soccer Ball");  
  7. 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
  1. function Ball(color, specifiedName, owner, weight)
  2. {
  3.   this.name=specifiedName;               
  4.   this.color=color;
  5.   this.owner=owner;
  6.   this.weight=weight;
  7. }
  8. var ball0=new Ball("black/white", "Soccer Ball", "John", 20);  
  9. var ball1=new Ball("gray", "Bowling Ball", "John", 30);  
  10. var ball2=new Ball("yellow", "Golf Ball", "John", 55);  
  11. var balloon=new Ball("red", "Balloon", "Pete", 10);  

  12. alert(ball0.name);                        // 输出 "Soccer Ball"
  13. alert(balloon.name);                      // 输出 "Balloon"
  14. alert(ball2.weight);                      // 输出 "55"
复制代码


  嘿!使用面向对象术语,你能够说Ball是一个拥有如下属性的对象类型:name, color, owner, weight。
  我们并没被限制只能添加形如字符串或者数字之类的简单数据类型作为属性。我们也能够将对象赋给属性。下面,supervisorEmployee的一个属性.

Example DT6
  1. function Employee(name, salary, mySupervisor)
  2. {
  3.   this.name=name;               
  4.   this.salary=salary;
  5.   this.supervisor=mySupervisor;
  6. }
  7. var boss=new Employee("John", 200);

  8. var manager=new Employee("Joan", 50, boss);  
  9. var teamLeader=new Employee("Rose", 50, boss);  

  10. alert(manager.supervisor.name+" is the supervisor of "+manager.name);
  11. alert(manager.name+"\'s supervisor is "+manager.supervisor.name);  
复制代码


  会输出什么呢?
  就像你在上面这个例子中看到的那样,managerteamLeader都有一个supervisor属性,而这个属性是类型Employee的一个对象。
  任何类型的对象都可以作为一个属性,回忆一下前面的Example 4(不是Example DT4),函数也是一个对象。所以你可以让一个函数作为一个对象的一个属性。下面,我将添加两个函数getSalaryaddSalary

Example DT7
  1. function Employee(name, salary)
  2. {
  3.   this.name=name;               
  4.   this.salary=salary;

  5.   this.addSalary=addSalaryFunction;

  6.   this.getSalary=function()
  7.                  {
  8.                    return this.salary;
  9.                  };
  10. }
  11. function addSalaryFunction(addition)
  12. {
  13.   this.salary=this.salary+addition;
  14. }

  15. var boss=new Employee("John", 200000);
  16. boss.addSalary(10000);                    // boss 长了 10K 工资……为什么老板工资可以长这么多:'(
  17. alert(boss.getSalary());                  // 输出 210K……为什么默认工资也那么高……:'(
复制代码


  addSalarygetSalary演示了几种将函数赋给属性的不同方法。如果你记得我们最开始的讨论;我讨论了三种声明函数的不同方式。所有那些在这里都是适用的,但是上面展示的两个最常用。
  让我们看看有什么不同。下面,注意一下9-12行的代码。当这部分代码执行的时候,函数getSalary被声明。如前面数次提到的,一个函数声明的结果是一个对象被创建。所以这时候boss被创建(接下来的第19行),而boss里有一个getSalary属性。

  1. function Employee(name, salary)
  2. {
  3.   this.name=name;               
  4.   this.salary=salary;

  5.   this.addSalary=addSalaryFunction;

  6.   this.getSalary=function()
  7.                  {
  8.                    return this.salary;
  9.                  };
  10. }
  11. function addSalaryFunction(addition)
  12. {
  13.   this.salary=this.salary+addition;
  14. }

  15. var boss=new Employee("John", 200000);
  16. var boss2=new Employee("Joan", 200000);
  17. var boss3=new Employee("Kim", 200000);
复制代码


  当你创建这个对象的更多实例时(boss2boss3),每一个实例都有一份getSalary代码的单独拷贝;而与此相反,addSalary则指向了同一个地方(即addSalaryFunction)。  

  看看下面的代码来理解一下上面所描述的内容。

Example DT8
  1. function Employee(name, salary)
  2. {
  3.   this.name=name;               
  4.   this.salary=salary;

  5.   this.addSalary=addSalaryFunction;
  6.   this.getSalary=function()
  7.                  {
  8.                    return this.salary;
  9.                  };
  10. }
  11. function addSalaryFunction(addition)
  12. {
  13.   this.salary=this.salary+addition;
  14. }

  15. var boss1=new Employee("John", 200000);
  16. var boss2=new Employee("Joan", 200000);


  17. // 给getSalary函数对象添加属性
  18. boss1.getSalary.owner="boss1";
  19. boss2.getSalary.owner="boss2";
  20. alert(boss1.getSalary.owner);   // 输出 "boss1"
  21. alert(boss2.getSalary.owner);   // 输出 "boss2"
  22. // 如果两个对象指向同一个函数对象,那么
  23. // 上面两个输出都应该是“boss2”。

  24. // 给addSalary函数对象添加属性
  25. boss1.addSalary.owner="boss1";
  26. boss1.addSalary.owner="boss2";
  27. alert(boss1.addSalary.owner);   // 输出 "boss2"
  28. alert(boss2.addSalary.owner);   // 输出 "boss2"
  29. // 因为两个对象都指向同一个函数,(子乌注:原文写are not pointing to the same function,疑为笔误)
  30. // 当修改其中一个的时候,会影响所有的实例(所以两个都输出“boss2”).
复制代码


  也许不是重要的事情,但这里有一些关于运行类似上面的getSalary的内嵌函数的结论: 1) 需要更多的存储空间来存储对象(因为每一个对象实例都会有它自己的getSalary代码拷贝);2) javascript需要更多时间来构造这个对象。
  让我们重新写这个示例来让它更有效率些。

Example DT9
  1. function Employee(name, salary)
  2. {
  3.   this.name=name;               
  4.   this.salary=salary;

  5.   this.addSalary=addSalaryFunction;
  6.   this.getSalary=getSalaryFunction;
  7. }
  8. function getSalaryFunction()
  9. {
  10.   return this.salary;
  11. }

  12. function addSalaryFunction(addition)
  13. {
  14.   this.salary=this.salary+addition;
  15. }
复制代码


  看这儿,两个函数都指向同一个地方,这将会节约空间和缩短构造时间(特别是当你有一大堆内嵌函数在一个构造函数的时候)。这里有另外一个函数的功能能够来提升这个设计,它叫做prototype,而我们将在下一节讨论它。

函数:原型
  每一个构造函数都有一个属性叫做原型(prototype,下面都不再翻译,使用其原文)。这个属性非常有用:为一个特定类声明通用的变量或者函数。

  你不需要显式地声明一个prototype属性,因为在每一个构造函数中都有它的存在。你可以看看下面的例子:

Example PT1
  1. function Test()
  2. {
  3. }
  4. alert(Test.prototype);  // 输出 "Object"
复制代码


  就如你在上面所看到的,prototype是一个对象,因此,你能够给它添加属性。你添加给prototype的属性将会成为使用这个构造函数创建的对象的通用属性。
  例如,我下面有一个数据类型Fish,我想让所有的鱼都有这些属性:livesIn="water"price=20;为了实现这个,我可以给构造函数Fishprototype添加那些属性。

Example PT2
  1. function Fish(name, color)
  2. {
  3.   this.name=name;
  4.   this.color=color;
  5. }
  6. Fish.prototype.livesIn="water";
  7. Fish.prototype.price=20;
复制代码


  接下来让我们作几条鱼:
  1. var fish1=new Fish("mackarel", "gray");
  2. var fish2=new Fish("goldfish", "orange");
  3. var fish3=new Fish("salmon", "white");
复制代码


  再来看看鱼都有哪些属性:
  1. for (var i=1; i<=3; i++)
  2. {
  3.   var fish=eval("fish"+i);   // 我只是取得指向这条鱼的指针
  4.   alert(fish.name+","+fish.color+","+fish.livesIn+","+fish.price);
  5. }
复制代码


  输出应该是:
  1. "mackarel, gray, water, 20"
  2. "goldfish, orange, water, 20"
  3. "salmon, white  water, 20"
复制代码


  你看到所有的鱼都有属性livesInprice,我们甚至都没有为每一条不同的鱼特别声明这些属性。这时因为当一个对象被创建时,这个构造函数将会把它的属性prototype赋给新对象的内部属性__proto__。这个__proto__被这个对象用来查找它的属性。
  你也可以通过prototype来给所有对象添加共用的函数。这有一个好处:你不需要每次在构造一个对象的时候创建并初始化这个函数。为了解释这一点,让我们重新来看Example DT9并使用prototype来重写它:

Example PT3
  1. function Employee(name, salary)
  2. {
  3.   this.name=name;               
  4.   this.salary=salary;
  5. }
  6. Employee.prototype.getSalary=function getSalaryFunction()
  7. {
  8.   return this.salary;
  9. }

  10. Employee.prototype.addSalary=function addSalaryFunction(addition)
  11. {
  12.   this.salary=this.salary+addition;
  13. }
复制代码



  我们可以象通常那样创建对象:

  1. var boss1=new Employee("Joan", 200000);
  2. var boss2=new Employee("Kim", 100000);
  3. var boss3=new Employee("Sam", 150000);
复制代码


  并验证它:
  1. alert(boss1.getSalary());   // 输出 200000
  2. alert(boss2.getSalary());   // 输出 100000
  3. alert(boss3.getSalary());   // 输出 150000
复制代码


  这里有一个图示来说明prototype是如何工作的。这个对象的每一个实例(boss1, boss2, boss3)都有一个内部属性叫做__proto__,这个属性指向了它的构造器(Employee)的属性prototype。当你执行getSalary或者addSalary的时候,这个对象会在它的__proto__找到并执行这个代码。注意这点:这里并没有代码的复制(和Example DT8的图表作一下对比)。


[ 本帖最后由 Sheneyan 于 2007-2-25 09:21 编辑 ]
已有 1 人评分威望 收起 理由
hutia + 5 精品文章

总评分: 威望 + 5   查看全部评分

西部数码顶级域名注册商39元抢注!
asfman 
帖子
586
体力
2647
威望
0
发表于 2006-7-26 09:32:21 |显示全部楼层
你的每副示意图都是 一样的
人有多大胆  地有多大产
没有做不到  只有想不到
租服务器,上51IDC | [长沙]招聘:PHP经理10K/WEB前端6K/PHP开发6K

使用道具 举报

帖子
123
体力
189
威望
0
发表于 2006-9-12 14:16:26 |显示全部楼层
Very Good
JimWeb

使用道具 举报

八一

银牌会员 手机认证 

帖子
770
体力
2088
威望
2
居住地
江苏省 苏州市
发表于 2006-9-12 23:41:47 |显示全部楼层
斑竹辛苦了,好东西要仔细的看那!

使用道具 举报

fish2008

高级会员

帖子
205
体力
1142
威望
0
居住地
广东省 深圳市
发表于 2006-9-13 09:21:42 |显示全部楼层

顶!

顶!希望咱们经典多出这样的贴子。
一条离不开网的鱼^-^

使用道具 举报

larry的马甲

银牌会员

帖子
463
体力
1209
威望
0
发表于 2006-9-13 10:51:51 |显示全部楼层
收藏了~~tks楼主哈

使用道具 举报

lynovr 

lynovr

新手上路

帖子
171
体力
232
威望
0
发表于 2006-9-13 11:13:04 |显示全部楼层
啊哦 看一下

使用道具 举报

ihibin 
帖子
18
体力
51
威望
0
发表于 2006-12-11 16:08:14 |显示全部楼层

没啥说的,顶了。。。

翻译的参考都写出来了,好

使用道具 举报

帖子
29
体力
76
威望
0
发表于 2006-12-11 16:14:35 |显示全部楼层
我爱你!

使用道具 举报

skybot 

size

钻石会员 手机认证 

帖子
3236
体力
12466
威望
7
发表于 2006-12-11 22:10:32 |显示全部楼层
..........面向对象啊....
http://www.qlili.com 个人站帮点啊

使用道具 举报

lwkyy 

学习笔记

中级会员

帖子
169
体力
553
威望
0
发表于 2007-1-30 22:33:12 |显示全部楼层
真的不错啊,谢谢了!!

使用道具 举报

帖子
46
体力
86
威望
2
居住地
山东省 济南市
发表于 2007-1-31 09:05:12 |显示全部楼层
不错,国外JS类的书籍很丰富也很棒。鼓励楼主再接再厉多翻译两本。
www.cuilin.name

使用道具 举报

hero4u 

孤竹林

金牌会员 手机认证 

帖子
1305
体力
3444
威望
14
居住地
湖南省 长沙市
发表于 2007-2-24 11:24:22 |显示全部楼层
呵呵,不错的文章了,看原型类好吃力了,呵呵
体验游戏 game4power

使用道具 举报

流光恋羽

高级会员 手机认证 

帖子
206
体力
745
威望
0
发表于 2007-2-24 11:30:52 |显示全部楼层
谢谢大大的翻译,中文还是那么的亲切~~

使用道具 举报

bound0 

老饕

版主 手机认证 

帖子
6593
体力
8788
威望
287
发表于 2007-2-24 22:45:56 |显示全部楼层
看这篇文章的时候,更正了我的一个印象。在我过去的印象当中,认为“属性”是和“方法”同级的概念,广义的属份(property)包括了属性(attribute)和方法(method),但是在中文中property和attribute却常常译作同一个词(属性)。我还曾经为此疑惑。不知日本人和台湾人是怎么处理这个词的翻译的,或许可以参考下他们的(说不定日本人是用片假名译音,译成“扑落魄踢”)。

一直认为“属性”是指对象中包含的可访问数据成分,而方法是可操作成分。

但是可操作的必定首先是可访问的,所以“属性”是包括了“方法”的。“方法”和其他“属性”之间除了可操作这一点之外,没有更多绝对的区别。
[Bound0 专题列表]
Pas besoin de gril : l'enfer, c'est les Autres.

使用道具 举报

帖子
1
体力
7
威望
0
发表于 2007-7-14 12:15:58 |显示全部楼层
梦里寻它千百度,原来它在这里住。
屠红磊

使用道具 举报

jskin 
帖子
76
体力
316
威望
0
发表于 2008-7-28 16:23:19 |显示全部楼层
翻译的不错,楼主辛苦了!

使用道具 举报

eLore 
帖子
224
体力
673
威望
2
居住地
广东省 惠州市
发表于 2008-7-29 01:57:54 |显示全部楼层
看发表日期,发现是06年的了,不过确实很经典,对于正确认识和使用函数帮助很大。
网络如此多娇 引无数小鸟竟折腰

使用道具 举报

ljlyy 
帖子
116
体力
490
威望
1
居住地
广东省 广州市
发表于 2008-8-6 21:50:09 |显示全部楼层
这么早的也被翻出来了!1

使用道具 举报

荷西

银牌会员 手机认证 

帖子
2770
体力
1881
威望
1
发表于 2008-8-7 08:02:12 |显示全部楼层
做个书签
上善若水

使用道具 举报

jaoooo 
帖子
53
体力
208
威望
0
发表于 2008-8-7 08:45:43 |显示全部楼层
温故而知新 书签

使用道具 举报

FFEEDD 

褪色

银牌会员 手机认证 

帖子
439
体力
1387
威望
1
居住地
北京市 朝阳区
发表于 2008-8-7 10:25:04 |显示全部楼层
楼上请不要无意义翻旧帖.当心遭雷P~~~
no idea

使用道具 举报

帖子
64
体力
377
威望
0
居住地
广东省 深圳市
发表于 2008-8-25 21:07:18 |显示全部楼层
看到getSalary和addSalary处实在不解,
敢问子乌前辈这两个函数是不是JS的函数?
如果是的话有什么作用?
To Be Is To Do!

使用道具 举报

帖子
323
体力
1168
威望
0
发表于 2008-8-25 21:24:33 |显示全部楼层
辛苦,顶!!

使用道具 举报

帖子
514
体力
1146
威望
0
居住地
广东省 深圳市
发表于 2008-8-28 13:34:47 |显示全部楼层
好 很好 我喜欢

使用道具 举报

nyu16 

夏夜

金牌会员 手机认证 

帖子
206
体力
3997
威望
0
居住地
浙江省 杭州市
发表于 2008-9-12 13:04:37 |显示全部楼层
很好 。。。我学习 。1!
温经散寒补肝肾强筋骨

使用道具 举报

啸天皇帝

银牌会员

帖子
587
体力
2290
威望
0
居住地
广东省 深圳市
发表于 2008-9-12 13:21:55 |显示全部楼层
现在上班,先藏了,回家慢慢研究。


呵呵....

使用道具 举报

帖子
41
体力
179
威望
0
发表于 2008-10-10 22:17:02 |显示全部楼层
@.@那我也留个书签!~~

使用道具 举报

帖子
48
体力
190
威望
0
居住地
湖北省 武汉市
发表于 2008-10-10 23:34:44 |显示全部楼层
不错,非常不错。
收下啦
谢谢子乌兄啦

使用道具 举报

mqycn 

勿弃

高级会员

帖子
168
体力
590
威望
2
居住地
山东省 济南市
发表于 2008-12-14 23:32:12 |显示全部楼层
此等好帖一定要细读

前几天在网上看到Javascript对象有四种创建方式:function方式,JSON方式,原型方式,create方式,只试验成功Function方式,还请楼主指点迷津

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

Archiver|手机版|安久科技提供CDN|blueidea.com ( 京ICP备05002321号 )  

GMT+8, 2012-2-13 13:03 , Processed in 0.436506 second(s), 9 queries , Gzip On, Memcache On.

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部