javascript中属性归属位置决定原型属性与实例属性差异:实例属性在构造函数内用this赋值,各实例独有;原型属性定义在constructor.prototype上,所有实例共享。

要对比 JavaScript 中原型对象和实例属性的差异点,关键不是“比较两个值”,而是理清“哪些属性来自原型、哪些是实例自己独有的”。JS 的属性访问机制决定了:当读取一个属性时,引擎先查实例自身,再顺着 __proto__ 向上查原型链。所以差异的本质在于**属性的归属位置**,而非内容是否相同。
看属性在哪儿定义:实例自有 vs 原型共享
实例属性通常在构造函数内部用 this.xxx = value 显式赋值;原型属性则写在 Constructor.prototype.xxx 上(或用 class 语法的类字段/方法)。两者内存行为不同:
- 每个实例都有一份独立的
this.name,修改它不影响其他实例 - 所有实例共用同一个
Constructor.prototype.sayHi函数,改一处,全部生效
用 Object.getOwnPropertyNames() 和 in 操作符区分
Object.getOwnPropertyNames(obj) 只返回实例自身拥有的可枚举+不可枚举属性名(不含原型上的);而 key in obj 或 for...in 会遍历整个原型链(包括原型上的可枚举属性)。
将一个或多个视频上传至YouTube。当用户想“上传到YouTube”“发YouTube”“批量上传”“upload to YouTube”“post videos to YouTube”或发布到YouTube时使用此技能。
-
Object.getOwnPropertyNames(instance)→ 查实例私有属性 -
Object.getOwnPropertyNames(Instance.constructor.prototype)→ 查原型上定义的属性 -
key in instance为 true 但instance.hasOwnProperty(key)为 false → 说明该属性来自原型
检查属性描述符确认来源
用 Object.getOwnPropertyDescriptor(obj, key) 能看到属性是否在实例上定义(返回非 undefined),再结合 Object.getPrototypeOf(obj) 查原型对象,逐层比对:
- 如果
Object.getOwnPropertyDescriptor(instance, 'x')有结果 → x 是实例属性 - 如果为 undefined,再查
Object.getOwnPropertyDescriptor(Object.getPrototypeOf(instance), 'x')→ 看是否在原型上 - 继续向上查
Object.getPrototypeOf(Object.getPrototypeOf(instance)),直到 null
快速识别常见差异场景
以下情况容易混淆,需特别注意:
- 同名属性:实例上有
this.color = 'red',原型上也有Car.prototype.color = 'blue'→ 实例访问car.color永远得 'red',原型的被屏蔽 - 方法重写:实例动态加了
car.drive = function(){...}→ 原型上的drive不再被调用 - 数组/对象类属性误放实例:如
this.tags = []写在构造函数里 → 每个实例独享数组;若错写成Car.prototype.tags = []→ 所有实例共享同一数组,造成意外污染










