JavaScript中的原型与继承

目录

JavaScript中的原型与继承

一. 基本概念

二. 主要内容

1. 对象和原型

2. 原型链

3. 函数的 .prototype 属性(构造函数)

4. ES6 的 class

三. 总结重点 

四. 示例 

原型链输出题

步骤解析:

console.log(obj1.getValue());

console.log(obj2.getValue());

console.log(obj1.value);

console.log(obj2.value);

原型链结构图

最终结果: 


JavaScript中的原型与继承

一. 基本概念

JavaScript 中的对象是通过 “原型” 来继承的。每个对象都有一个原型,它是另一个对象。当你访问一个属性时,如果对象本身没有这个属性,就会去原型上找,一层层向上,直到找到为止,这就是 原型链

二. 主要内容

1. 对象和原型

每个 JavaScript 对象都有一个“隐藏属性” [Prototype](通常通过 proto访问),它指向另一个对象。这个被指向的对象叫“原型”。

const animal = {
  eats: true
};

const rabbit = {
  jumps: true
};

rabbit.__proto__ = animal;

console.log(rabbit.eats);  // true,继承自 animal
console.log(rabbit.jumps); // true,自己的属性

2. 原型链

如果原型也有原型,就形成了一条链:

rabbit → animal → Object.prototype → null

查找属性时会一层层往上找,直到:

  • 找到为止,返回值

  • 到达 null,返回 undefined

3. 函数的 .prototype 属性(构造函数)

当你使用构造函数(或者类)创建对象时,JavaScript 会自动把对象的 proto设置为构造函数的 .prototype

function Person(name) {
  this.name = name;
}
Person.prototype.sayHi = function() {
  console.log(`Hi, I'm ${this.name}`);
};

const alice = new Person('Alice');
alice.sayHi(); // Hi, I'm Alice

原理图: 

alice.__proto__ === Person.prototype

所以 alice 可以访问 sayHi 方法。 

4. ES6 的 class

class Animal {
  speak() {
    console.log('I can speak');
  }
}

class Dog extends Animal {
  bark() {
    console.log('Woof!');
  }
}

const d = new Dog();
d.bark();  // Woof!
d.speak(); // I can speak

实际等价于: 

Dog.prototype.__proto__ = Animal.prototype;

三. 总结重点 

 

四. 示例 

原型链输出题

function A() {
  this.value = 1;
}
A.prototype.getValue = function () {
  return this.value;
};

function B() {
  A.call(this);
}
B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

const obj1 = new B();
const obj2 = new A();

A.prototype.value = 100;

console.log(obj1.getValue()); // ?
console.log(obj2.getValue()); // ?
console.log(obj1.value);      // ?
console.log(obj2.value);      // ?

提示(可以从这里思考):

1. obj1obj2 都是怎么来的?

2. 谁的 value 是自己身上的?谁是从原型里找的?

3. 修改 A.prototype.value = 100 对谁有影响?

步骤解析:

第一步:构造对象

const obj1 = new B(); // 触发 B 构造函数 → A.call(this)
const obj2 = new A(); // 触发 A 构造函数

所以 obj1.value = 1(通过 A.call(this) 赋值),obj2.value = 1(A 构造函数赋值)。

第二步:原型链分析

obj1 --> B.prototype --> A.prototype --> Object.prototype
obj2 --> A.prototype --> Object.prototype

 getValue() 是定义在 A.prototype 上,两个对象都能通过原型链访问到。

第三步A.prototype.value = 100;

这 不会影响 obj1.value 或 obj2.value,因为它们自己已经有了 value = 1 的属性。

输出结果分析 

console.log(obj1.getValue());

  • obj1.getValue() → A.prototype.getValue

  • this.value 中的 this 是指 obj1

  • obj1 自己有 value = 1,所以输出:1

输出:1

console.log(obj2.getValue());

  • obj2.getValue() → A.prototype.getValue

  • this.value 中的 thisobj2

  • obj2 自己也有 value = 1

输出:1

console.log(obj1.value);

  • obj1 自己的 value1,所以直接返回

输出:1

console.log(obj2.value);

  • 同样,obj2.value = 1 是实例自己的属性

输出:1

 

原型链结构图

最终结果: 

1

1

1

1

 

 

 


                
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值