您的位置:首页 > 科技 > 能源 > JavaScript对象

JavaScript对象

2024/10/5 19:13:17 来源:https://blog.csdn.net/m0_61619549/article/details/140891229  浏览:    关键词:JavaScript对象

概述

在JavaScript中有一句颇有争议的话  ——   “一切皆对象”

这个观念是JavaScript设计哲学的一个重要部分,它让JavaScript在编程时提供了极大的灵活性和表达能力。

虽然在JS中确实几乎所有的东西都可以被视为对象,但有几个核心概念需要明确:

  • 原始类型:JS中的基本数据类型本身不是对象。但某些时候,JS会临时将它们包装成对象(除了null和undefined),比如,当它们被用作对象时(例如,通过调用方法)

      字符串"hello"可以调用.length属性,实际上是JS内部将其临时转换成了String对象。

let str = 'hello'
console.log(str.length) //5
  • 函数:在JS中,函数也是对象。这意味着函数可以拥有属性和方法。这是JS实现高阶函数(接受函数作为参数或返回函数的函数)和闭包等强大的编程模式的支撑。

  • 内置对象:JS还提供了许多内置对象,如Array、Date、RegExp等,这些内置对象提供了丰富的功能,使得开发者可以轻松地处理数组、日期、正则表达式等。

关于对象包装:

  1. 原始包装对象:对于基本数据类型(数字、字符串、布尔值等),JS会临时使用它们的包装对象版本(如NumberStringBoolean),以便你可以访问它们的方法(如.toString().length等)。但是,这些包装对象是临时的,只在访问方法时存在,之后就会被丢弃
  2. null 和 undefined:对于nullundefined,它们没有对应的原始包装对象。因此,当你尝试对nullundefined使用属性访问操作符时,JS无法将它们转换为对象,从而会抛出一个TypeError

基础

对象的创建

JS提供了两种创建对象的主要方式:

  1. 对象字面量:通过{  }直接定义对象的属性和方法

    let person = {name: 'Alice',age: 30
    }
  2. 构造函数(Constructor):通过定义构造函数(用于初始化新创建对象的函数),并使用new关键字创建对象实例

    function Person(name, age) {this.name = namethis.age = age
    }
    let person = new Person('Bob', 25)

对象的嵌套

对象的属性可以是原始数据类型,也可以是一个对象(包括函数数组等)

let person = {name: 'IKUN',work: {skill: '摸鱼'},greet: function () {console.log(`Hello, my name is ${this.name}.`)}
}
console.log(person.work.skill) //摸鱼
person.greet() //Hello, my name is IKUN

对象的属性访问

运算符( . )表示getattr(访问)的意思;通常,使用[ ]访问时需要加引号。

添加
let person = {}
person.name = 'IKUN'
person['skill'] = '守护最好的KUNKUN'
console.log(person.name) //IKUN
console.log(person['skill']) //守护最好的KUNKUN
修改
let person = {naem: 'IkUN',skilk: '守护最好的KUNKUN'
}
person.name = 'KUNKUN'
person['skill'] = '打篮球'
console.log(person.name) //KUNKUN
console.log(person['skill']) //打篮球
删除
let person = {name: 'IkUN',skill: '守护最好的KUNKUN'
}
delete person.name// 删除name属性
delete person['skill'] // 删除skill属性
delete person.gender // 删除一个不存在的gender属性也不会报错
判断是否拥有某属性

1.in操作符        不过这个属性不一定是对象自身的,它可能是继承得到的

let person = {name: 'IkUN',
}
console.log('name' in person) // true
console.log('age' in person) // false

2.hasOwnProperty()        检查对象自身(不包括原型链)是否具有指定的属性

let person = {name: 'IkUN'
}
console.log(person.hasOwnProperty('name')) // true
console.log('toString' in person) // true
console.log(person.hasOwnProperty('toString')) // false

​​​​​​​进阶

原型对象

JS对象可以从一个“称为原型” 的对象里继承属性和方法。这种”原型链继承“是 JS 的核心特征之一

参考

​​​​​​JavaScript函数-CSDN博客  ——  “构造函数 ”

静态方法与实例方法
  1. 静态方法:定义在构造函数本身上的方法,它不能通过实例来调用,只能通过类本身来调用。静态方法通常用于实现与类本身相关的功能,比如工具类。
  2. 实例方法:实例对象从原型对象(prototype)上继承来的方法,可以由实例调用(通过原型链访问)。实例方法通常用于操作实例的属性或执行与实例相关的操作。

