JavaScript 创建对象的五种方法

本文详细介绍了JavaScript中创建对象的五种方法:原始模式、工厂模式、构造函数(包括new关键字和静态成员与实例成员)、构造函数+原型以及ES6的类。每种方法的优缺点和使用场景都有所阐述,帮助读者理解并掌握JavaScript对象创建的多种方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JavaScript 是一门面向对象的编程语言(Object Oriented Programming),面向对象编程具有灵活、代码可复用、容易维护和开发的优点,更适合多人合作的大型软件项目。

在 JavaScript 中,有这么一句话:“万物皆对象”。 对象是一组无序的相关属性和方法的集合,例如字符串、数值、数组、函数等。这即是说,对象是由属性和方法组成的:

  • 属性:事物的特征,在对象中用属性来表示(常用名词)

  • 方法:事物的行为,在对象中用方法来表示(常用动词)

这篇博客我们来讲讲 JavaScript 创建对象的几种方法。

创建对象的五种方法

1 原始模式

//1.原始模式,对象字面量方式
var person = {
    name: 'Jack',
    age: 18,
    sayName: function() {
		console.log(this.name)
    }
};

//2.原始模式,Object构造函数方式
var person = new Object()
person.name = 'LoveLinqi'
person.age = 18
person.sayName = function () {
    console.log(this.name)
};

2 工厂模式

看上面的原始模式,越看越可爱,因为我们绝大多数人第一次创建的对象可能都是以这种原始模式的。

但是,当我们要创建批量的对象person1、person2……时,你可能就不会觉得这种模式很可爱了。

于是我们开始创办“工厂”,让“工厂”来为我们生产对象,这就是创建对象的工厂模式:

function factoryPerson(name, age) {
    var person = new Object();
    person.name = name;
    person.age = age;
    person.sayName = function() {
        alert(this.name)
    };
    return person;
}
var person1 = factoryPerson('LoveLinqi', 18);
console.log(person1 instanceof Object);//ture
console.log(typeof(person1));//Object

工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题,即怎样知道一个对象的类型(上例中我们用 instanceof 只可识别对象person1为Object)。

另外,使用工厂模式,每次创建对象时都要创建一个独立的对象,代码臃肿。

3 构造函数

在ES6之前,JS中并没有引入类的概念,对象不是基于类创建的,而是用一种称为构造函数的特殊函数来定义对象和它们的特征。

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

var person1 = new Person('Linqi',18)
console.log(person1 instanceof Object)//true
console.log(person1 instanceof Person)//true
console.log(typeof(person1));//Object

Person('LoveLinqi', 18)
console.log(window.name);//Linqi

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与 new 一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。

在 JS 中,使用构造函数时要注意以下两点:

  1. 构造函数用于创建某一类对象,其首字母要大写

  2. 构造函数要和 new 一起使用才有意义

3.1 new关键字

new 在执行时会做四件事情:

  1. 在内存中创建一个新的空对象。

  2. 让 this 指向这个新的对象。

  3. 执行构造函数里面的代码,给这个新对象添加属性和方法。

  4. 返回这个新对象(所以构造函数里面不需要 return )。

3.2 静态成员和实例成员

构造函数中的属性和方法我们称为成员, 成员可以添加。

1. 实例成员:

  • 实例成员就是构造函数内部通过this添加的成员,如上例代码中 name、age、sayName就是实例成员。

  • 实例成员只能通过实例化的对象来访问;

2. 静态成员:

  • 静态成员是在构造函数本身上添加的成员,如上例代码中的sex就是静态成员;

  • 静态成员只能通过构造函数来访问。​​​​​​​

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

var person1 = new Person('LoveLinqi',18)
console.log(Person.age)//undefine,不可以用构造函数访问实例成员

Person.sex = 'fale'//定义静态成员
console.log(Person.sex)//fale,可以用构造函数访问静态成员
console.log(person1.sex)//undefine,不可以用实例访问静态成员

4 构造函数+原型

构造函数方法很好用,但是存在浪费内存的问题。 现在比较常用的创建对象的方式是构造函数+原型。

什么意思呢?

假如我们为一个构造函数创建两个实例:

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

var person1 = new Person('科比',18)
var person2 = new Person('詹姆斯',19)
 

那么它们调用sayName() 方法时,指向的是不同的内存地址,这就造成了内存浪费,我们理应将共享的方法提取出来。

在这篇 blog 中,我只告诉你这种方式的做法是:将独立的属性方法放入构造函数中,而可以共享的部分则放入原型中,这样做可以最大限度节省内存而又保留对象实例的独立性。

(关于 JavaScript 中原型链的知识请见下篇 blog)

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

Person.prototype.sayName = function() {
  this.sayName = function() {
    alert(this.name);
  };
}
var person1 = new Person('Linqi', 18)
console.log(person1)
/*打印内容:
* age: 18
* name: "Linqi"
* __proto__:{
*   hobbies: (2) ["sleep", "weibo"]
*   sayName: ƒ ()
*   constructor: ƒ Person(name, age)
*   __proto__: Object
* }
*/

Person.prototype.hobbies = ['sleep', 'weibo']
console.log(person1.__proto__)
/*打印内容:
* hobbies: (2) ["sleep", "weibo"]
* sayName: ƒ ()
* constructor: ƒ Person(name, age)
* __proto__: Object
*/

5 类

还有一种创建对象的方法就是类了。类是ES6中新增的语法,用class关键字创建一个类。

class Person {
  constructor(name,age) {   // constructor 构造器或者构造函数
      this.name = name;
      this.age = age;
    }
   sayName() {
      console.log(this.name);
   }
}    
var person1 = new Person('LoveLinqi', 18)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值