原型链的查找规则

本文介绍了JavaScript中原型对象与__proto__属性的概念,解释了如何利用它们来节省内存,并详细阐述了原型链的查找规则。

要了解原型链的查找机制,必须了解以下2个概念:

原型对象(prototype)与原型(__proto__)

二者之前的关系:实例对象的__proto__等于创建这个实例对象的构造函数的原型对象.

一.原型对象

所有函数都有原型对象prototype,可以用来节约内存,若要将所有对象的公共方法或属性抽离出来,减少内存占用,那么可以将这些属性和方法放到原型对象上面去,因为原型对象上面所有的属性和方法都是共享的,所有对象实例都可以访问,原型对象只有一个地址,因此可以节约内存.实际上,原型对象也是由顶级对象Object,new出来的实例对象,Object(也是一个内置构造函数),且所有原型对象都有constructor-构造函数属性.

二. __proto__属性

所有对象都有一个属性__proto__,因为原型对象一定有constructor属性,则对象的__proto__一定也有constructor属性,且constructor属性值就是构造函数本身.

可以参考以下图片了解构造函数,实例对象与原型对象三者之间的关系...

 三.原型链的查找规则

1.当访问一个对象的属性或方法时,首先查找这个对象自身有没有该属性

2.如果没有就查找它的原型对象,也就是__proto__指向的prototype原型对象

3.如果还没有就查找原型对象的原型对象(Object的原型对象)

4.依此类推直到找到Object为止(null)

参考此图:

 

<think>好的,用户现在需要我解释原型和原型链。之前他们问过闭包,现在转向原型相关的问题,可能是在学习JavaScript的核心概念。我需要确保他们理解这两个概念,以及它们在JavaScript中的作用。 首先,用户可能已经了解闭包,现在想深入对象和继承机制。原型和原型链JavaScript中实现继承的基础,但很多初学者会觉得这部分有点抽象。我得用简单易懂的语言,结合例子来说明。 原型是什么?每个JavaScript对象都有一个原型对象,从中继承属性和方法。构造函数通过prototype属性指向原型,而实例通过__proto__访问原型。这部分需要分点解释,避免混淆。 原型链呢?当访问对象的属性时,如果对象本身没有,就会沿着原型链向上查找,直到找到或到达null。这个过程就是原型链的机制。比如实例的原型是构造函数的prototype,而构造函数的prototype本身可能有自己的原型,形成链式结构。 要注意用户可能的疑问点,比如构造函数和实例的关系,__proto__和prototype的区别,以及如何通过原型链实现继承。可能需要用例子来演示,比如Person构造函数,实例person如何访问原型上的方法。 还要提到现代JavaScript中推荐使用Object.getPrototypeOf而不是直接访问__proto__,以及ES6的class语法糖背后还是基于原型链的。这样用户能理解新旧方法的不同,但本质是一样的。 用户可能的问题包括为什么要有原型链,和类继承有什么不同,或者如何自己实现继承。这时候可能需要补充原型继承的优点,比如灵活、节省内存,以及可能的缺点,比如理解成本高。 另外,注意用户之前的问题是关于闭包的,可能他们正在系统学习JavaScript的核心概念,所以需要确保解释清晰,结构合理,帮助他们建立知识体系。最后总结原型链的重要性,比如在继承、方法共享、instanceof机制中的应用。</think>--- ### 一、原型(Prototype)的本质 **每个 JavaScript 对象都有一个隐藏的 `[[Prototype]]` 属性**,指向它的原型对象(即父对象)。 通过原型,对象可以继承其他对象的属性和方法。 --- ### 二、关键概念对应关系 | 角色 | 描述 | 代码表示 | 实际指向 | |---------------|--------------------------|-------------------|----------------------| | 构造函数 | 创建对象的模板 | `function Foo(){}`| - | | `prototype` | 构造函数的原型属性 | `Foo.prototype` | 实例的原型对象 | | 实例 | 构造函数创建的具体对象 | `const obj = new Foo()` | - | | `__proto__` | 实例的原型引用(已弃用) | `obj.__proto__` | `Foo.prototype` | | `Object.getPrototypeOf()` | 获取对象的原型(推荐) | `Object.getPrototypeOf(obj)` | 同 `__proto__` | --- ### 三、原型链(Prototype Chain)的运作 1. **查找规则**: 当访问对象属性时,会按以下顺序查找: **对象自身属性 → 原型对象属性 → 原型的原型属性 → ... → `null`** 2. **链式结构演示**: ```javascript // 1. 定义构造函数和原型方法 function Person(name) { this.name = name; } Person.prototype.sayHi = function() { console.log("Hi, I'm " + this.name); }; // 2. 创建实例 const person = new Person("Alice"); // 3. 属性查找路径 person.sayHi(); // 触发原型链查找: // person → Person.prototype → Object.prototype → null ``` 3. **原型链终点**: 所有对象的原型链最终都指向 `Object.prototype`,而 `Object.prototype.__proto__` 是 `null`。 --- ### 四、手绘图解原型链 ``` 实例 (person) │ ▼ __proto__ Person.prototype 原型对象 │ ↑ constructor │ │ └─────────────────────┘ ▼ __proto__ Object.prototype 顶级原型 │ ▼ __proto__ null ``` --- ### 五、原型链的核心作用 1. **实现继承**: ```javascript function Student(name, grade) { Person.call(this, name); // 继承属性 this.grade = grade; } Student.prototype = Object.create(Person.prototype); // 继承方法 Student.prototype.study = function() { /*...*/ }; ``` 2. **方法共享**: 所有实例共享原型上的方法,节省内存(与每次创建实例都复制方法对比)。 3. **动态修改**: 修改原型会立即影响所有实例: ```javascript Person.prototype.sayBye = function() { console.log("Bye!"); }; person.sayBye(); // 所有实例均可调用 ``` --- ### 六、关键特性 - **`instanceof` 的原理**: 检查构造函数的 `prototype` 是否在对象的原型链上。 - **现代替代方案**: ES6 的 `class` 语法本质仍是原型链(语法糖),如: ```javascript class Person { constructor(name) { this.name = name; } sayHi() { console.log(`Hi, I'm ${this.name}`); } } // sayHi 实际存储在 Person.prototype 上 ``` --- ### 七、总结要点 | 概念 | 核心描述 | 典型应用场景 | |-----------|---------------------------------------|----------------------| | 原型 | 对象继承属性和方法的来源 | 方法共享、继承实现 | | 原型链 | 通过 `__proto__` 链接的多级查找机制 | 属性查找、继承体系 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值