解决方案 »

  1.   

    类似class型语言里的extends,B extends A,C extends B。B继承A,C继承B。原型链就是用来实现这种链式继承关系的。每个对象都有一个看不见的属性,那就是__proto__,有时候也用中括号表示,记作[prototype],这个__proto__和function的prototype是有关系的,一个对象的__proto__属性是指向这个对象的构造器的原型的,也就是说:obj.__proto__ === obj.constructor.prototype; // true
    不知道LZ对function的prototype和obj的__proto__有没有认识,以及,new操作到底干了什么。先看看这个:function A(){};
    A.prototype.test = "someValue";
    var a = {};
    a.constructor = A;
    a.__proto__ = A.prototype;
    a.test; //"someValue"其实,new操作符做的工作,大致如下:function A(){};
    A.prototype.test = "someValue";
    var a = new A();
    a.test; //"someValue
    a instanceof A; //true
    A.prototype.isPrototypeOf(a); //true
    这里再说own property。故名思议,就是固有属性的意思。先看看这个:var a = {};
    a.toString(); // "[object Object]"
    'toString' in a; // true
    a.hasOwnProperty('toString'); //false
    a.toString = function(){return "a";};
    a.toString(); // "a"
    a.hasOwnProperty('toString'); //true这说明,a对象确实有toString方法,但是'toString'并不是a对象的固有属性,当给a对象注册一个toString属性后,toString把之前的来自Object的方法屏蔽了,并且hasOwnProperty也返回了true。那我们来分析一下使用a.toString的时候,js解析器是如何查找的。首先,在a的固有属性中查找toString方法,如果找到,则直接返回,使用该值即可。如果未找到,对,未找到,那怎么办呢?于是,解析器会继续在a的__proto__中查找toString。如果还未找到怎么办?嘿嘿,别忘了__proto__这个属性的本质也是一个对象,所以a.__proto__也会有__proto__属性。于是就在__proto__的__proto__中查找toString。直到,直到,直到什么?那这样岂不会死循环?No,js中有一个对象,他没有原型,那就是Object.prototype,也就是(new Object()).__proto__。({}).__proto__; //Object {}
    ({}).__proto__.__proto__; //null于是,这个递归过程找到了出口。很多js环境,都不允许直接操作__proto__这个属性,因此,js中书写继承看起来相当诡异。function A(){}
    A.prototype.a = "valueFromA";
    function B(){}
    B.prototype = new A();
    //B.prototype.__proto__ = A.prototype;
    //B.prototype = Object.create(A.prototype);
    B.prototype.b = "valueFromB";
    var inst = new B();
    inst.a; //valueFromA
    inst.b; //valueFromB;
    B.prototype = new A();这一句着实让人费解,但是知道new操作的背后,如果我们可以操作__proto__,那么,B.prototype.__proto__ = A.prototype,这一句就语义清晰多了。当然,用最新的Object.create方法,
    B.prototype = Object.create(A.prototype),那就更明白了,从A的prototype构造B的prototype,和B extends A已经相差不远了。
      

  2.   

    function A() {}function B() {}B.prototype = new A();
      

  3.   

    js原型链原理看图说明当初ECMAscript的发明者为了简化这门语言,同时又保持继承的属性,于是就设计了这个链表。 如果在数据结构中学过链表,链表中有一个位置相当于指针,指向下一个结构体。于是乎__proto__也一样,每当你去定义一个prototype的时候,相当于把该实例的__proto__指向一个结构体,那么这个被指向结构体就称为该实例的原型。 文字说起来有点儿绕,看图说话 
    var foo = { 
    x: 10, 
    y: 20 
    }; 
    当我不指定__proto__的时候,foo也会预留一个这样的属性, 如果有明确的指向,那么这个链表就链起来啦。 很明显,下图中b和c共享a的属性和方法,同时又有自己的私有属性。 __proto__默认的也有指向。它指向的是最高级的object.prototype,而object.prototype的__proto__为空。 var a ={ 
    x: 10, 
    calculate: function (z)

    return this.x + this.y + z 

    }; var b = { 
    y: 20, 
    __proto__: a 
    }; var c = { 
    y: 30, 
    __proto__: a 
    }; // call the inherited method 
    b.calculate(30); // 60 理解了__proto__这个属性链接指针的本质。再来理解constructor。 当定义一个prototype的时候,会构造一个原形对象,这个原型对象存储于构造这个prototype的函数的原形方法之中。function Foo(y){ 
    this.y = y ; 
    } Foo.prototype.x = 10; Foo.prototype.calculate = function(z){ 
    return this.x+this.y+z; 
    }; var b = new Foo(20); alert(b.calculate(30)); 
      

  4.   

    上面引用一篇文章现在说说我自己的理解原型链就好比通过__proto__与prototype之间的关系进行函数之间的连接组成的一天锁链
      

  5.   

    推荐看看
    http://blog.csdn.net/siczxw555/article/details/6138428 浅析JS原型链,这篇文章讲得浅显易懂
    http://dmitrysoshnikov.com/ecmascript/javascript-the-core/ 这篇文章的图不错我觉得应该记住的是:
     如果构造器(函数)有个原型对象A,则由构造器构造的对象实例都复制于这个原型对象A。对象实例是没有原型的,也就是没有prototype这个属性,构造器(函数)才有原型对象,原型对象的constructor属性会指向构造器(函数)。所以,记住:对象实例只是构造于某个原型,而不拥有某个原型。但是,每个对象在内部会有个__proto__属性,指向构造其的原型,由这个属性维护的被称为内部原型链,它是js引擎支持js原型继承机制所需要的。而由prototype和constructor维护的被称为外部原型链,供我们写js代码回溯用。
      

  6.   

    你要这样想prototype 可能也有他自己的prototype
    要么空要么有
    有的话就成了一个链
      

  7.   

    当js中的引用类型(类)需要继承其他引用类型(类)的时候,不能像其他语言一样靠关键字extend(如class A extends B 类A继承类B)来实现,而是要靠主要两个步骤实现:1.实例化要继承的引用类型(父类);
    2.将自己的原型即prototype属性指向第一步中得到的实例。如:A要继承B
    1.var c=new B();
    2.A.prototype=c;
    那么此时,当实例化A的时候(var d=new A()),实例d的原型(prototype属性)指向c,而c的原型(prototype)又指向B.prototype,z这就形成了实例与原型的链条。这就是原型链的基本概念。 
      

  8.   

    楼上几个发的链接都不错,我在补充几个:
    http://blog.csdn.net/a569171010/article/details/7467514
    http://www.iteye.com/topic/195409
    http://stauren.net/log/eggxfygvg.html
    http://blog.endlesscode.com/2010/01/23/javascript-prototype-chain/
    http://www.cnblogs.com/ziyunfei/archive/2012/10/15/2723963.htmlhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/JavaScript_Overview?redirectlocale=en-US&redirectslug=JavaScript%2FGuide%2FJavaScript_Overview
     
    https://developer.mozilla.org/zh-CN/docs/JavaScript/Guide
      

  9.   

    简单来说原型__proto__和prototype的区别:
    __proto__:所有对象都有,prototype只有函数有。
      

  10.   

    function Foo(y) {//等价于 var Foo=new Function('y','this.y=y');
      this.y = y;
    }
    Foo.prototype.x = 10;
    Foo.prototype.calculate = function (z) {
      return this.x + this.y + z;
    };
    var b = new Foo(20);
    var c = new Foo(30);
    b.calculate(30); // 60
    c.calculate(40); // 80
    console.log(
      b.__proto__ === Foo.prototype, // true
      c.__proto__ === Foo.prototype, // true
      b.constructor === Foo, // true
      c.constructor === Foo, // true
      b.prototype===undefined,
      c.prototype===undefined,
      Foo.constructor===Function,
      Foo.prototype,
      Foo.__proto__===Function.prototype,
      Foo.prototype.constructor === Foo, // true
      Foo.prototype.__proto__===Object.prototype,
      Function.__proto__,//是一个空函数
      Object.prototype.__proto__===null,
      b.calculate === b.__proto__.calculate, // true
      b.__proto__.calculate === Foo.prototype.calculate // true);