一张图解释清楚JS中的原型、原型链(高频面试考点) |
您所在的位置:网站首页 › 原型链例子 › 一张图解释清楚JS中的原型、原型链(高频面试考点) |
原型 原型链 下面这张图是一位小伙伴面试前端岗位,被问到JavaScript的原型和原型链的知识点,没有答出来,面试结束之后,HR发给他的。我觉得这张图把prototype和__proto__解释的很好,在这里分享给大家,并为大家推导一下整幅图: ![]() prototype:原型 __proto__:原型链 2. 从属关系prototype从属于函数,是函数的一个原型属性(也叫prototype属性),是一个对象;__proto__是对象的属性,它本身也是一个对象。对象的__proto__属性保存着创建该对象的构造函数的prototype属性。每个对象(除了null)都默认有__proto__属性。 从属关系很重要,一定要搞明白! 3. 验证从属关系上一期推文我们已经知道,用class关键字创建出来的类其实也是一个函数: class Person {} console.log(typeof Person); // function既然类是函数,那么它一定有自己的prototype属性: console.log(Person.prototype); // {constructor: ƒ}用Person类创建一个对象,验证该对象有__proto__属性,并且根据从属关系,验证等于其构造函数(此处为Person类)的prototype属性: const p = new Person(); console.log(p.__proto__); // {constructor: ƒ} console.log(p.__proto__ === Person.prototype); // true 4. 解释一下constructor属性延用上面的例子,我们打印p.__proto__对象,会看到它的第一个属性就是constructor属性,并且这个constructor属性指向创建这个对象的类: ![]() 我们展开constructor属性: ![]() 发现constructor属性里面还有一个prototype属性,而且这个prototype属性刚好等于p.__proto__,如果我们再展开它: ![]() …… 经过不断的展开、观察,不难发现,对象p.__proto__的constructor属性指向构造它的类,而这个constructor属性的prototype属性又等于p.__proto__,也就是说,constructor属性和prototype属性是一对相反的方向,代码验证: console.log(p.__proto__.constructor); // class Person {} console.log(p.__proto__.constructor.prototype); // {constructor: ƒ} console.log(p.__proto__.constructor.prototype.constructor); // class Person {} console.log(p.__proto__.constructor.prototype.constructor.prototype); // {constructor: ƒ} ……所以根据constructor属性,我们可以推测是什么构造出来的这个对象。 5. 验证一个想法有了上边的基础,我们打印一下Person.prototype.__proto__: ![]() 我们发现,Person.prototype.__proto__的constructor属性指向的是Object,那么这段代码自然自然成立: console.log(Person.prototype.__proto__.constructor === Object); // true // 有了刚刚讲过的constructor属性的经验,我们可以得到: console.log(Person.prototype.__proto__ === Object.prototype); // true我们只需要再记住JS中这样的一个规定: Object.prototype.__proto__ = null; // 原型链的最尾端为null我们就基本解释左半张图: ![]() 相信大家都知道,在JS中,一切皆为对象。函数也不例外,在JS中,每一个函数实际上都是一个函数对象。既然知道了函数也是对象,函数也一定有__proto__属性。延用上边的例子: console.log(typeof Person); // function console.log(Person.__proto__); // ƒ () { [native code] }展开Person.__proto__: ![]() 因为在JS的底层,Person类是由new Function()而来,即: console.dir(Person.__proto__.constructor); // ƒ Function()则: console.dir(Person.__proto__ === Function.prototype); // true又因为Function的类型也是函数: console.log(typeof Function); // function所以我们可以推出: console.dir(Function.__proto__ === Function.prototype); // true之前说过,一个对象的__proto__属性和prototype属性均为对象,且对象默认情况下都有自己的__proto__属性,我们打印一下Function.prototype.__proto__: ![]() 就是说: console.log(Function.prototype.__proto__.constructor === Object); // true从而得到: console.log(Function.prototype.__proto__.constructor.prototype === Object.prototype); // true抵消掉constructor.prototype之后得到: console.log(Function.prototype.__proto__ === Object.prototype); // true至此,文章开头的原型原型链图,解释(推导)完毕。 (完) |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |