深入理解JavaScript对象创建

简介: 深入理解JavaScript对象创建

深入理解JavaScript对象创建

在JavaScript中,对象是包含相关数据和方法的集合。这些数据和方法可以是任何数据类型,包括其他对象。JavaScript提供了多种创建对象的方式,每种方式都有其独特的用途和优点。本文将详细解析JavaScript中创建对象的各种方法,并讨论它们的适用场景。

1. 对象字面量

对象字面量(也称为对象初始化器)是创建对象的最简单方式。只需要定义一个变量,并使用大括号 {} 包围属性和方法即可。

let person = {
    name: "Alice",
    age: 30,
    greet: function() {
        console.log(`Hello, my name is ${this.name}`);
    }
};

这种方式非常直观,并且代码量很少。但是,如果你需要创建多个具有相同属性和方法的对象,这种方式就会变得冗余。

另外补充,下面方式是等价的,都是创建了一个原型为Object.prototype的空对象

let a = {}//字面量的方式创建
let a = new Object()//Object构造函数创建
let a = Object.creat(Object.prototype)
let b = Object.creat(null)

这是创建一个原型为null的空对象

Object.create(proto,[propertiesObject])方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__。

proto 新创建对象的原型对象; propertiesObject 可选:

  1. configurable true
    只有该属性描述符的类型可以被改变并且该属性可以从对应对象中删除。 默认为 false
  2. enumerable true
    只有在枚举相应对象上的属性时该属性显现。 默认为 false
  3. value 与属性关联的值。可以是任何有效的JavaScript值(数字,对象,函数等)。 默认为undefined.
  4. writable true
    只有与该属性相关联的值被assignment operator改变时。 默认为 false
  5. get 作为该属性的 getter 函数,如果没有 getter 则为undefined。函数返回值将被用作属性的值。 默认为 undefined
  6. set 作为属性的 setter 函数,如果没有 setter 则为undefined。函数将仅接受参数赋值给该属性的新值。默认为 undefined
let o = Object.create({}, { p: { value: 42, writable: true } })
o.p = 2
console.log(o.p);//2

举个例子这个o对象就是一个原型是{},属性p可写的一个对象;

2. 构造函数

构造函数是一种特殊的函数,用于初始化新创建的对象。在JavaScript中,你可以使用 new 关键字和构造函数来创建对象。

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.greet = function() {
        console.log(`Hello, my name is ${this.name}`);
    };
}

let alice = new Person("Alice", 30);
let bob = new Person("Bob", 25);

这种方式解决了对象字面量方式的冗余问题,但每个对象仍然有其自己的 greet 方法,这在一定程度上还是浪费了内存。

3. 原型

在JavaScript中,每个函数都有一个 prototype 属性,它是一个指向原型对象的指针。原型对象包含可以由特定类型的所有实例共享的属性和方法。

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

Person.prototype.greet = function() {
    console.log(`Hello, my name is ${this.name}`);
};

let alice = new Person("Alice", 30);
let bob = new Person("Bob", 25);

在这个例子中,greet 方法被定义在 Person 的原型上,因此所有的 Person 实例都可以访问这个方法,但这个方法只在内存中存在一次,从而节省了内存。

4. Object.create()

Object.create() 方法创建一个新对象,使用现有的对象作为新创建对象的 __proto__

let personProto = {
    greet: function() {
        console.log(`Hello, my name is ${this.name}`);
    }
};

let alice = Object.create(personProto);
alice.name = "Alice";
alice.age = 30;

let bob = Object.create(personProto);
bob.name = "Bob";
bob.age = 25;

Object.create()` 提供了更多的灵活性,因为它允许你选择一个原型对象,而不是使用构造函数的原型。然而,这种方式通常不用于创建具有复杂结构的对象。


5. class(ES6 引入)

从 ES6 开始,JavaScript 引入了 class 关键字,作为创建对象和继承的新方式。尽管 class 本质上仍然是基于原型的继承,但它提供了一种更清晰、更直观的语法。

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

    greet() {
        console.log(`Hello, my name is ${this.name}`);
    }
}

let alice = new Person("Alice", 30);
let bob = new Person("Bob", 25);

class` 语法使代码更易于理解和组织,特别是对于那些熟悉基于类的面向对象编程的开发者来说。

