这次你还不懂原型和原型链,请出门右转

233 阅读3分钟

关于 js原型原型链 这个知识点,不光是 面试官问的频率高,我们平时的开发当中,那也是举足轻重啊。一个前端不懂原型和原型链,就好比那无源之水,无本之木。

思考

请想下平常写代码常用的方法如map、filter、every、some....等等,这些方法从哪里来的?

image.png

这些方法其实就是通过原型链共享来的 image.png

原型

原型是 Javascript 中的继承的基础,所有 JavaScript 对象都从原型继承属性和方法, JavaScript 的继承就是基于原型的继承。

prototype
  1. 每一个函数(通常指构造函数),都有一个属性 prototype , 就是原型(显示原型)。普通对象(例如构造函数 new 出来的实例对象)是没有这个属性的(这里为什么说普通对象呢,因为JS里面,一切皆为对象,所以这里的普通对象不包括函数对象)。它是构造函数原型对象;这个我在之前的文章里也说过,如果有不了解的小伙伴可以看这儿 (构造函数的特点下面的第7点)

  2. 这个原型(prototype)的值是一个对象(object

就长这个样子
 {
    constructor: xxx,
        show: function () { }  // 这里可以自己添加方法哟!!!
    __proto__: yyy,
}

image.png

  1. 添加到原型上的所有方法和属性,被所有 new 出来的实例对象共享。
function Person(name, age) {
    this.name = name;
    this.age = age;
};
Person.prototype.show = function (params) {
    return '我show' + params
}
// console.log(Person.prototype)
const p1 = new Person('张三', 22);
const p2 = new Person('李四', 20);
console.log('p1.show()', p1.show('蒂花之秀'));
console.log('p2.show()', p2.show('造化钟神秀'));
console.log('p1.__proto__=== Person.prototype',p1.__proto__=== Person.prototype);
console.log('Person.prototype.constructor === Person',Person.prototype.constructor === Person);

image.png 4. 每一个实例对象,都有一个属性 __proto__ , 叫隐式原型,指向(等于)自己构造函数的显示原型 image.png 5. 原型上的 constructor 属性,指向构造函数本身 image.png

原型链

JavaScript 通过构造函数 来生成实例。但是有一个问题,在构造函数中通过 this 赋值的属性或者方法,是每个实例自己的的实例属性以及实例方法,他们之间无法共享公共属性(这儿就不举例了,之前的文章已经讲过了,不清楚的小伙伴请移步这儿)。所以设计出了一个原型对象,来存储这个构造函数的公共属性以及方法。原型可以一直追溯往上,形成一个链条式的查找路径,这就是原型链,所以这就是原型链设计的初衷

原型链的基本作用就是属性共享,如果没有原型链,像一些常用的方法例如split,join这些,每次使用前都得重新定义一遍。

  1. 构造函数的显示原型(prototype),也是一个普通的 object 对象,也有自己的 __proto__ 属性,指向自己构造函数(Object)的显示原型prototype
Person.prototype.__proto__ === Object.prototype   // true
Object.prototype.constructor === Object    // true
  1. Object.prototype 也是一个普通对象,也有__proto__, 指向 null

    Object.prototype.__proto__===null image.png

  2. 对象方法访问优先级

先自己 ===>沿着原型链往上 (找到就结束,如果直到 Object.prototype 都没有,就不存在 !!!) 先自己,找到就返回 image.png

自己没有就往上找父级,找到就返回,没有就继续往上 image.png

继续往上 image.png

这就是原型和原型链 再给一张草图(StudentPerson 的子类 不明白 继承 的可以移步这儿,这篇文章就不再赘述了) image.png