function Person(name) {this.name = name // 实例属性
}
// 静态方法
Person.staticMethod = function () {console.log('这是一个静态方法')
}
// 原型对象方法(实例方法)
Person.prototype.greet = function () {console.log(`Hello, my name is ${this.name}`)
}
// 使用
const person1 = new Person('Alice')
person1.greet() // 调用实例方法
// Person.greet(); // 错误,不能通过类直接调用实例方法
Person.staticMethod() // 调用静态方法
// person1.staticMethod(); // 错误,静态方法不能通过实例调用

        属性同理 —— 实际上对象的方法可以看作是对象属性的一种

 对象的常用方法

1.Object.assign()       

将所有可枚举的自有属性的值从一个或多个对象复制到目标对象,并返回目标对象。

 语法:

Object.assign(target, source1,source1....)
  • target: 目标对象
  • source: 源对象,其可枚举的自有属性将被复制到目标对象上

 示例:

const target = { a: 1, b: 2 }
const source1 = { b: 4, c: 5 }
const source2 = { c: 6 }
const returnedTarget = Object.assign(target, source1, source2)
console.log(target)
// 输出: Object { a: 1, b: 4, c: 6 }
console.log(returnedTarget)
// 输出: Object { a: 1, b: 4, c: 6 }
// 注意,`Object.assign()` 改变了 `target` 对象
//,并且 `target` 和 `returnedTarget` 指向同一个对象。
  1. Object.assign() 执行的是浅拷贝,如果对象的属性值是引用数据类型,那它只拷贝地址。
  2. 如果source或target不是对象,则会先将其转换为一个对象。如果是 null 或 undefined,则会抛出一个 TypeError,因为 null 和 undefined 不能被转换为对象。

  3. 如果多个source具有相同的属性,则后面的source会覆盖前面的source中的属性值。

  4. Object.assign() 会复制source的所有自有属性,包括字符串和符号属性名。

2.Object.create()

指定一个对象作为新创建对象的原型链的起点。新对象将继承指定原型对象的属性和方法。

 语法:

const newObject = Object.create(proto[, propertiesObject])
  • proto:新创建对象的原型对象
  • propertiesObject(可选):一个对象,其属性描述符将会被添加到新创建的对象上,这些属性对应新对象的自身属性(即非继承自原型的属性)

示例:

