《JS的原型和原型链》前端前端

  JS的原型和原型链算是前端面试题的热门题目了js 原型链,也是参加了几场面试,感觉好多次都被问到对原型和原型链的理解,所以今天也是索性把他给整理出来,一方面方便自己以后复习查看,另一方面也是给大家分享一下我对原型和原型链的理解。

  ES6之前中并没有引入类(class)的概念,JavaScript并非通过类而是直接通过构造函数来创建实例

  什么是原型

  每一个javascript对象(除null外)创建的时候,就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型中“继承”属性。

  这么说可能会有点抽象,举个例子吧

   function Person(age) {

        this.age = age       
    }
    Person.prototype.name = 'kavin'
    var person1 = new Person()

  就是说在通过构造函数创建实例的时候,如果去实例中找寻某个属性值的时候,如果他有的话就会直接输出,如果没有的话,就会去它的原型对象中去找。

  prototype:每个函数都有一个prototype属性,这个属性指向函数的原型对象。

  __proto__:这是每个对象(除null外)都会有的属性,叫做__proto__,这个属性会指向该对象的原型。

  constructor:每个原型都有一个constructor属性,指向该关联的构造函数。

  原型相关的知识考点一般就是围绕这张图,那怎么去验证这张图的正确性呢?

   console.log(Person===Person.prototype.constructor) // true

    console.log(person.__proto__ == Person.prototype) // true
    console.log(person.__proto__.constructor == Person) // true

  估计大家看到底四个的时候会有一些疑问了,为什么person.constructor == Person,其实还是前面所说到的,因为person没有这个属性的情况下,会从它的原型中去继承,这个时候第三个式子和第四个式子就是一样的了。

  什么时候会用到原型

  下面说一下什么时候会用到原型,还是像上边一样,举个简单的例子:

   function Person(name, age, gender) {

            this.name = name
            this.age = age
            this.gender = gender
            this.sayName = function () {
                console.log("我的名字叫" + this.name);
            }

  这和上边看起来是没什么区别的js 原型链,但是小差别就在这个sayName ,就是说每创建一个Person构造函数,在Person构造函数中,为每一个对象都添加了一个sayName方法,也就是说构造函数每执行一次就会创建一个新的sayName方法。

  一个还好,如果创建了一百个实例,一千个甚至上万个呢,这时候就体现出原型的好处了,我们可以把sayName方法放到构造函数的prototype上,这时候只需要创建一个,而且每一个实例都可以访问到。

  什么是原型链

  单的回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么假如我们让原型对象等于另一个类型的实例,结果会怎样?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层层递进,就构成了实例与原型的链条。

  简单的表达就是:上边说道如果实例没有一个属性,它会去它的原型中去找,但是如果它的原型中也没有这个属性呢,会停止寻找么,不一定,因为它的原型可能也有自己的原型,这个时候他就会去它的原型的原型中去寻找,这个时候会停下么,还是不一定,要看他原型的原型有没有原型,这样就形成了一条原型链。

  直到最后一个找不到原型时返回null

文章由官网发布,如若转载,请注明出处:https://www.veimoz.com/1819
0 评论
569

发表评论

!