原型

1,定义:原型是function对象的一个属性,它定义了构造函数制造出对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。

原型就相等于构造函数所要构造的对象的父亲,比如上面person里虽然是空的,但是可以访问name属性,这就是一种继承、

可以访问原型中的对象,也可以访问自己的对象

原型的作用:

利用原型的特点和概念,可以提取共有属性,减少代码重复执行

原型的增删改查:

查看:直接点就好

改:

发现person对象中增加了lastName属性,返回的也是person中的lastName属性。

所以,你只能像下面那样写:

增加:

删:

切记:

这是删不掉的,系统会认为你是在删除一个没有的元素,所以才会返回true,如下

原型还可以用下面这种表示方法

--------------------------------------------------------------------------------------------------------

发现键入了person.constructor之后返回了person的构造函数,(constructor会返回构造这个对象的构造函数)

Person.prototype.constructor暂时没有什么用

那么,这个constructor是从哪里来的?我们自己没有设置,看下面:

那么,我们现在更改constructor

发现也会更改

-----------------------------------------------------------------------------------------------------------------

我们最开始把name:abc保存到了原型里面,现在在proto里面找到了name : abc,所以proto就是用来保存原型的

在说构造函数构造对象时的三段式:

先建立一个空的this对象,

然后执行this.xxx = xxx;

最后返回this,

其实最先创造的this对象并不是空的,里面就有: __proto__ : Person.prototype,它起到一个连接的作用,如果在自己的对象空间中没有找到对应的元素就回沿着__proto__的值去查找,即到原型中查找

再看下面:

我们改变proto之后就会发现person.name值也进行更改了

三段式(new触发)第一段建立一个this对象,内部__proto__指向这个时候的Person.prototype,然后接下来Person.prototype改变了自己的内容,但是这个时候他是通过重新申请一个空间来改变的,同时__proto__的指向并没有发生变化,所以还是sunny(原理就是原始值和引用值)

就和下面一样

这个是由于在new 执行的时候才会有this对象出来

 

<think>好的,我现在需要帮助用户理解JavaScript中的原型原型链。用户要求详细的示例和解析,所以我得先理清楚这两个概念的基本定义和它们之间的关系。首先,原型是什么?根据引用[1],原型是每个JavaScript对象都有的一个内部属性,用于实现属性和方法的继承。构造函数有prototype属性,指向原型对象,而实例对象通过__proto__访问原型。 接下来,原型链是怎么形成的呢?引用[2]提到,当访问一个对象的属性时,如果对象本身没有该属性,就会沿着原型链向上查找,直到找到或到达原型链末端(null)。这个过程是通过每个对象的__proto__连接起来的链条。例如,实例的__proto__指向构造函数的prototype,而构造函数的prototype的__proto__可能指向Object.prototype,最终到null,形成一个链式结构。 用户可能想知道如何通过代码来验证这些概念。我需要举一个构造函数的例子,比如创建一个Person构造函数,然后生成实例,并展示原型链的层级。例如,Person.prototype是实例的原型,而Person.prototype本身也是一个对象,它的原型是Object.prototype。这样,当实例访问toString方法时,会沿着原型链找到Object.prototype的toString。 然后,继承是如何通过原型链实现的?根据引用[3],可以通过将子类的prototype指向父类的实例来实现继承。例如,Student继承Person,将Student.prototype = new Person(),这样Student的实例就能访问Person的属性和方法。同时,还需要修正constructor的指向,避免引用混乱。 用户可能还会关心ES6中的class语法和原型的关系。引用[4]指出,class本质上是原型继承的语法糖。使用class定义类时,其方法会被添加到原型对象上,extends关键字则基于原型链实现继承。这样,class让原型继承更直观,但底层机制不变。 需要确保提供的示例代码正确且易于理解。比如,定义构造函数、添加方法到原型、创建实例并调用方法。同时,展示原型链的查找过程,比如使用hasOwnProperty检查属性是否在实例上,以及instanceof运算符的原理。 用户可能的问题包括原型链的终点是什么,如何判断属性是实例自身还是继承来的,以及如何实现继承的不同方法。在回答时,要分点清晰,结合代码示例和引用资料中的概念,确保准确性和易懂性。 最后,生成的相关问题需要覆盖原型链的应用、与class的关系、性能影响、常见错误等,帮助用户进一步深入理解。</think>### JavaScript 原型原型链详解 #### 一、原型(Prototype) 1. **基本概念** JavaScript 中每个对象都有一个隐藏属性 `[[Prototype]]`(通过 `__proto__` 访问),指向其原型对象。构造函数通过 `prototype` 属性关联原型对象,实例通过 `__proto__` 继承原型属性和方法[^1][^4]。 ```javascript function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log(`Hello, ${this.name}!`); }; const alice = new Person("Alice"); alice.sayHello(); // 调用原型方法 [^1] ``` 2. **原型层级** 实例的 `__proto__` 指向构造函数的 `prototype`,而构造函数的 `prototype` 本身也是对象,其 `__proto__` 指向 `Object.prototype`,最终原型链顶端为 `null`。 ```javascript console.log(alice.__proto__ === Person.prototype); // true console.log(Person.prototype.__proto__ === Object.prototype); // true console.log(Object.prototype.__proto__); // null [^2] ``` --- #### 二、原型链(Prototype Chain) 1. **属性查找机制** 当访问对象属性时,JavaScript 会按以下顺序查找: - 对象自身属性 - 沿原型链逐级向上查找(通过 `__proto__`) - 直到找到属性或到达 `null`[^3] ```javascript console.log(alice.hasOwnProperty("name")); // true(自身属性) console.log(alice.hasOwnProperty("sayHello")); // false(继承属性) ``` 2. **原型链继承示例** 通过修改原型链实现继承: ```javascript function Student(name, grade) { Person.call(this, name); this.grade = grade; } Student.prototype = Object.create(Person.prototype); // 继承原型 Student.prototype.constructor = Student; // 修正构造函数指向 const bob = new Student("Bob", 3); bob.sayHello(); // 继承自Person原型 ``` --- #### 三、关键特性与用法 1. **原型链的终点** 所有原型链的终点是 `Object.prototype`,其 `__proto__` 为 `null`。 2. **判断原型关系** - `instanceof`:检测构造函数是否在原型链上 ```javascript console.log(bob instanceof Student); // true console.log(bob instanceof Person); // true ``` - `Object.getPrototypeOf()`:获取对象的原型 ```javascript console.log(Object.getPrototypeOf(bob) === Student.prototype); // true ``` 3. **原型污染与防御** 修改 `Object.prototype` 会影响所有对象,需谨慎操作: ```javascript Object.prototype.customMethod = () => {}; // 所有对象均可访问 ``` --- #### 四、ES6 Class 与原型链 `class` 是原型继承的语法糖,本质仍基于原型链: ```javascript class Animal { constructor(name) { this.name = name; } speak() { console.log(`${this.name} makes a noise.`); } } class Dog extends Animal { speak() { super.speak(); console.log(`${this.name} barks.`); } } const dog = new Dog("Rex"); dog.speak(); // 继承并扩展方法 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值