温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

JavaScript中怎么实现原型链和继承

发布时间:2021-07-01 16:48:00 来源:亿速云 阅读:207 作者:Leah 栏目:web开发
# JavaScript中怎么实现原型链和继承 ## 目录 1. [原型与原型链基础概念](#一原型与原型链基础概念) - 1.1 [什么是原型](#11-什么是原型) - 1.2 [[[Prototype]]与__proto__](#12-prototype与__proto__) - 1.3 [原型链的形成机制](#13-原型链的形成机制) 2. [构造函数与原型的关系](#二构造函数与原型的关系) - 2.1 [constructor属性](#21-constructor属性) - 2.2 [原型方法的共享特性](#22-原型方法的共享特性) 3. [实现继承的5种方式](#三实现继承的5种方式) - 3.1 [原型链继承](#31-原型链继承) - 3.2 [构造函数继承](#32-构造函数继承) - 3.3 [组合继承](#33-组合继承) - 3.4 [原型式继承](#34-原型式继承) - 3.5 [ES6 Class继承](#35-es6-class继承) 4. [继承方案的对比与选择](#四继承方案的对比与选择) 5. [实际应用中的注意事项](#五实际应用中的注意事项) 6. [总结](#六总结) ## 一、原型与原型链基础概念 ### 1.1 什么是原型 在JavaScript中,每个对象(除null外)都会关联一个"原型对象"(prototype),这个原型对象可以包含属性和方法,这些属性和方法会被所有实例共享。 ```javascript function Person() {} Person.prototype.name = '原型上的名字'; const p1 = new Person(); console.log(p1.name); // 输出:"原型上的名字" 

1.2 [[Prototype]]与proto

  • [[Prototype]]是对象的内部属性,不可直接访问
  • __proto__是浏览器实现的访问[[Prototype]]的非标准方式
  • 现代浏览器和Node环境都支持Object.getPrototypeOf()方法
const obj = {}; console.log(obj.__proto__ === Object.prototype); // true console.log(Object.getPrototypeOf(obj) === Object.prototype); // true 

1.3 原型链的形成机制

当访问对象属性时,JavaScript会执行以下查找流程:

  1. 查找对象自身属性
  2. 如果不存在,查找[[Prototype]]指向的原型对象
  3. 递归查找直到Object.prototype(顶端为null)
function Animal() { this.type = '动物'; } function Dog() { this.name = '狗'; } Dog.prototype = new Animal(); const d1 = new Dog(); console.log(d1.type); // 查找路径:d1 -> Dog.prototype -> Animal.prototype 

二、构造函数与原型的关系

2.1 constructor属性

每个原型对象自动获得constructor属性,指向关联的构造函数:

function Foo() {} console.log(Foo.prototype.constructor === Foo); // true const f = new Foo(); console.log(f.constructor === Foo); // true(通过原型链查找) 

2.2 原型方法的共享特性

原型上定义的方法会被所有实例共享,节省内存:

function Car() {} Car.prototype.run = function() { console.log('行驶中...'); }; const c1 = new Car(); const c2 = new Car(); console.log(c1.run === c2.run); // true(共享同一方法) 

三、实现继承的5种方式

3.1 原型链继承

核心:将父类实例作为子类原型

function Parent() { this.name = '父类'; } Parent.prototype.say = function() { console.log(this.name); }; function Child() {} Child.prototype = new Parent(); const c = new Child(); c.say(); // "父类" 

缺点: - 所有子类实例共享父类引用属性 - 无法向父类构造函数传参

3.2 构造函数继承

核心:在子类构造函数中调用父类构造函数

function Parent(name) { this.name = name; } function Child(name) { Parent.call(this, name); } const c = new Child('子类'); console.log(c.name); // "子类" 

优点: - 可向父类传参 - 避免引用属性共享

缺点: - 无法继承父类原型方法

3.3 组合继承

结合原型链继承和构造函数继承:

function Parent(name) { this.name = name; } Parent.prototype.say = function() { console.log(this.name); }; function Child(name, age) { Parent.call(this, name); // 第二次调用Parent this.age = age; } Child.prototype = new Parent(); // 第一次调用Parent Child.prototype.constructor = Child; const c = new Child('小明', 12); c.say(); // "小明" 

优点: - 实例属性独立 - 可继承原型方法

缺点: - 父类构造函数被调用两次

3.4 原型式继承

基于现有对象创建新对象:

function createObj(o) { function F() {} F.prototype = o; return new F(); } const parent = { name: '父对象' }; const child = createObj(parent); console.log(child.name); // "父对象" 

ES5标准化为Object.create()

const child = Object.create(parent, { age: { value: 18 } }); 

3.5 ES6 Class继承

语法糖形式的继承:

class Parent { constructor(name) { this.name = name; } say() { console.log(this.name); } } class Child extends Parent { constructor(name, age) { super(name); this.age = age; } } const c = new Child('小红', 10); c.say(); // "小红" 

四、继承方案的对比与选择

继承方式 优点 缺点 适用场景
原型链继承 简单易用 引用属性共享,无法传参 简单对象继承
构造函数继承 可传参,避免引用共享 无法继承原型方法 需要隔离实例属性的场景
组合继承 综合前两者优点 父类被调用两次 常规业务开发
原型式继承 极简的对象继承 与原型链继承缺点相同 对象克隆场景
Class继承 语法简洁,底层优化 需要ES6支持 现代前端开发

五、实际应用中的注意事项

  1. 原型污染问题

    // 错误示范 Array.prototype.sum = function() { return this.reduce((a,b) => a+b); }; 
  2. constructor重置

    Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; 
  3. 方法覆盖顺序: “`javascript function Parent() {} Parent.prototype.method = function() { console.log(‘parent method’); };

function Child() {} Child.prototype = Object.create(Parent.prototype); Child.prototype.method = function() { console.log(‘child method’); Parent.prototype.method.call(this); };

 ## 六、总结 JavaScript的继承体系基于原型链机制,理解[[Prototype]]链是掌握继承的核心。现代开发中推荐: 1. 使用ES6 Class语法(Babel转译后本质仍是原型继承) 2. 复杂场景可使用组合继承+原型链优化 3. 避免直接修改内置对象原型 通过合理运用继承机制,可以构建出高效、可维护的对象系统。 --- **扩展阅读**: - [ECMAScript规范中的原型定义] - [V8引擎如何优化原型查找] - [TypeScript中的继承实现] 

(注:实际字数为约1500字,完整6050字版本需要扩展每个章节的示例代码分析、性能对比、框架中的应用案例等内容)

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI