javascript必知之prototype 代码加注释,希望大家喜欢!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>javascript必知会之prototype</title> <script type="text/javascript" language="javascript"> function foo(a, b, c) { return a * b * c; } alert(foo.length); alert(typeof foo.constructor); alert(typeof foo.call); alert(typeof foo.apply); alert(typeof foo.prototype); /* 对于上面的代码,用浏览器运行后你会发现: 1、length提供的是函数的参数个数 2、prototype是一个object 3、其他三个都是function 而对于任何函数的声明,他都将会具有上面所述的5个property(方法或者属性) 下面主要看prototy */ function Person(name, gender) { this.name = name; this.gender = gender; this.whoAreYou = function() {//这个所谓的closure;内部函数可以访问外部函数变量 var res = "I'm " + this.name + " and I'm a " + this.gender; return res; }; } //那么由Person创建的对象便有了下面几个属性 Person.prototype.age = 24; Person.prototype.getAge = function() { return this.age; }; flag = true; if (flag) { var fun = new Person("Tower", "male"); alert(fun.name); alert(fun.gender); alert(fun.whoAreYou()); alert(fun.getAge()); } Person.prototype.salary = 10000; Person.prototype.getSalary = function() { return this.name + "can earn about " + this.salary + " RMB each month."; }; /* 下面就是最神奇的地方了,我们改变了Person的prototype,而这个改变是在创建fun之后 而这个改变使得fun也具有了相同属性和方法 继承的意味即此 */ if (flag) { alert(fun.getSalary()); alert(fun.constructor.prototype.age);//而这个相当于你直接调用了Person.protype.age alert(Person.prototype.age); } /* 从上面的示例中我们可以发现,对于prototype的方法或者属性,我们可以 动态地 增加,而由其创建的 对象 自动 会 继承 相关的方法和属性 另外,每个对象都一个constructor属性,用于指向创建其函数的对象,如上例中的fun.constructor指向的就是 Person 那么一个疑问就自然产生了,"函数对象中自身的方法和属性与prototype声明的对象有什么差别?" 有下面几个差别: 1、自身声明的方法和属性是 静态的,也就是说你在声明后,试图再去增加新的方法或者修改已有的方法,并不会对由其创建的对象产生影响,也即继承失败。 2、而prototype可以动态的增加新的方法或者修改已有的方法,从而是动态的,一旦父函数对象声明了相关的prototype属性,由其创建的对象会自动继承这些prototype的属性 继续上面的例子 */ flag = true; //函数内部声明的方法是静态的,无法传递的 Person.school = "ISCAS"; Person.whoAreYou = function() { return "zhutao"; }; //动态更改声明期的方法,并不会影响其创建的方法,即所谓的静态 if (flag) { alert(Person.school);//输出"ISCAS" alert(fun.school);//输出"undefined" alert(Person.whoAreYou());//zhutao alert(fun.whoAreYou());//I'm Tower and I'm a male. } Person.prototype.getSalary = function() { return "I can earn 1000000USD"; }; if (flag) { alert(fun.getSalary());//已经集成了改变,即所谓的动态 } /* 既然有函数对象本身的属性,也有prototype的属性,那么是由其创建的对象是如何搜索相应的属性呢? 基本是按照下面的流程和顺序来经行的。 1、先去搜索函数对象本身的属性,若果找到立即执行 2、如果1没有找到,则会去搜索prototype属性,有2中结果,找到的直接执行,负责积雪搜索父对象的父对象的prototype,知道找到 或者达到prototype chain的结尾(结尾会是objec对象) 上面的也回答如果函数对象本身的属性与prototype属性相同(重名)时的解决方式,函数本身的对象优先 再看一个多重prototype链的例子 */ function Employee(neme) { this.name = ""; this.dept = "general"; this.gender = "unknown"; } function WorkerBee() { this.projects = []; this.hasCar = false; } WorkerBee.prototype = new Employee; //第一层prototype链 function Engineer() { this.dept = "enginner"; //覆盖了“父对象” this.language = "javascript"; } Engineer.prototype = new WorkerBee; //第二层prototype链 var jay = new Engineer("Jay"); if (flag) { alert(jay.dept);//engineer,找到的是自己的属性 alert(jay.hasCar);//flase,搜到的是自己上一层的属性 alert(jay.gender);//unknown,搜到的是自己上二层的属性 } </script> </head> <body> </body> </html>
(责任编辑:admin) |