阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 对象创建方式

对象创建方式

作者:陈川 阅读数:37626人阅读 分类: JavaScript

对象字面量

对象字面量是最简单直接的创建对象方式,使用花括号{}包裹键值对。这种方式适合创建简单的、不需要复用的对象。

const person = {
  name: '张三',
  age: 30,
  greet() {
    console.log(`你好,我是${this.name}`);
  }
};

对象字面量支持各种值类型作为属性值,包括函数、数组、其他对象等。ES6之后还支持计算属性名:

const propKey = 'gender';
const person = {
  [propKey]: 'male',
  ['user' + 'Name']: '李四'
};

构造函数

使用new关键字调用构造函数可以创建对象实例。这种方式适合需要创建多个相似对象的场景。

function Person(name, age) {
  this.name = name;
  this.age = age;
  this.greet = function() {
    console.log(`你好,我是${this.name}`);
  };
}

const person1 = new Person('王五', 25);
const person2 = new Person('赵六', 28);

构造函数的问题在于每个实例都会创建自己的方法副本,造成内存浪费。解决方法是将方法定义在原型上:

function Person(name, age) {
  this.name = name;
  this.age = age;
}

Person.prototype.greet = function() {
  console.log(`你好,我是${this.name}`);
};

Object.create()

Object.create()方法使用现有对象作为新创建对象的原型。这种方式适合需要精确控制对象原型链的场景。

const personProto = {
  greet() {
    console.log(`你好,我是${this.name}`);
  }
};

const person = Object.create(personProto);
person.name = '钱七';
person.age = 35;

可以传入第二个参数来定义属性描述符:

const person = Object.create(personProto, {
  name: {
    value: '孙八',
    writable: true,
    enumerable: true
  },
  age: {
    value: 40,
    enumerable: true
  }
});

类语法

ES6引入了类语法,本质上是构造函数的语法糖,但提供了更清晰的面向对象编程方式。

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  greet() {
    console.log(`你好,我是${this.name}`);
  }

  static createDefault() {
    return new Person('默认', 0);
  }
}

const person = new Person('周九', 45);
const defaultPerson = Person.createDefault();

类支持继承、静态方法、getter/setter等特性:

class Employee extends Person {
  constructor(name, age, position) {
    super(name, age);
    this.position = position;
  }

  get info() {
    return `${this.name}(${this.age}) - ${this.position}`;
  }
}

工厂函数

工厂函数是返回对象的函数,不需要使用new关键字。这种方式适合需要封装复杂创建逻辑的场景。

function createPerson(name, age) {
  return {
    name,
    age,
    greet() {
      console.log(`你好,我是${this.name}`);
    }
  };
}

const person = createPerson('吴十', 50);

可以结合闭包创建私有成员:

function createPerson(name) {
  let _age = 0; // 私有变量
  
  return {
    name,
    get age() {
      return _age;
    },
    set age(value) {
      if(value >= 0) {
        _age = value;
      }
    }
  };
}

单例模式

单例模式确保一个类只有一个实例。在JavaScript中可以通过立即执行函数表达式(IIFE)实现。

const Singleton = (function() {
  let instance;
  
  function createInstance() {
    return {
      id: Math.random(),
      log() {
        console.log(`实例ID: ${this.id}`);
      }
    };
  }
  
  return {
    getInstance() {
      if(!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true

对象解构与合并

ES6引入的对象解构和展开运算符提供了新的对象创建方式。

// 对象解构创建变量
const { name, age } = { name: '郑十一', age: 55 };

// 展开运算符合并对象
const defaults = { color: 'red', size: 'medium' };
const config = { ...defaults, size: 'large' };

可以用于浅拷贝对象:

const original = { a: 1, b: { c: 2 } };
const copy = { ...original };

动态属性名

ES6允许在对象字面量中使用表达式作为属性名。

const dynamicKey = 'dynamicProp';
const obj = {
  [dynamicKey]: '动态属性值',
  [`computed_${dynamicKey}`]: '计算属性值'
};

属性描述符

通过Object.defineProperty()可以精确控制对象属性的行为。

const obj = {};
Object.defineProperty(obj, 'readOnlyProp', {
  value: '不可修改',
  writable: false,
  enumerable: true
});

Object.defineProperties(obj, {
  prop1: {
    value: '属性1',
    writable: true
  },
  prop2: {
    get() {
      return this.prop1 + ' 扩展';
    }
  }
});

原型链继承

JavaScript使用原型链实现继承,可以通过多种方式设置对象的原型。

// 设置__proto__(不推荐)
const parent = { parentProp: '父属性' };
const child = { childProp: '子属性' };
child.__proto__ = parent;

// 使用Object.setPrototypeOf
Object.setPrototypeOf(child, parent);

// 构造函数继承
function Parent() {
  this.parentProp = '父属性';
}
function Child() {
  Parent.call(this);
  this.childProp = '子属性';
}
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

上一篇:函数柯里化

下一篇:属性描述符

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