原来并不是所有对象都有原型
学习了这么久的JavaScript,看到这张图终于对原型以及原型链理解透彻了!
前言
在JavaScript这门充满魔力的语言中,原型和原型链是两个核心而又略显神秘的概念,它们支撑起了JavaScript的继承机制,让对象之间的属性和方法得以共享。本文将深入浅出地解析原型、原型链以及隐式原型的奥秘,揭开JavaScript面向对象编程的一角。
JavaScript中的原型与原型链探秘
原型:对象的公共祖先
在JavaScript中,每个函数都会自动获得一个名为prototype
的属性,这个属性是一个对象,可以理解为通过该函数构造的所有实例对象的公共原型对象。当我们使用构造函数创建新对象时,新对象会自动链接到这个原型对象,从而继承原型上的属性和方法。这便是原型的核心作用——实现属性和方法的复用与继承。
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log(this.name);
};
let person1 = new Person("一颗苹果OMG");
person1.sayName(); // 输出: 一颗苹果OMG
在上述代码中,sayName
方法定义在Person.prototype
上,所有通过Person
构造函数创建的实例都可以访问到这个方法。
原型链:属性查找的林荫小路
当访问一个对象的属性或方法时,如果该对象本身没有定义这个属性或方法,JavaScript引擎不会立即报错,而是会沿着一条链——即原型链继续寻找。这条链的起点是当前对象,终点通常是Object.prototype
(所有对象的最终原型),途中经过的对象都是通过各自的__proto__
属性链接起来的。
__proto__
,即对象的隐式原型,指向创建该对象的构造函数的prototype
。正是通过这个隐式链接,对象能够访问到其原型上的属性和方法,形成了所谓的原型链。
隐式原型与显式原型的关系
- 显式原型(prototype) :存在于函数对象上,用于指定由该构造函数创建的实例对象的原型。
- 隐式原型(__ proto__) :存在于每一个普通对象上(包括函数对象),指向创建该对象的构造函数的原型对象。
两者的关系可以用一句话概括:对象的__proto__
指向构造该对象的函数的prototype
。
所有对象都有原型吗?
几乎所有的JavaScript对象都通过原型链连接在一起,形成一个巨大的对象网络,但也有例外。使用Object.create(null)
创建的对象就是一个特例,它没有原型链,因为它的__proto__
为null
,意味着这个对象是一个孤立的个体,不继承任何属性或方法。
结语
JavaScript的原型和原型链机制是其面向对象编程的核心,它通过动态的属性查找规则,实现了对象之间的继承和属性共享。而Object.create(null)
的使用,则提醒我们,即便在原型无所不在的世界里,也存在着特立独行的例外。
转载自:https://juejin.cn/post/7377683176229126171