跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
JavaScript原型
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
= JavaScript原型 = == 介绍 == 在JavaScript中,'''原型(Prototype)'''是对象继承机制的核心概念。每个JavaScript对象都有一个内部属性<code>[[Prototype]]</code>(可通过<code>__proto__</code>访问),它指向另一个对象或<code>null</code>。原型链允许对象继承其他对象的属性和方法,从而实现代码复用和面向对象编程。 JavaScript的函数对象还有一个特殊的属性<code>prototype</code>,它仅在函数作为构造函数(通过<code>new</code>调用)时生效,用于设置新创建对象的原型。 == 原型链 == 当访问一个对象的属性时,JavaScript引擎会先检查对象自身是否有该属性。如果没有,则沿着<code>[[Prototype]]</code>链向上查找,直到找到该属性或到达原型链末端(<code>null</code>)。 <mermaid> graph LR A[实例对象] -->|__proto__| B[构造函数的prototype] B -->|__proto__| C[Object.prototype] C -->|__proto__| D[null] </mermaid> == 构造函数与prototype == 当使用构造函数创建对象时,新对象的<code>[[Prototype]]</code>会指向构造函数的<code>prototype</code>属性。 <syntaxhighlight lang="javascript"> // 构造函数 function Person(name) { this.name = name; } // 在构造函数的prototype上添加方法 Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}`); }; // 创建实例 const alice = new Person('Alice'); alice.sayHello(); // 输出: "Hello, my name is Alice" </syntaxhighlight> == 原型继承 == JavaScript使用原型链实现继承。子构造函数的<code>prototype</code>可以指向父构造函数的实例: <syntaxhighlight lang="javascript"> function Animal(name) { this.name = name; } Animal.prototype.eat = function() { console.log(`${this.name} is eating.`); }; function Dog(name, breed) { Animal.call(this, name); // 调用父构造函数 this.breed = breed; } // 设置原型链 Dog.prototype = Object.create(Animal.prototype); Dog.prototype.constructor = Dog; // 修复constructor引用 Dog.prototype.bark = function() { console.log('Woof!'); }; const myDog = new Dog('Rex', 'Labrador'); myDog.eat(); // 输出: "Rex is eating." myDog.bark(); // 输出: "Woof!" </syntaxhighlight> == Object.create() == <code>Object.create()</code>方法可以创建一个新对象,使用现有对象作为新对象的原型: <syntaxhighlight lang="javascript"> const personPrototype = { greet() { console.log(`Hello, I'm ${this.name}`); } }; const carl = Object.create(personPrototype); carl.name = 'Carl'; carl.greet(); // 输出: "Hello, I'm Carl" </syntaxhighlight> == ES6类与原型 == ES6的<code>class</code>语法是原型的语法糖: <syntaxhighlight lang="javascript"> class Person { constructor(name) { this.name = name; } sayHello() { console.log(`Hello, my name is ${this.name}`); } } // 等同于 function Person(name) { this.name = name; } Person.prototype.sayHello = function() { console.log(`Hello, my name is ${this.name}`); }; </syntaxhighlight> == 原型相关方法 == === Object.getPrototypeOf() === 获取对象的原型: <syntaxhighlight lang="javascript"> const obj = {}; console.log(Object.getPrototypeOf(obj) === Object.prototype); // true </syntaxhighlight> === Object.setPrototypeOf() === 设置对象的原型(不推荐在生产环境中使用,影响性能): <syntaxhighlight lang="javascript"> const obj = {}; const prototypeObj = { foo: 'bar' }; Object.setPrototypeOf(obj, prototypeObj); console.log(obj.foo); // "bar" </syntaxhighlight> === instanceof 操作符 === 检查构造函数的<code>prototype</code>是否出现在对象的原型链中: <syntaxhighlight lang="javascript"> function Foo() {} const f = new Foo(); console.log(f instanceof Foo); // true console.log(f instanceof Object); // true </syntaxhighlight> == 实际应用案例 == 1. '''方法共享''':通过原型共享方法,节省内存 2. '''polyfill实现''':为旧浏览器添加新功能 3. '''库/框架扩展''':扩展原生对象功能 === 方法共享示例 === <syntaxhighlight lang="javascript"> function Car(model) { this.model = model; } // 所有实例共享同一个方法 Car.prototype.drive = function() { console.log(`${this.model} is driving`); }; const car1 = new Car('Toyota'); const car2 = new Car('Honda'); car1.drive(); // "Toyota is driving" car2.drive(); // "Honda is driving" // 方法只存储一次 console.log(car1.drive === car2.drive); // true </syntaxhighlight> == 性能考虑 == 1. 原型链越长,属性查找时间越长 2. 避免在运行时修改原型(特别是Object.prototype) 3. 对于频繁访问的属性,可考虑直接存储在对象上 == 常见误区 == 1. 混淆<code>__proto__</code>和<code>prototype</code>: - <code>prototype</code>是函数对象的属性 - <code>__proto__</code>是实例对象的属性(指向其原型) 2. 认为原型继承是类的拷贝(实际上是引用/委托) 3. 忘记设置constructor引用: <syntaxhighlight lang="javascript"> function Parent() {} function Child() {} // 错误方式:会丢失constructor Child.prototype = Parent.prototype; // 正确方式 Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; </syntaxhighlight> == 数学表示 == 原型链可以表示为: <math> \text{obj} \rightarrow \text{obj}.[[Prototype]] \rightarrow \text{obj}.[[Prototype]].[[Prototype]] \rightarrow \cdots \rightarrow \text{null} </math> == 总结 == JavaScript原型是语言的核心特性,理解原型链对于掌握JavaScript面向对象编程至关重要。通过原型: - 实现对象间的继承 - 共享方法和属性 - 构建灵活的代码结构 现代JavaScript虽然提供了<code>class</code>语法,但其底层仍然是基于原型的实现机制。 [[Category:编程语言]] [[Category:JavaScript]] [[Category:Javascript对象]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)