zoukankan      html  css  js  c++  java
  • 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();

  • 相关阅读:
    phpcms v9 更改首页
    不是技术牛人,如何拿到国内IT巨头的Offer
    超实用的PHP代码片段!
    Android 中的 Service 全面总结
    近期十大优秀jQuery插件推荐
    DIOCP之编写第一个应用程序(二)
    DIOCP之编写第一个应用程序(一)
    DIOCP之DEMO学习顺序及达到要求
    DIOCP之EchoServer分析
    DIOCP之数据接收事件
  • 原文地址:https://www.cnblogs.com/qylbg/p/3222890.html
Copyright © 2011-2022 走看看