欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

前端面试题:JS中的原型和原型链

程序员文章站 2024-03-23 21:02:34
...

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

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

什么是原型

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

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

function Person(age) {
    this.age = age       
}
Person.prototype.name = 'kavin'
var person1 = new Person()
console.log(person1.name)  //kavin

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

前端面试题:JS中的原型和原型链

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
console.log(person.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);
        }
    }

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

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

什么是原型链

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

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

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

前端面试题:JS中的原型和原型链