<script language="javascript">
function person(name){
this.name = name;
}
person.prototype.say = function(){alert("hello, i'm " + this.name);}function employee(name, salary){
person.call(this, name);
this.salary = salary;
}
employee.prototype = new person(); //等效于employee.prototype = person.prototypeemployee.prototype.showMoney = function(){alert(this.name + "'s salary is " + this.salary);}alert(employee.prototype == person.prototype);
alert(employee.prototype == person);
</script>
大家看上面的代码,是一个简单的继承,employee.prototype = new person();的目的是将employee的protoytype设置成person的prototype,从而可以通过“原型链”调用到person的prototype的方法,所以我觉得他等效于employee.prototype = person.prototype,但通过下面的两个alert来看,他们并不等效,请问它们的区别是什么,原因在哪里?
看看这个
当然不等效employee.prototype = new person() 这样的话person中this上的属性也会在employee.prototype而employee.prototype = person.prototype 而这样就只会有原型上的东西。 this上的没有。
employee.prototype = new person();使得employee的实例拥有了person的所有属性,包括person.prototype里的所有属性,
employee.prototype只是employee的原型对象,当js试图查找employee实例里的某一属性时会先查找 emloyee的实例成员,如果没找到会从employee.prototype里查找,然后person的实例, person.prototype...以此类推.employee.prototype person.prototype person
是三个不同的概念, employee.prototype和person.prototype是Object, person是构造函数.所以他们之间不会相等!
var e = new employee("BillGates", 5000);
alert(e.prototype.name);
结果:
Error:'e.prototype.name' 为空或不是对象
汗 没看明白
employee.prototype = new person();
看上面 就知道下面不等了
alert(employee.prototype == person.prototype);
alert(employee.prototype == person);
employee.prototype = new person();
表示employee.prototype是person的实例。既employee.prototype.__proto__ = person.prototype
employee.prototype里找某个属性或者方法时,首先从对象本身找(new person实例对象),找不到才根据隐式链__proto__(firefox可访问)指向,到person.prototype里去找,还找不到就到person.prototype.__proto__(也就是Object.prototype)去找,这么一层层往上找。
你可以好好看下下面这张图,我贴了好多次了,转自cnblogs一位大牛riccc的图,红色部分就是__proto__链式指向
给你好好说说//这个函数定义对应图上左边use(应该是user) defined functions那一层,用户定义函数
function person(){
}
//同上
function employee(){
}
//这个employee.prototype对应左边objects that(应该是those :D) created by user defined functions那一层
employee.prototype = new person()然后你再看红色箭头指向,再结合我#13楼的描述。
employee.prototype = new person();和employee.prototype = person.prototype;
从实际应用的效果来说,其实也没什么大的区别喽!只是new person()的话就多了一层,但是从实际效果来看应该是没什么区别的吧?不知这样说对不对
再给你个例子function person(){
this.feature = 'cruel animal';
}
person.prototype = {}
function employee(){
}
//employee.prototype = person.prototype;
employee.prototype = new person();//把这行注释掉,再把上面的打开,alert(rookie.feature);为什么会alert出undefined?请再仔细思考.
var rookie = new employee();
alert(rookie.feature);
所以如果 employee.prototype == person.prototype 为真 EP == PP
则证明 new person() == person.prototype NP == PP
但是 new person() == person.prototype 明显是不能相等的 NP==PP -->F
所以反推 employee.prototype == person.prototype 为真是错误的 EP==PP -->F我也学楼上的 搞的复杂点
接17楼1.如果是
employee.prototype = new person();
var rookie = new employee();
alert(rookie.feature);
那么要找rookie.feature
就循着这条链去找( -> 意为如果找不到则往下一个对象找)
rookie(new employee) -> rookie.__proto__(employee.prototype,也就是new person) -> employee.prototype.__proto__
(person.prototype) -> person.prototype.__proto__(Object.prototype)rookie.feature在这条链中的 employee.prototype处被找到,也就是第二步:rookie.__proto__2.如果是
employee.prototype = person.prototype;
var rookie = new employee();
alert(rookie.feature);
那么要找rookie.feature
就循着这条链去找
rookie(new employee) -> rookie.__proto__(employee.prototype,也就是person.prototype)
-> employee.prototype.__proto__(Object.prototype)
找不到,over.prototype就是一条链,一环扣一环.不用继承那种东西理解反而好些.
function person(name){
this.name = name;
}
person.prototype.say = function(){
alert("hello, i'm " + this.name);
}
var t=new person("fang");
alert(t.name);
t.say();
function employee(name, salary){
person.call(this, name);
this.salary = salary;
}
//并没有继承person.prototype中的say方法
var tt=new employee("fang","1000");
alert(tt.name);
alert(tt.salary);
//employee.prototype拥有属性name,方法say(),即拥有person及person.prototype中的所有方法和属性
employee.prototype = new person();
//此又增加了showMoney()方法
/**因此employee.prototype有属性name,方法say(),showMoney()
即拥有person及person.prototype中的所有方法和属性即employee.prototype
对象中的属性和方法
**/
employee.prototype.showMoney = function(){
alert(this.name + "'s salary is " + this.salary);
}
var ttt=new employee("fang","1000");
employee.prototype.say();
/* person.prototype中只有方法say()
* person中有属性name和对象person.prototype,相当于person.prototype是person子集
* employee.prototype=person+person.prototype+employee.prototype
*/
alert(employee.prototype == person.prototype);
alert(employee.prototype == person);
http://blog.csdn.net/niuyongjie/archive/2009/11/15/4810835.aspx
第一种: function a(){
this.c=12;
} function b(){
a.call(this);
}
var bb= new b(); alert(bb.c); //12 b继承了a 这种方式非常的巧妙, call 是Function原型的一个
方法,意思也很简单 a.call(this); 就是说调用a方法,并把a方法里的this换成你给的参数 这里我们给的就是b中的this. 也就是说我们在new b()时我们调用了a方法 而a方法我们把他里面的this 换成了b方法里的this。
这就相当于我们给b中的this添加了c这个属性, 所以我们bb就有c这个属性. 第二种: function a(){
this.c=12;
this.d=function(){
alert(this.c);
}
} function b(){
this.c=34;
}
var aa=new a();
b.prototype=aa; var bb=new b();
bb.d();//34 为什么是34? 前面说过javascript 会先访问this里的然后访问prototype里的 在这里我们b.prototype=new a(); 很明显我们给b的prototype原型指向了一个对象,即aa;而aa是有d这个方法的。所以我们的bb也有了d这个方法. 但是这里为什么是34而不是12呢?简单的说 javascript中this的指向就是你调用一个方法时.(点) 前面的那个对象 。比如这里bb.d();我们这里d方法点前面是bb 所以this指向的就是bb这个对象,而bb我们设置了一个c的属性c=34 ;所以这里就弹出了34.当我们去点b方法中this.c=34时,结果就变成了12 这是为什么呢? 写的实在手痛了 这个问题就留给你回答吧。提醒(1: this是可以访问原型中的属性的,2:根据开始我对对象属性访问顺序的分析)
那个javascript对象模型图极其精炼啊,为什么不用心去看看呢?
你理解了那张图,你就能理解下面这个例子//1
Object.prototype.a = 'hello Object.prototype';
//2
Function.prototype.a = 'hello Function.prototype';function o(){
}var t = new o();alert(t.a);//为什么是 hello Object.prototype ?
alert(o.a);//为什么是 hello Function.prototype ?
Object.prototype.a = 'hello Object.prototype';
//2
Function.prototype.a = 'hello Function.prototype';
//3
Object.prototype.b = 'hello Object.prototype B';function o(){
}var t = new o();alert(t.a);//为什么是 hello Object.prototype ?
alert(o.a);//为什么是 hello Function.prototype ?
alert(Function.a);//为什么是hello Function.prototype ?
alert(Object.a);//为什么是hello Function.prototype ?
alert(Object.b);//为什么是hello Object.prototype B ?
=======================
重点就是了解对象属性[[prototype]]也就是__proto__的指向
当然javascript的继承基本靠的是prototype链.
你不想深究的话,那就这样吧.
这个我说的有误,不好意思,我现在并没用再用继承去理解js对象继承之间的关系了,知道js是通过prototype和call的传递this来模拟类的继承,而xx.prototype = new yy();时会使yy的prototype成为xx.prototype的一部分
再说那张图不是我画的,是我以前跟你一样晕的时候,搜索到的
原文在这里http://www.cnblogs.com/RicCC/archive/2008/02/15/JavaScript-Object-Model-Execution-Model.html
看不懂不要紧,多看几遍,再慢慢体会那张图.你会有豁然开朗的感觉.再给你个例子,firefox(因为firefox下才可访问__proto__)下不用new,如何模拟实例化一个函数?
只考虑了__proto__指向,把问题最简单化.
//请在firefox下运行
function init(fn){
var o = {}
o.__proto__ = fn.prototype;
fn.call(o);
return o;
}
var c = function(a,b){
this.a = 'a';
}
c.prototype = {
b : 'b'
}var i = init( c );alert(i.b);//为什么能找到b这个属性?
而使用xx.prototype = yy.prototype;的话,则会将xx的prototype完全指向成yy的prototype,所以,如果在xx.prototype = yy.prototype;之前有改变xx.prototype的操作的话,这之后都没丢失之前的操作
function init(fn){
var o = {} //创建一个对象
o.__proto__ = fn.prototype; //将对象o内置的原型对象设置为fn的prototype——__proto__被称为内置原型对象
fn.call(o); //将o作为fn的this并调用fn
return o;
}
var c = function(a,b){
this.a = 'a';
}
c.prototype = {
b : 'b'
}var i = init( c );alert(i.b);//为什么能找到b这个属性?因为i=o
且o.__proto__=c.prototype
又因为c.prototype.b = 'b'
所以o.__proto__.b=o.b=='b'
所以i.b=='b'
这样对不?
alert(i.b)首先找i这个对象里有无b属性,没有就到i.__proto__去找,也就是fn.prototype,如果还找不到,就应该到
fn.prototype.__proto__去找,也就是Object.prototype
建议可以看看这2篇文章
http://www.mscto.com/JavaScript/2009010343993.html
http://topic.csdn.net/u/20080714/10/cacb56ca-819d-48ff-adf6-7ffe9a13af5b.html相信会使楼主对javascript理解更上一层楼。