前言
JavaScript作为前端入门三件套之一,也是前端求职的必会知识,重要性不言而喻。
这个系列分享个人学习JavaScript的记录,和大家一起学习讨论。
下面介绍关于原型&原型链的相关重要知识点。
1、构造函数创建对象
javascript
function Student() {
}
var student = new Student();
student.name = 'xiaoming';
console.log(student.name) // xiaoming
var student2 = new Student();
student2.name = 'xiaohong';
console.log(student.name) // xiaohong
在这个案例中,Student 就是一个构造函数,用 new 创建了实例对象 student和studen2。
2、prototype
2.1、prototype属性的定义
在 JavaScript 中,
prototype
是一个特殊的属性,它存在于所有函数对象上。当你使用new
关键字调用一个函数来创建一个新对象时,这个新对象会有一个内部属性[[Prototype]]
,通常通过__proto__
或Object.getPrototypeOf()
来访问。这个内部属性指向了函数的prototype
属性。
2.2、 prototype属性的作用
prototype
属性的主要作用是实现继承。在prototype
上添加属性或方法时,所有通过该函数创建的实例都会共享这些属性和方法。
2.3、案例分析
javascript
function Student() {
}
//Student 是一个构造函数,用于创建新的对象。
Student.prototype.name = 'xiaoming';
//在 Student 的 prototype 上添加了一个属性 name,其值为 'xiaoming'。所有通过 Student 创建的实例都会共享这个 name 属性。
var student1 = new Student();
var student2 = new Student();
//使用 new Student() 创建了两个实例 student1 和 student2。
console.log(student1.name) // xiaoming
console.log(student2.name) // xiaoming
//由于 student1 和 student2 的原型链上都指向了 Student.prototype,而 Student.prototype 上有一个 name 属性,因此它们都能访问到 name 属性的值 'xiaoming'。
student1.__proto__
和student2.__proto__
:这两个实例的[[Prototype]]
属性都指向了Student.prototype
。
构造函数 与实例原型 之间的关系图如下:
3、proto
javascript
function Student() {
}
var student = new Student();
console.log(student.__proto__ === Student.prototype); // true
关系图:
是否有原型指向构造函数或者实例呢?
4、constructor
原型并不能指向实例,因为一个构造函数可以生成多个实例;
但原型可以指向构造函数 :constructor, 每个原型都有一个constructor属性指向相关的构造函数。
javascript
function Student() {
}
console.log(Student === Student.prototype.constructor); // true
5、实例与原型
当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性(向上查找 ),如果还查不到,就去找原型的原型,一直找到最顶层为止。
javascript
function Student() {
}
Student.prototype.name = 'xiaoming';
var student = new Student();
student.name = 'xiaohong';
console.log(student.name) // xiaohong
delete student.name;
console.log(student.name) // xiaoming
这里的案例,给实例对象 student 添加了 name 属性,当打印student.name的时候,结果为xiaohong。
当删除了student的 name 属性时,我们尝试读取student.name,从 student 对象中找不到 name 属性,这时候就会向上查找,从 student 的原型也就是 student.proto,也就是Student.prototype中查找,结果为xiaoming。
6、原型的原型
如果我们在实例的原型上还没有找到属性呢?这时候又向上查找(原型的原型),那原型的原型又是什么?
javascript
var obj = new Object();
obj.name = 'xiaoming'
console.log(obj.name) // xiaoming
原型对象就是通过 Object 构造函数生成的。关系图:
7、原型链
Object.prototype的原型又是什么?
所有原型链的末端都是
null
。例如,普通对象的原型链最终会指向Object.prototype
,而Object.prototype
的原型是null
。
javascript
//结合上述的例子
console.log(Object.getPrototypeOf(student1)); // Student.prototype
console.log(Object.getPrototypeOf(Student.prototype)); // Object.prototype
console.log(Object.getPrototypeOf(Object.prototype)); // null
总结
函数的
prototype
属性:
每个函数都有一个
prototype
属性,它是一个对象。通过
new
关键字调用函数创建对象时,新对象的[[Prototype]]
会指向该函数的prototype
属性。对象的
[[Prototype]]
属性:
每个对象都有一个内部属性
[[Prototype]]
,通常通过__proto__
或Object.getPrototypeOf()
来访问。这个属性指向了该对象的原型对象。
原型链的查找机制:
- 当访问一个对象的属性或方法时,如果该对象本身没有这个属性或方法,JavaScript 会沿着原型链向上查找,直到找到为止,或者到达原型链的末端(
null
)。共享属性和方法:
- 通过在
prototype
上添加属性和方法,所有通过该函数创建的实例都可以共享这些属性和方法。
如果你喜欢这个系列的内容,请多多点赞、收藏,期待你的留言评论~
关注我,获取最新文章消息。