javascript必知之prototype 代码加注释,希望大家喜欢!
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="" >
<head>
<title>必知会之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>