JS从入门到精通--对象

147 阅读5分钟

对象的创建方式

在JavaScript中,有多种方式可以创建对象。以下是常见的几种方式:

  1. 使用字面量表示法(Literal Notation)创建对象:
const obj = {
 key1: value1,
 key2: value2,
};
//这种方式使用花括号 `{}` 来创建对象,并在其中定义键值对。
  1. 使用构造函数创建对象
function Person(name, age) {
  this.name = name;
  this.age = age;
}
const person = new Person("John", 25);

//在这种方式中,我们使用构造函数创建对象。构造函数是一个特殊的函数,
//它通过使用 `new` 关键字来创建对象,并通过 `this` 关键字来定义对象的属性。
  1. 使用Object.create()方法创建对象
const obj = Object.create(null);
obj.key1 = value1;
obj.key2 = value2;
//这种方式使用 `Object.create()` 方法来创建一个新对象,并可以在后续代码中为其添加属性。
  1. 使用工厂函数创建对象:
function createPerson(name, age) {
return {
    name: name,
    age: age,
   }
 }

const person = createPerson("John", 25);
// 工厂函数是一个返回对象的函数,它可以根据传入的参数动态地创建并返回对象。
  1. 使用 ES6 的类(Class)创建对象:
 class Person {
   constructor(name, age) {
     this.name = name;
     this.age = age;
   }
 }

 const person = new Person("John", 25);

 ES6 引入了类的概念,可以使用 `class` 关键字来定义类,并使用 `new` 关键字创建类的实例对象。

对象的操作

在JavaScript中,有许多可以用来操作对象的方法和操作符。下面是一些常见的对象操作:

  1. 访问对象属性:

    • 使用点符号(.):object.property
    • 使用方括号([]):object['property']
  2. 设置对象属性:

    • 使用点符号(.):object.property = value
    • 使用方括号([]):object['property'] = value
  3. 删除对象属性:

    • 使用 delete 操作符:delete object.property
  4. 检查对象是否具有属性:

    • 使用 in 操作符:'property' in object
  5. 迭代对象属性:

    • 使用 for...in 循环:
    for (let key in object) {
      // 使用 object[key] 访问属性值
    }
    
    
  6. 复制对象:

    • 使用对象展开运算符(...)进行浅拷贝:const newObj = { ...oldObj }
    • 使用 Object.assign() 进行浅拷贝:const newObj = Object.assign({}, oldObj)
    • 使用 JSON.parse() 和 JSON.stringify() 进行深拷贝:
    const newObj = JSON.parse(JSON.stringify(oldObj))
    
    
  7. 比较对象:

    • 使用 === 或 Object.is() 进行严格相等比较:object1 === object2
    • 使用库函数或自定义函数进行深度比较:例如 lodash 库中的 isEqual() 方法

这些是常见的对象操作方法和操作符。根据需要,您可以使用它们来访问、设置、删除属性,检查属性是否存在,迭代属性,复制对象以及比较对象。

对象的遍历for...in

在JavaScript中,你可以使用 for...in 循环来遍历对象的属性。for...in 循环会迭代对象的可枚举属性,并将每个属性的键(key)赋值给循环变量。

以下是使用 for...in 循环遍历对象的示例代码:

const obj = {
  name: 'John',
  age: 25,
  city: 'New York'
};

for (let key in obj) {
  console.log(key + ': ' + obj[key]);
}

在上述示例中,for...in 循环用于遍历对象 obj 的属性。在每次迭代中,循环变量 key 会分别被赋值为对象的每个属性的键。通过 obj[key] 可以访问到对应属性的值。

循环的输出将是:

name: John
age: 25
city: New York

需要注意的是,for...in 循环会迭代对象自身可枚举的属性,以及从原型链中继承的属性。如果你只关心对象自身的属性,可以结合使用 hasOwnProperty() 方法来进行判断:

for (let key in obj) {
  if (obj.hasOwnProperty(key)) {
    console.log(key + ': ' + obj[key]);
  }
}

hasOwnProperty() 方法是 JavaScript 内置的对象方法,用于检查对象是否具有指定的属性。通过这种方式,可以过滤掉从原型链继承的属性,只遍历对象自身的属性。

需要注意的是,for...in 循环的遍历顺序是不确定的,因为对象的属性在内部存储时是无序的。如果需要按特定顺序遍历属性,可以考虑使用其他方法,如 Object.keys() 结合数组的遍历方法。

this指向

在 JavaScript 中,关键字 this 用于引用当前执行上下文中的对象。它的具体指向取决于函数的调用方式和上下文。

以下是几种常见情况下 this 的指向:

  1. 全局上下文:在全局作用域中,函数直接被调用时,this 指向全局对象(在浏览器中通常是 window 对象)。
console.log(this); // 指向全局对象 (window)
  1. 函数调用:当函数作为独立函数调用时,this 指向全局对象(非严格模式下),或者是 undefined(严格模式下)。
function myFunction() {
  console.log(this);
}

myFunction(); // 在浏览器中指向全局对象 (window) 或者 undefined (严格模式)
  1. 方法调用:当函数作为对象的方法调用时,this 指向调用该方法的对象。
const obj = {
  name: 'John',
  sayHello: function() {
    console.log(this.name);
  }
};

obj.sayHello(); // 指向 obj 对象,输出 "John"
  1. 构造函数:当函数作为构造函数使用时(使用 new 关键字创建对象),this 指向新创建的对象。
function Person(name) {
  this.name = name;
}

const john = new Person('John');
console.log(john.name); // 输出 "John"
  1. 显式绑定:通过 call()apply() 或 bind() 方法,可以显式地指定函数的 this 值。
function greet() {
  console.log('Hello, ' + this.name);
}

const obj = {
  name: 'John'
};

greet.call(obj); // 使用 call() 显式绑定,输出 "Hello, John"

需要注意的是,箭头函数(=>)具有词法作用域的 this,它会继承外部函数的 this 值,而不是根据调用方式来确定 this

原型、原型链

在JavaScript中,每个对象都有一个原型(prototype)

下面是一个示例来说明原型和原型链的概念

// 定义一个构造函数
function Person(name) {
  this.name = name;
}

// 在构造函数的原型上定义一个方法
Person.prototype.sayHello = function() {
  console.log('Hello, ' + this.name);
};

// 创建一个实例
const john = new Person('John');

// 调用实例的方法
john.sayHello(); // 输出 "Hello, John"

// 检查属性和方法的来源
console.log(john.hasOwnProperty('name')); // true
console.log(john.hasOwnProperty('sayHello')); // false
console.log(john.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Object.prototype.__proto__); // null

在上述示例中:

  • Person 是一个构造函数Person 对象
  • Person.prototype 是原型对象,包含了sayHello 方法。
  • john 是通过 Person 构造函数创建的实例对象。
  • john.sayHello() 调用了 Person.prototype 上的 sayHello 方法。
  • hasOwnProperty() 方法用于检查属性
  • __proto__ 属性用于访问对象的原型。