精华内容
下载资源
问答
  • js的原型链

    2016-09-28 21:32:00
    之前对js的原型链和原型对象有所了解,每当别人问我什么是原型链和原型对象时,我总是用很官方(其实自己不懂)的解释去描述。有一句话说的好:如果你不能把一个很复杂的东西用最简单的话语描述出来,那就说明你...

    开篇

    之前对js中的原型链和原型对象有所了解,每当别人问我什么是原型链和原型对象时,我总是用很官方(其实自己不懂)的解释去描述。有一句话说的好:如果你不能把一个很复杂的东西用最简单的话语描述出来,那就说明你没有真正的理解。最近正在读《Javascript高级程序设计》,书中对原型对象和原型链的描述让我受益匪浅,下面仅用一个对比性的例子来说明。

    我们经常会这么写

        function Person () {
            this.name = 'John';
        }
        var person = new Person();
        Person.prototype.say = function() {
            console.log('Hello,' + this.name);
        };
        person.say();//Hello,John

    上述代码非常简单,Person原型对象定义了公共的say方法,虽然此举在构造实例之后出现,但因为原型方法在调用之前已经声明,因此之后的每个实例将都拥有该方法。从这个简单的例子里,我们可以得出:
    原型对象的用途是为每个实例对象存储共享的方法和属性,它仅仅是一个普通对象而已。并且所有的实例是共享同一个原型对象,因此有别于实例方法或属性,原型对象仅有一份。所有就会有如下等式成立:

                                person.say == new Person().say

    可能我们也会这么写

        function Person () {
            this.name = 'John';
        }
        var person = new Person();
        Person.prototype = {
            say: function() {
                console.log('Hello,' + this.name);
            }
        };
        person.say();//person.say is not a function

    很不幸,person.say方法没有找到,所以报错了。其实这样写的初衷是好的:因为如果想在原型对象上添加更多的属性和方法,我们不得不每次都要写一行Person.prototype,还不如提炼成一个Object来的直接。但是此例子巧就巧在构造实例对象操作是在添加原型方法之前,这样就会造成一个问题:
    var person = new Person()时,Person.prototype为:Person {}(当然了,内部还有constructor属性),即Person.prototype指向一个空的对象{}。而对于实例person而言,其内部有一个原型链指针proto,该指针指向了Person.prototype指向的对象,即{}。接下来重置了Person的原型对象,使其指向了另外一个对象,即
    Object {say: function}
    这时person.proto的指向还是没有变,它指向的{}对象里面是没有say方法的,因为报错。
    从这个现象我们可以得出:
    在js中,对象在调用一个方法时会首先在自身里寻找是否有该方法,若没有,则去原型链上去寻找,依次层层递进,这里的原型链就是实例对象的__proto__属性

    若想让上述例子成功运行,最简单有效的方法就是交换构造对象和重置原型对象的顺序,即:

        function Person () {
            this.name = 'John';
        }
        Person.prototype = {
            say: function() {
                console.log('Hello,' + this.name);
            }
        };
        var person = new Person();
        person.say();//person.say is not a function

    一张图让你秒懂原型链


     

    其实,只需要明白原型对象的结构即可:

        Function.prototype = {
            constructor : Function,
            __proto__ : parent prototype,
            some prototype properties: ...
        };

    总结:函数的原型对象constructor默认指向函数本身,原型对象除了有原型属性外,为了实现继承,还有一个原型链指针__proto__,该指针指向上一层的原型对象,而上一层的原型对象的结构依然类似,这样利用__proto__一直指向Object的原型对象上,而Object的原型对象用Object.__proto__ = null表示原型链的最顶端,如此变形成了javascript的原型链继承,同时也解释了为什么所有的javascript对象都具有Object的基本方法。



    文/Pursue(简书作者)
    原文链接:http://www.jianshu.com/p/aa1ebfdad661
    著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

    转载于:https://www.cnblogs.com/huenchao/p/5918036.html

    展开全文
  • js 的原型链

    2016-06-28 18:07:11
    原型链(Prototype chain)Javacript 是一门高度抽象面向对象(object-oriented)语言, 它没有类概念,但是,重用[reuse]这个理念没什么不同(某些方面,甚至比class-更加灵活),可以由prototype chain原型链来...

    从别的博客粘过来的,做个备忘录,以后好查。

    原型链(Prototype chain)

    Javacript 是一门高度抽象的面向对象(object-oriented)语言, 它没有类的概念,但是,重用[reuse]这个理念没什么不同(某些方面,甚至比class-更加灵活),可以由prototype chain原型链来实现。

    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
    };
    
    // 调用继承过来的方法
    b.calculate(30); // 60
    c.calculate(40); // 80

    原理很简单:如果在对象b中找不到calculate方法(也就是对象b中没有这个calculate属性), 那么就会沿着原型链开始找。如果这个calculate方法在b的prototype中没有找到,那么就会沿着原型链找到a的prototype,一直遍历完整个原型链。记住,一旦找到,就返回第一个找到的属性或者方法。因此,第一个找到的属性成为继承属性。如果遍历完整个原型链,仍然没有找到,那么就会返回undefined。

    注意一点,this这个值在一个继承机制中,仍然是指向它原本属于的对象,而不是从原型链上找到它时,它所属于的对象。例如,以上的例子,this.y是从b和c中获取的,而不是a。当然,你也发现了this.x是从a取的,因为是通过原型链机制找到的。

    这里写图片描述

    构造函数(Constructor)

    // 构造函数
    function Foo(y) {
      // 构造函数将会以特定模式创建对象:被创建的对象都会有"y"属性
      this.y = y;
    }
    
    // "Foo.prototype"存放了新建对象的原型引用
    // 所以我们可以将之用于定义继承和共享属性或方法
    // 所以,和上例一样,我们有了如下代码:
    
    // 继承属性"x"
    Foo.prototype.x = 10;
    
    // 继承方法"calculate"
    Foo.prototype.calculate = function (z) {
      return this.x + this.y + z;
    };
    
    // 使用foo模式创建 "b" and "c"
    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
    
      // "Foo.prototype"自动创建了一个特殊的属性"constructor"
      // 指向a的构造函数本身
      // 实例"b"和"c"可以通过授权找到它并用以检测自己的构造函数
    
      b.constructor === Foo, // true
      c.constructor === Foo, // true
      Foo.prototype.constructor === Foo // true
    
      b.calculate === b.__proto__.calculate, // true
      b.__proto__.calculate === Foo.prototype.calculate // true
    
    );

    这里写代码片

    执行上下文栈(Execution Context Stack)

    在ECMASscript中的代码有三种类型:global, function和eval。

    每一种代码的执行都需要依赖自身的上下文。当然global的上下文可能涵盖了很多的function和eval的实例。函数的每一次调用,都会进入函数执行中的上下文,并且来计算函数中变量等的值。eval函数的每一次执行,也会进入eval执行中的上下文。

    注意,一个function可能产生无限的上下文环境,因为一个函数的调用(甚至递归)都产生了一个新的上下文环境

    一个执行上下文可以激活另一个上下文,就好比一个函数调用了另一个函数(或者全局的上下文调用了一个全局函数),然后一层一层调用下去。逻辑上来说,这种实现方式是栈,我们可以称之为上下文堆栈。

    当一段程序开始时,会先进入全局执行上下文环境[global execution context], 这个也是堆栈中最底部的元素。此全局程序会开始初始化,初始化生成必要的对象[objects]和函数[functions]. 在此全局上下文执行的过程中,它可能会激活一些方法(当然是已经初始化过的),然后进入他们的上下文环境,然后将新的元素压入堆栈。在这些初始化都结束之后,这个系统会等待一些事件(例如用户的鼠标点击等),会触发一些方法,然后进入一个新的上下文环境。

    执行上下文(Execution Context)

    一个执行的上下文可以抽象的理解为object。每一个执行的上下文都有一系列的属性(我们称为上下文状态),他们用来追踪关联代码的执行进度。这个图示就是一个context的结构。

    这里写图片描述

    除了这3个所需要的属性(变量对象(variable object),this指针(this value),作用域链(scope chain) ),执行上下文根据具体实现还可以具有任意额外属性。接着,让我们仔细来看看这三个属性。

    展开全文
  • JS的原型链

    2017-06-12 16:38:48
     JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。  构造函数继承 一个对象  继承对象也有构造函数,其构造函数还去继承...

      在JavaScript 中,每当定义一个对象(函数)时候,对象中都会包含一些预定义的属性。其中函数对象的一个属性就是原型对象 prototype。

      JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。

      构造函数继承 一个对象

      继承对象也有构造函数,其构造函数还去继承其他对象

      其他对象也有构造函数,构造函数还去继承其他对象

      其他对象也有构造函数,构造函数还去继承其他对象

      。。。。。

      以上继承形成了一个继承的链条,称为原型链,原型链的顶端是Object

      对象访问一个成员顺序:

      ① 对象本身获取

      ② 对象构造函数里边获取

      ③ 构造函数继承对象本身获取

      ④ 构造函数继承对象的构造函数里边获取

      。。。。。。

      直到找到Object成员为止。

      例如constructor、hasOwnPrototype、isPrototypeOf等等都是原型链顶端Object的成员。

      

    JS的原型链

      

    JS的原型链
    展开全文
  • 深入浅出的理解js的原型链

    什么是原型链

    JavaScript是面向对象的,每个实例对象都有一个__proto__属性,该属性指向它的原型对象,这个实例对象的构造函数有一个原型属性prototype,与实例的proto属性指向同一个对象。当一个对象在查找一个属性的时候,自身没有就会根据__proto__向它的原型进行查找,如果都没有,则向它的原型的原型继续查找,直到查到Object.prototype.proto_为null,这样也就形成了原型链。

    1、 简单看一下使用构造函数创建对象的原型体现

    在这里插入图片描述
    字写的太难看,简单看下,嘿嘿
    js通过new 构造函数生成一个实例对象,实例对象的__proto__ 指向原型对象,构造函数通过prototype指向原型对象,而原型对象通过cunstructor指回构造函数
    在这里插入图片描述通过实例对象的__proto__和构造函数的prototype做比较我们得到的上面如图所示的原型体现,从而衍生出原型链

    通过图示以及代码实例我们清楚的认识到通过构造函数生成的实例对象可以通过__proto__指向到构造函数的原型对象。

    但是我们也知道通过实例对象可以访问toString/toValues/isPrototypeOf方法,虽然在构造函数中我们没有往原型对象中添加这些方法,所以我们得到了所有函数的原型默认是 Object的实例,那么由此可以得到如下图所示
    在这里插入图片描述
    那我们就知道构造函数为啥能访问oString/toValues/isPrototypeOf这些方法了,因为这些方法挂载在Object的原型对象上,而所有函数的原型默认是 Object的实例,也就是说我们能通过一条链能访问到这些原型方法,这条链就是原型链。如下图所示
    在这里插入图片描述

    这就是通过构造函数生成的一条原型链,原型链的找到最顶级为null.
    此次分享就到这里,希望能帮到大家
    本人的字有点丑,好久不写字了,见谅!!!!!

    展开全文
  • 一.js的原型链 原型链是JS特有的一种继承机制 原型链会涉及到___proto___,prototype 原型链的顶端就是null 应用场景:继承 优点:把相同或类似的方法写在原型上,方便实例化对象复用 缺点:不好理解,通常只前端人才...
  • js的原型链个人收获

    2018-06-25 11:14:45
    最近在看js的原型链,自己也遇到很多问题,也去看了很多关于这些的博客,看的云里雾里。所以也想写篇博客和大家分享下自己的收获和遇到的一些问题。 首先,来说下js的对象: 普通对象有__proto__属性(隐形原型)...
  • 简谈JS的原型链和作用域链

    千次阅读 2017-07-18 13:00:43
    谈起js的原型链和作用域链,我觉得还是和图结合起来说比较明白,手绘了一些图片,图片看起来虽然比较丑,但是结合起来理解地应该比较清楚
  • js的原型链理解

    2015-09-06 17:10:25
    1.常见的对象的原型链 2.实例化的对象的原型链 3.instanceof的实现原理
  • function Person(){} var person=new Person(); var Father=function(){}
  • 怎么理解js的原型链继承?

    千次阅读 2019-11-24 14:47:15
    js的es6语法出来之前,我们想实现js的继承关系,需要借助于原型链。之前的文章,我有讲过原型和原型链的概念。在这,再重新回顾一下。 js中万物皆对象,每个对象都有一个隐式原型 __proto__ ,指向创建它的构造...
  • JS的原型链 - 继承的一种实现

    万次阅读 2020-06-04 14:35:10
    ES5继承(原型链继承)中,子类和父类 __proto__ 都指向 [Function] ES6继承(类 extends ),子类 __proto__ 会指向父类, 阮一峰 : 子类必须在 constructor 方法中调用 super 方法,否则新建实例时会报错。这...
  • 原型链: *** 查找方式: 对象实例 -> 构造函数的原型对象prototype -> Object的原型对象prototype -> undefined
  • 原型链 借用构造函数 组合继承 原型式继承 寄生式继承 寄生组合式继承
  • js的原型链以及继承

    2019-06-07 13:59:33
    创建一个函数时候会生成一个对象,这个对象就叫做原型对象(prototype),所有原型对象会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数指针。 二:prototype与__proto_ _...
  • 原型:每个构造方法中都有一个prototype属性,该...它指向它构造函数的prototype原型对象,而prototype原型对象又具有一个自己的原型对象,就这样层层向上直到Object对象的原型prototype。 这个路径就是原型链。 ...
  • 认识原型链 JS的构造函数 在ES6之前没有class关键字,使用构造函数来实例化一个对象,构造函数方式方法首字母需要大写,如下: function GetMsg(name, age){ this.name = name; this.age = age; } .....
  • 你清楚JS的原型链

    2020-06-06 20:57:30
    简单理解:prototype就是通过调用构造函数而创建的那个对象实例的原型对象,可以让所有对象实例共享它所包含的属性和方法。 function Person() {} Person.prototype.name = "Helen"; Person.prototype.age = 23; ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 7,732
精华内容 3,092
关键字:

js的原型链