全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-16 6 分钟 ✍️ juanwangdev

JavaScript 原型式继承

原型式继承是一种无需构造函数的继承方式,基于现有对象直接创建新对象,通过 Object.create() 实现。

Object.create() 方法

JavaScript
// 基本用法:基于原型对象创建新对象
const proto = {
    name: 'default',
    sayHello: function() {
        console.log('Hello, ' + this.name);
    }
};

const obj = Object.create(proto);
obj.name = 'Tom';  // 添加自身属性

obj.sayHello();  // 'Hello, Tom'
console.log(obj.__proto__ === proto);  // true

原理实现

JavaScript
// Object.create 的简易实现
function create(proto) {
    function F() {}          // 创建临时构造函数
    F.prototype = proto;     // 原型指向目标对象
    return new F();          // 返回新实例
}

// 使用
const proto = { greet: 'hello' };
const obj = create(proto);
console.log(obj.__proto__ === proto);  // true

// ES5 标准 Object.create 还支持第二个参数
const obj2 = Object.create(proto, {
    name: {
        value: 'Tom',
        writable: true,
        enumerable: true,
        configurable: true
    }
});
console.log(obj2.name);  // 'Tom'

使用场景

JavaScript
// 场景一:浅拷贝对象
const original = {
    name: 'Original',
    data: [1, 2, 3]
};
const copy = Object.create(original);
copy.name = 'Copy';  // 自身属性,不影响原对象

console.log(original.name);  // 'Original'
console.log(copy.name);      // 'Copy'

// 注意:引用类型仍共享
console.log(copy.data);      // [1, 2, 3](继承)
copy.data.push(4);
console.log(original.data);  // [1, 2, 3, 4](被修改!)

// 场景二:创建纯净对象(无原型)
const pureObj = Object.create(null);
console.log(pureObj.__proto__);  // undefined
console.log(pureObj.toString);   // undefined(无继承方法)

pureObj.foo = 'bar';
console.log(JSON.stringify(pureObj));  // '{"foo":"bar"}'

// 场景三:原型链中间层
function Animal() {}
Animal.prototype.speak = function() {};

function Dog() {}
// 不用 new Animal(),用 Object.create 避免冗余属性
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

与其他继承方式对比

JavaScript
// 原型链继承:创建父类实例作为原型
Dog.prototype = new Animal();  // 有实例属性

// 原型式继承:直接使用父类原型
Dog.prototype = Object.create(Animal.prototype);  // 无实例属性

// 对比
function Animal(name) {
    this.name = name;  // 实例属性
    this.colors = [];
}
Animal.prototype.speak = function() {};

function Dog() {}

// 原型链继承:Dog.prototype 有 name 和 colors
Dog.prototype = new Animal('default');
console.log(Dog.prototype.colors);  // [](存在)

// 原型式继承:Dog.prototype 无实例属性
Dog.prototype = Object.create(Animal.prototype);
console.log(Dog.prototype.colors);  // undefined(不存在)

Object.create() 参数详解

JavaScript
// 第一个参数:原型对象
const proto = { x: 1, y: 2 };
const obj = Object.create(proto);

// 第二个参数:属性描述符(可选)
const obj2 = Object.create(proto, {
    z: {
        value: 3,
        writable: true,
        enumerable: true,
        configurable: true
    },
    secret: {
        value: 'hidden',
        enumerable: false  // 不可枚举
    }
});

console.log(obj2.x);  // 1(继承)
console.log(obj2.z);  // 3(自身)
console.log(obj2.secret);  // 'hidden'
console.log(Object.keys(obj2));  // ['z'](secret 不可枚举)

寄生继承

JavaScript
// 原型式继承 + 增强
function createEnhanced(original) {
    const clone = Object.create(original);
    // 增强对象
    clone.sayHi = function() {
        console.log('Hi from ' + this.name);
    };
    return clone;
}

const proto = { name: 'Proto' };
const enhanced = createEnhanced(proto);
enhanced.sayHi();  // 'Hi from Proto'

// 注意:增强方法每个实例都创建一次(非共享)
const another = createEnhanced(proto);
console.log(enhanced.sayHi === another.sayHi);  // false

注意事项

  • Object.create(null) 创建无原型对象,适合纯数据字典
  • 引用类型属性仍被共享,需在自身属性中覆盖
  • 寄生继承为每个实例创建增强方法,内存效率低
  • ES5 之前需手动实现 create() 函数
JavaScript
// 创建纯净对象的优势
const dict = Object.create(null);
dict.foo = 'bar';
dict.constructor = 'safe';  // 无冲突
console.log(dict.hasOwnProperty);  // undefined

// 普通对象的问题
const normal = {};
normal.constructor = 'safe';
console.log(normal.constructor);  // 'safe'(覆盖了原型)

要点总结

  • Object.create(proto) 创建以 proto 为原型的新对象
  • 无需构造函数,直接基于现有对象继承
  • Object.create(null) 创建无原型对象,适合数据字典
  • 寄生继承:原型式继承 + 对象增强
  • 引用类型仍共享,需额外处理
  • 与原型链继承区别:不创建父类实例,只有原型链接

📝 发现内容有误?点击此处直接编辑

← 上一篇 JavaScript instanceof 原理
下一篇 → JavaScript 原型链基础
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库