再看另外一个例子

  class Person {
    //私有属性和私有方法,方法是在属性名之前,使用#表示
    //只能在类的内部使用(this.#count)。如果在类的外部使用,就会报错。
      #count = 0;
      //ES6 明确规定,Class 内部只有静态方法,没有静态属性(在提案中)
      static bar() {
        console.log(`静态方法`);
      }
        constructor(name, age, job) {
            this.name = name;
            this.age = age;
            this.job = job;
            this.eat = function () {
                console.log(`${this.name}调用了eat`);
            }
        }
        //sayName这个方法在实例的prototype上
        sayName() {
            console.log(this.name);
        }
        //sneeze打喷嚏这个方法在实例对象上  赋值语句+箭头函数 创建实例的自定义方法
        sneeze = ()=>{
          console.log(this)
        }
    }

类的属性除非是显式定义在其本身上(即this对象上),否则都定义在原型上。eat,sayName这两个方法是实例都可以调用,区别就是sayName在实例的prototype上。

总结

JavaScript提供了多种创建对象的方式,每种方式都有其优点和适用场景。对象字面量方式简单直观,但不适合创建大量相似对象。构造函数方式解决了对象字面量的冗余问题,但可能会浪费内存。原型方式进一步节省了内存,但需要更多的理解和注意。Object.create() 提供了更多的灵活性,但通常不用于复杂对象。最后,class 语法提供了一种更清晰、更直观的方式来创建对象和进行继承,特别是对于熟悉基于类的编程的开发者来说。

在选择创建对象的方式时,应根据具体需求和场景进行权衡。例如,如果你需要创建大量具有相同属性和方法的对象,那么使用构造函数和原型可能是更好的选择。如果你需要更多的灵活性和控制,那么 Object.create()class 可能是更好的选择。无论选择哪种方式,都应确保代码的可读性和可维护性。

相关文章
|
2天前
|
JavaScript 前端开发
javascript判断对象中是否存在某个字段
javascript判断对象中是否存在某个字段
|
2天前
|
JavaScript 前端开发
JS遍历数组和对象的方法有哪些
JS遍历数组和对象的方法有哪些
|
2天前
|
JavaScript
js中批量修改对象属性
js中批量修改对象属性
|
2天前
|
JavaScript 前端开发
JavaScript BOM 浏览器对象模型
JavaScript BOM 浏览器对象模型
|
3天前
|
JavaScript 前端开发 Unix
Node.js 全局对象
Node.js 全局对象
10 2
|
4天前
|
JavaScript 前端开发
深入解析JavaScript中的面向对象编程,包括对象的基本概念、创建对象的方法、继承机制以及面向对象编程的优势
【6月更文挑战第12天】本文探讨JavaScript中的面向对象编程,解释了对象的基本概念,如属性和方法,以及基于原型的结构。介绍了创建对象的四种方法:字面量、构造函数、Object.create()和ES6的class关键字。还阐述了继承机制,包括原型链和ES6的class继承,并强调了面向对象编程的代码复用和模块化优势。
11 0
|
4天前
|
存储 JSON JavaScript
JavaScript基础-对象与JSON
【6月更文挑战第11天】本文介绍了JavaScript对象的创建(字面量、构造函数、Class)与操作,包括属性访问和描述符。同时讲解了JSON的性质及其与JS对象的关系,以及序列化和解析过程。文章还列举了三个常见易错点(属性访问错误、JSON格式错误、循环引用)并提供了避免策略。通过代码示例展示如何操作对象和处理JSON,强调实践对于掌握这些概念的重要性。
|
12天前
|
JSON JavaScript 数据格式
1.js动态的往json数据添加新属性和值 2.JSON 和 JS 对象互转 3.对象转化为数组
1.js动态的往json数据添加新属性和值 2.JSON 和 JS 对象互转 3.对象转化为数组
15 0
|
23天前
|
XML JavaScript 前端开发
JavaScript简介&引入方式(JavaScript基础语法、JavaScript对象、BOM、DOM、事件监听)
JavaScript简介&引入方式(JavaScript基础语法、JavaScript对象、BOM、DOM、事件监听)
16 2
|
24天前
|
Web App开发 JavaScript 前端开发
JavaScript 中的 Range 和 Selection 对象
JavaScript 中的 `Range` 和 `Selection` 对象用于处理文本选择。`Range` 表示文档中选定的区域,而 `Selection` 表示用户选择的文本或光标位置。`Range` 可以创建并设置于任何元素或文本,具有多个属性(如 `startContainer`, `endContainer`, `collapsed`)和方法(如 `cloneContents`, `deleteContents`)。`Selection` 提供了获取和操作用户选择的方法,如 `anchorNode`, `focusNode` 和 `addRange`。两者在所有现代浏览器中基本兼容。
7 1
JavaScript 中的 Range 和 Selection 对象