// 创建一个空对象,其原型为null
const obj1 = Object.create(null)
console.log(obj1.hasOwnProperty) // undefined,因为obj1没有原型// 创建一个对象,其原型为另一个对象
const personProto = {isHuman: true,printIntroduction: function () {console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`)}
}
// 使用propertiesObject来定义新对象的自身属性
const properties = {name: {value: 'John',writable: true,enumerable: true,configurable: true}
}
// 创建新对象,其原型为personProto,并添加name属性
const john = Object.create(personProto, properties)
john.printIntroduction()
// 预期输出: "My name is John. Am I human? true"
  1. Object.create(null) ,得到一个没有原型的对象,它不会有任何继承自Object.prototype的方法,如hasOwnProperty、toString等。这在某些需要避免继承自Object.prototype的默认属性和方法的场景中很有用。

3.Object.defineProperty() 

直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。这个方法允许你精确地添加或修改对象的属性。

语法:

Object.defineProperty(obj, prop, descriptor)
  • obj:要定义属性的对象
  • prop:要定义或修改的属性的名称或Symbol
  • descriptor:将被定义或修改的属性描述符

   属性描述符(可包含以下之一或多个

  • value:属性的值。
  • writable:当且仅当该属性的值可以被改变时为true
  • configurable:当且仅当该属性的描述符可以被改变,且该属性可以从对应的对象中被删除时为true
  • enumerable:当且仅当该属性出现在对象的枚举属性中时为true
  • get:作为该属性的 getter 函数,如果没有 getter 则为undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入this值(即被访问的对象)。
  • set:作为该属性的 setter 函数,如果没有 setter 则为undefined。当属性值被修改时,会调用此函数。该函数将接收唯一参数,即被赋予的新值。

示例:

const person = {firstName: 'John',lastName: 'Doe',fullName: ''
}
//writable属性描述符
Object.defineProperty(person, 'age', {value: 18,writable: false
})
console.log(person.age) // 18
// 尝试修改属性失败,因为writable为false
person.age = 22
console.log(person.age) // 仍然是18
//getter和setter
Object.defineProperty(person, 'fullName', {get: function () {return `${this.firstName} ${this.lastName}`},set: function (value) {;[this.firstName, this.lastName] = value.split(' ')}
})
console.log(person.fullName) // John Doe
person.fullName = 'Alice Idorila '
console.log(person.firstName) // Alice
console.log(person.lastName) // Idorila
4.Object.defineProperties() 

语法与 Object.defineProperty() 方法基本一样,不同的是,Object.defineProperties() 可以一次定义或修改多个属性。

var obj = {};
Object.defineProperties(obj, {'property1': {value: true,writable: true},'property2': {value: 'Hello',writable: false}
});
console.log(obj); //  property1: true  property2: "Hello"
5.Object.keys()

返回一个数组,包含对象自身(不含继承)所有可枚举属性(不包括 Symbol 类型的属性)的键名。

这个方法在需要遍历对象的键或获取对象的所有键名时非常有用。

语法:

​Object.keys(obj)
  •  obj : 目标对象

示例:

const person = {firstName: 'John',lastName: 'Doe',age: 30,[Symbol.for('id')]: 12345
}
console.log(Object.keys(person))
// 输出: ["firstName", "lastName", "age"]
// 注意:Symbol 类型的属性不会被包括在内
6.Object.values()

返回一个数组,包含对象自身的所有可枚举属性的值。

这个方法允许你轻松地获取对象属性的值数组,而无需手动遍历对象的键。

语法:

​Object.keys(obj)
  •  obj : 目标对象

 示例:

const person = {name: 'John',age: 30,city: 'New York'
}
console.log(Object.values(person))
// 输出: ["John", 30, "New York"]
7.Object.entries()

返回一个数组,包含对象自身可枚举属性的键值对。

其排列与使用 for...in 循环遍历对象时返回的顺序一致(两者的主要区别是 for...in 循环还会枚举其原型链上的属性)。

语法:

Object.entries(obj)
  • obj:目标对象

示例:

const object1 = {a: 'somestring',b: 42,c: false
}
console.log(Object.entries(object1))
// 输出: [ ['a', 'somestring'], ['b', 42], ['c', false] ]
// 可以通过解构赋值来提取键和值
for (let [key, value] of Object.entries(object1)) {console.log(`${key}: ${value}`)
}
// 输出:
// a: somestring
// b: 42
// c: false
// 映射对象的值到一个新数组
const values = Object.entries(object1).map(([key, value]) => value)
console.log(values)
// 输出: ['somestring', 42, false]
7.Object.is()​​​​​​​

用于确定两个值是否相同。这个方法与严格相等运算符(===)非常相似,但在处理 +0 和 -0,以及 NaN 时有所不同。

语法:

Object.is(value1, value2)

与 === 的区别

  1. 处理 NaN
    • Object.is(NaN, NaN) 返回 true,因为按照 ECMAScript 规范,NaN 被视为与自身相等的唯一值。
    • NaN === NaN 返回 false,因为严格相等运算符认为 NaN 不等于自身。
  2. 处理 +0 和 -0
    • Object.is(+0, -0) 返回 false,因为 +0 和 -0 被视为不同的值。
    • +0 === -0 返回 true,因为严格相等运算符认为 +0 和 -0 是相等的。

示例:

console.log(Object.is(NaN, NaN)) // true
console.log(NaN === NaN) // false
console.log(Object.is(+0, -0)) // false
console.log(+0 === -0) // true
console.log(Object.is(42, 42)) // true
console.log(42 === 42) // true
console.log(Object.is('foo', 'foo')) // true
console.log('foo' === 'foo') // true
console.log(Object.is(true, true)) // true
console.log(true === true) // true
console.log(Object.is(Object.create(null), Object.create(null))) // false
console.log(Object.create(null) === Object.create(null)) // false
8.hasOwnProperty()

判断一个对象自身(不包括其原型链)是否含有指定的属性。

示例:判断是否拥有某属性

9.isPrototypeOf()

判断当前对象是否为另一个对象的原型链中的的原型对象。

 语法:

prototypeObject.isPrototypeOf(object)
  • prototypeObject:需要判断是否为原型的对象。
  • object:需要检查其原型链中是否包含 prototypeObject 的对象。

示例:

function Person(name) {this.name = name
}
let person1 = new Person('Alice')
console.log(Person.prototype.isPrototypeOf(person1)) // true
console.log(Object.prototype.isPrototypeOf(person1)) // true
console.log(Function.prototype.isPrototypeOf(Person)) // true

---------------------------------------------------------------------------------------------------------------------------------

如有不足或遗漏,烦请私信或评论留言

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com