您的位置:首页 > Web前端 > JavaScript

javascript的面向对象方法调用中的优先级浅析

2011-04-07 17:28 387 查看
javascript的面向对象有人说实际上应该成为基于对象,我觉得很有道理。因为javascript中只有所有构成的基本元素就是对象,包括类也是以对象的形式出现的。

这里不打算分析javascript面向对象的基本原理,只想从面向对象的方法调用的角度入手,了解javascript的继承中,方法的优先级。

首先定义一个类:person

function person(){
this.name;
this.age;
this.sex;
//              this.getName=function(){
//                  console.log("person类的getName被调用");
//                  return this.name;
//              };
this.setName=function(name){
console.log("person类的setName被调用");
this.name=name;
};
}


类同时也是一个方法,上面的类定义代码中,定义了内联的方法getName和setName。

然后给类的prototype属性定义两个同名的方法:

person.prototype.getName=function(){
console.log("person.prototype.getName()被调用");
return this.name;
}
person.prototype.setName=function(name){
console.log("person.prototype.setName()被调用");
this.name=name;
}


给类的原型定义方法:person.prototype.getName=function()... 意义上等价于:给person这个方法所代表的类,定义方法。仔细看来:这里的person.prototype是一个引用,指向的是person方法所代表的类。我们知道,引用都是指向对象的,为什么还有指向类的引用呢?其实这个类就是对象。只不过javascript里所有东西都是对象,不存在纯粹的类。

实际上这里的person一方面代表一个方法(构造函数)。另一方面person.prototype代表的就是传统意义上的类。那么给这个person类定义的方法,就可以被所有person类的对象使用。

而现在看来,类的内联方法和类的原型中定义的方法同名,都可以通过例如:对象名.getName()的方式来调用。

我们建立一个这个person类的实例my,看看调用的效果:

var my=new person();
my.setName("peter");
var name=my.getName();
console.log(name);


console.log(name)将输出peter,这是调用了person构造函数中的内联方法getName的结果。如果注释掉内联方法getName,将调用person.prototype中定义的getName方法。

由此说明,构造函数中定义的方法优先级高于原型中定义的方法。

再进一步,给my这个对象,顶一个getName方法,看看结果:

var my=new person();
my.setName("peter");
my.getName=function(){
console.log("my对象的.getName()被调用");
return this.name;
}
var name=my.getName();
console.log(name);


现在my这个对象也有了一个getName方法,再次执行,my.getName()将调用my对象中定义的getName()

由此说明,当方法名相同时,方法优先级由高至低:对象中定义的方法-->类构造函数中的内联方法-->类原型中定义的方法。

上面说明的情况不涉及到类的继承。只是说明一个类和这个类的对象中有同名的方法时,调用的优先级。

那么,有继承的情况如何呢?

我们简单的定义一个类继承person:

function employee(){
console.log("employee的构造函数被调用");
}
employee.prototype=new person();
var emp1=new employee();

emp1.setName("john");
var john=emp1.getName();
console.log(john);


这里,emp1.setName("john")首选考虑调用的是他的父类的构造函数中内联的方法,其次在考虑prototype中定义的方法。

同样的,如果给john对象定义了一个getName方法的话:
employee.prototype=new person();
var emp1=new employee();

emp1.setName("john");
emp1.getName=function(){
console.log("john类的getName方法被调用");
return this.name;
};
var john=emp1.getName();
console.log(john);


那么这时,emp1对象的getName方法被优先调用。相当于覆盖了父类中定义的同名方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: