js 原型 继承

自定义类型

简单的说 prototype 就是我们定义的类Person 的一个属性,这个属性prototype是一个对象 ,对象的所有属性name age和speak方法 都会被我们定义的这个类Person  所创建的对象(或说成自定义类的实例)new Person   共享。

相当于类的公共属性和方法。

原型模式。在我们声明一个新的函数后,该函数(在JavaScript中,函数也是对象)就会拥有一个prototype的属性。

prototype是一个对象,表示会被该函数创建的所有对象拥有的公共属性和方法。

function Person(){}
Person.prototype.name="令狐冲";
Person.prototype.age=26;
Person.prototype.speak = function(){
 alert(this.name + "is " + this.age + "years old");
}
var person1 = new Person();
person1.speak();
var person2 = new Person();
alert(person1.speak == person2.speak);   // true
----------------------------------------------------------------------------------------------------

可以看到,虽然构造函数内没有声明speak方法,但我们创建的对象person1还是能调用speak方法,这是因为JavaScript有一个搜索规则,先搜索实例属性和方法,找到则返回;如果没找到,则再到prototype中去搜索。原型模式使得方法是与类相关的,并且没有污染全局作用域,

但其也有自身的缺点:一是所有属性(如 name,age)也都与类相关,这意味着所有对象共享一份属性,这显然是不合理的;二是没有办法向构造函数传入初始化数据了。

解决的方法很简单,就是混合使用构造函数模式和原型模式。

-----------------------------------------------------

function Person(name, age){
 this.name = name;
 this.age = age;
}
Person.prototype.speak = function(){
 alert(this.name + "is " + this.age + "years old");
}
var person1 = new Person();
person1.speak();
var person2 = new Person();
alert(person1.speak == person2.speak);   // true

不难发现,组合模式实现了我们的所有需求,这也是目前应用得比较广泛的一种模式。有面向对象编程经验的开发人员可能会觉得将prototype的声明放在构造函数外面有点别扭,那么能否将其放到构造函数里去呢?答案是肯定的,使用动态组合模式即可。
function Person(name, age){
   this.name = name;
   this.age = age;
   if (Person.prototype.speak == "undefined"){
     Person.prototype.speak = function(){
     alert(this.name + "is " + this.age + "years old");
    }
  }
}
-------------------------------------------------------------

var person = new Object();
person.name = "Sam";
person.age = 16;
person.speak = function(){
 alert(this.name + "is " + this.age + "years old");
}
person.speak();

可以看到,上面创建了一个Object类型的对象,然后为其添加了name和age属性以及一个speak方法。直接创建模式虽然简单,但其缺点是显而易见的:当我们需要创建许多相同的对象时,每次都要重复编写代码。为了解决这个问题,我们可以将创建对象的过程进行封装,于是便有了下面的工厂模式。
------------------------
参考资料:创世软件团队, 原文地址: http://www.cnblogs.com/hujian/archive/2012/05/03/2479979.html

这个例子说明了一个类型如何从另一个类型继承。
function AClass()
{
       this.Property = 1;
       this.Method = function()
       {
              alert(1);
       }
}
 
function AClass2()
{
       this.Property2 = 2;
       this.Method2 = function()
       {
              alert(2);
       }
}
AClass2.prototype = new AClass();
 
var obj = new AClass2();
alert(obj.Property);
obj.Method();
alert(obj.Property2);
obj.Method2();

 

这个例子说明了子类如何重写父类的属性或方法。

function AClass()
{
       this.Property = 1;
       this.Method = function()
       {
              alert(1);
       }
}
 
function AClass2()
{
       this.Property2 = 2;
       this.Method2 = function()
       {
              alert(2);
       }
}
AClass2.prototype = new AClass();
AClass2.prototype.Property = 3;
AClass2.prototype.Method = function()
{
       alert(4);
}
var obj = new AClass2();
alert(obj.Property);
obj.Method();

------------------------------
可以在对象上增加属性或方法

function Aclass()
{
this.Property = 1;
this.Method = function()
{
    alert(1);
}
}
var obj = new Aclass();
obj.Property2 = 2;
obj.Method2 = function()
{
    alert(2);
}
alert(obj.Property2);
obj.Method2();

-----------------------------------------------------
可以在对象上改变属性。(这个是肯定的)
也可以在对象上改变方法。(和普遍的面向对象的概念不同)

 function Aclass()
{
this.Property = 1;
this.Method = function()
{
    alert(1);
}
}
var obj = new Aclass();
obj.Property = 2;
obj.Method = function()
{
    alert(2);
}
alert(obj.Property);
obj.Method();

 -----------------------------------------------
可以在外部使用prototype为自定义的类型添加属性和方法。

function Aclass()
{
this.Property = 1;
this.Method = function()
{
    alert(1);
}
}
Aclass.prototype.Property2 = 2;
Aclass.prototype.Method2 = function
{
    alert(2);
}
var obj = new Aclass();
alert(obj.Property2);
obj.Method2();

-------------------------------------
这个例子演示了通常的在JavaScript中定义一个类型的方法
function Aclass()
{
this.Property = 1;
this.Method = function()
{
    alert(1);
}
}
var obj = new Aclass();
alert(obj.Property);
obj.Method();


-----------------------------------------------------------------

在实例上不能使用prototype,否则发生编译错误

Object.Property = 1;
Object.Method = function()
{
    alert(1);
}
 
alert(Object.Property);
Object.Method();

posted @ 2013-07-29 14:34  令狐冲之12  阅读(362)  评论(0编辑  收藏  举报