JS 原型 Prototype

简介: JS 原型 Prototype


Prototype

基于原型的语言

每个对象拥有一个原型对象,对象以其原型为模板、从原型继承方法和属性。
原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链 (prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。

函数的原型属性

每个函数都有一个特殊的属性叫作原型(prototype)

function doSomething(){}
console.log( doSomething.prototype );

以上便是 doSometing 这个函数的 原型 属性

修改原型

function doSomething(){}
doSomething.prototype.foo = "bar";
console.log( doSomething.prototype );

创建实例

我们可以使用 new 运算符来在现在的这个原型基础之上,创建一个 doSomething 的实例

function doSomething(){}
doSomething.prototype.foo = "bar"; // add a property onto the prototype
var doSomeInstancing = new doSomething();
doSomeInstancing.prop = "some value"; // add a property onto the object
console.log( doSomeInstancing );

此时可以看到 doSomeInstancing 的输出中第一项 constructor 是这个实例的 构造函数 ,也就是 doSomething 函数,第二项 prop 这是我们手动为这个实例添加的一个属性。而其中一个最关键的属性便是 <prototype> ,以往我们使用 a.__proto__ 来访问到这个属性,但其实这并不是一个标准定义。这个属性则是实现继承的核心,它其实就是构造函数的 prototype ,也就是 doSomething.prototype ,也是我们这个实例的 doSomeInstancing.constructor.prototype == doSomeInstancing.__proto__ 。

当我们想要从这个实例中获取 foo 这个属性时,JS会首先在当前实例属性中去寻找,如果没有则会找到这个实例的构造函数原型属性中去找,也就是 doSomething.prototype.foo ,如果还找不到就会在这个原型的原型上去找。

比如 doSomeInstancing.toString 这个函数其实有 Object.prototype.toString == doSomeInstancing.toString ,这是因为 doSomeInstancing.toString -> doSomeInstancing.__proto__.toString -> doSomeInstancing.__proto__.__proto__.toString ,且 doSomeInstancing.__proto__.__proto__ == doSomething.prototype.__proto__ == Object.prototype

继承发生在 prototype

上面例子中 doSomeInstancing 包含从 Object 中继承了 toString 方法,但其实 Object 这个构造函数(类) 还有类似 Object.keys 这样的函数,它们没有被继承下来,这是因为它们时直接"依附"在 Object 之上,可以理解为 Java 中的静态函数, 而只有在 Object.prototype 中定义的属性才会被继承

注意: The prototype property is one of the most confusingly-named parts of JavaScript — you might think that it points to the prototype object of the current object, but it doesn’t (that’s an internal object that can be accessed by __proto__ , remember?). prototype instead is a property containing an object on which you define members that you want to be inherited.

Object.create

var person2 = Object.create(person1);
person2.__proto__ == person1

create() 实际做的是从指定原型对象创建一个新的对象。这里以 person1 为原型对象创建了 person2 对象

手动实现继承

let a = {} // 创建一个空对象
a.foo = "zz"
let b = {} // 创建另一个空对象
b.__proto__ = a // 设置 b 的 原型
console.log(b.foo == "zz")
目录
相关文章
|
存储
(pinia-plugin-persistedstate)pinia 持久化存储
(pinia-plugin-persistedstate)pinia 持久化存储
1789 1
|
开发框架 JavaScript 前端开发
vue首次加载白屏问题
vue首次加载白屏问题
655 0
|
3月前
|
人工智能 JavaScript 测试技术
DeepSeek Harness爆火,测试开发的下一个“版本答案”找到了!
DeepSeek于2026年8月开源Agent执行底座Harness,6天获16.7万星。它并非模型,而是“AI操作系统”:以插件化架构解耦模型与工具,支持多厂商LLM,实现“一切皆插件”。专为测试开发等工程场景设计,推动从写脚本到编排Agent的范式升级。
|
4月前
|
人工智能 自然语言处理 JavaScript
放弃Selenium吧!2026年最火的AI驱动测试框架终极盘点
本文探讨2026年AI驱动测试的范式变革:Selenium等传统工具因维护成本高、适配慢而式微;AI测试框架以“意图驱动”替代“脚本指令”,通过LLM决策+结构化执行实现语义定位与动态恢复。分析Karate Agent、Midscene.js、QA Wolf三类框架差异,并给出渐进落地建议——测试体系需从面向“稳定UI”转向拥抱“持续变化”。
|
10月前
|
人工智能 人机交互 语音技术
|
6月前
|
JSON 前端开发 JavaScript
前端组件库—— Vditor 知识点大全(四)
教程来源 http://oplhc.cn Vditor 是一款功能强大的浏览器端 Markdown 编辑器,支持图片拖拽/粘贴上传、Mermaid/ECharts 图表、KaTeX 数学公式、离线部署及实时保存等高级特性,兼容 Vue/React,高度可定制。
在 Vue.js 中使用 watch 来监听对象属性的变化
在 Vue.js 中使用 watch 来监听对象属性的变化
|
JavaScript
Vue3基础(十)___toRaw___markRaw
本文介绍了Vue 3中`toRaw`和`markRaw`的用法,解释了`toRaw`用于获取`ref`和`reactive`对象的原始数据,而`markRaw`用于阻止Vue将对象转换为响应式数据。文章通过代码示例展示了这两个函数在实际开发中的应用和效果。
477 0
Vue3基础(十)___toRaw___markRaw
|
资源调度 前端开发 IDE
pnpm 多包管理项目
pnpm 多包管理项目
1162 2
|
Java
vue3知识点:Teleport组件
vue3知识点:Teleport组件
438 1