JavaScript:对象

简介: JavaScript:对象

对象是什么

对象的定义

对象是 JavaScript 数据类型的一种,之前已经学习了数值类型、字符串类型、布尔类型、undefined。对象数据类型可以被理解成是一种数据集合。

对象数据类型,有点类似于数组,它是多个数据的集合,不同的是,对象内部的数据,都是对这个对象的描述,先为大家展示一个对象:

let person = {
            name: "张三",
            age: 18,
            dance: function(){
                document.write("张三会跳舞");
            },
            cook: function(){
                document.write("张三会做饭");
            }
        }

这是一个名为person的对象,它内部有四个属性,分别是name,age,以及cook函数,dance函数。这四个属性都是对这个person对象的描述,代表其名字为张三,十八岁,会做饭,会跳舞。

其中,后两个函数,一般不称为属性,而称为方法。


对象的组成

对象由其内部的属性和方法组成,属性就是一些基础数据,而方法本质就是一些函数,当我们使用这个对象的时候,就可以执行它的某一个函数,比如我们在刚刚的对象中,可以调用它的函数dance,这样屏幕就会输出一句”张三会跳舞“。可以把输出这句话的功能,称之为这个对象的方法。


对象的使用

对象声明

那么我们要如何声明一个对象?我们有两种方式:直接声明和利用函数声明。

利用函数声明

语法:let 对象名 = new Object()

由于对象也是一个数据类型,和其它数据类型一样,需要使用let,var,const这种关键字。

这种函数方法其实不常用,以上语法会得到一个空对象,也就是其内部没有任何属性,不过后续有增加属性的方法,不必担心,在此不对此方法过多赘述了。

直接声明

语法:

let 对象名 = {
            属性1: 属性值1,
            属性2: 属性值2
        }

这种直接声明的方式,和数组十分类似,我们只需用一个大括号把对象的属性括起来,每两个属性之间用逗号隔开即可。这样我们就可以得到一个初始化过的对象,当然,你也可以一个属性值都不写,直接得到一个空对象。


访问对象

既然我们得到了一个对象,我们就需要访问这个对象的值,就好比得到了一个数组,我们也需要去访问数组的元素。

访问对象有两种方法:对象名.属性对象名['属性']

对象名.属性

示例:

我们在此访问person这个对象,获取它的name属性,通过对象名.属性,即person.name就可以得到张三这个值。

对象名['属性']

我们再利用另一个方法访问一下age这个属性:

可以发现我们一样访问到了属性的值,这里要十分注意[]内部的属性要加上引号,单引号或双引号都可以。

那么为什么需要两种方法呢?

我们为person这个对象在加一个属性:previous-name:"张四"来代表曾用名:

报错了,说明这个语法是有问题的,当我们的属性名字太长,需要使用特殊符号来区分的时候,需要为其加上引号:

加上引号后,这个报错就消失了,此时的previous-name:"张四"是合法的。

尝试以不同方式访问这个previous-name

这里一共用了四种方式访问,主要问题在于,访问时要不要加引号?用哪种方式访问?

首先person.'previous-name'已经报错,毫无疑问是不行的,删除后再执行一次:

运行后,程序报错了:第25行的previous没有定义,这里不加引号就已经违背基础语法了,报错是毫无疑问的。把它注释掉,再执行一次:

用一个点访问的方式全军覆没了,不论加不加引号,解析都会有问题。

最后得出结论,这种带有特殊字符,需要用引号引起的属性名,必须使用中括号的形式来访问

两种方法都有自己的应用面,都非常重要。


对象方法的调用

我们刚刚的访问,都是基于对象的属性,没有访问对象的后两个方法,因为方法的本质是函数,函数调用又是额外的语法:对象名.方法名(函数参数)对象名['方法名'](函数参数)

分析一下,其实不难发现,相比于访问对象的属性,调用对象的方法只是在访问完毕后,加上一个调用函数的小括号而已,而函数的传参是在小括号里面也不难理解。

示例:

最后函数都正常执行了,也就是方法成功调用了。


增加与改变对象属性

增加或改变对象的属性,语法是完全一致的,只需要直接赋值即可,当被赋值的属性在对象中存在,那么可以直接修改;如果被赋值的属性在对象中不存在,那么就会增加这个属性。

示例:

原先age是存在的,于是person.age = 20;就直接修改了age属性的值;

原先weight不存在,于是person.weight = "100kg";增加了该属性。


删除对象属性

删除对象的属性,需要用到关键字delete,语法:delete 对象名.属性名或者delete 对象名['属性名'],这样就能删除对应的对象。

示例:

最后,age属性和previous-name属性都被删掉了。


遍历对象

对象和数组很像,我们在遍历数组的时候,往往是利用下标来一个个访问,但是对象没有下标,该如何访问?

首先介绍一个for in语句,它可以遍历数组:

我们利用for in语句,可以在每一次循环时,为k一次赋值一个下标,那么我们遍历数组只需要arr[k]就可以了:

我们成功输出了这个数组的所有值。

这个for in语句对对象同样生效:

我们利用for in语句,让k每次循环,都得到一个属性名,但是,我们检测k的类型后,发现它是string类型。这说明,k并不直接等于属性名,而是属性名的字符串形式,也就是 k = “属性名” 。这十分重要,因为这意味着我们无法通过属性名.k的形式来获得对应的属性,因为自带一对引号。所以我们要使用属性名[k]的形式,由于k自带引号,无需在对k加引号。

示例:

这样我们就通过for in语句遍历了整个对象的所有属性。


内置对象

对象不仅可以我们自己创建,JavaScript还提供了丰富的内置对象,我们需要时可以直接调用。

回想一下我们曾经使用过的 console.logconsole其实就是 JavaScript 中内置的对象,该对象中存在一个方法叫 log,然后调用 log 这个方法,即 console.log()

除了 console 对象外,JavaScritp 还有其它的内置的对象

在此我介绍一个Math对象。

Math对象

Math 是 JavaScript 中内置的对象,称为数学对象,这个对象下即包含了属性,也包含了许多的方法。

属性
  • Math.PI,获取圆周率
console.log(Math.PI);

调用得到:3.141592653589793

方法
  • Math.random,生成 0 到 1 间的随机数
Math.random()

0 ~ 1 之间的随机数, 包含 0 不包含 1


  • Math.ceil,数字向上取整
Math.ceil(3.4)

舍弃小数部分,整数部分加1


  • Math.floor,数字向下取整
Math.floor(4.68)

舍弃小数部分,整数部分不变


  • Math.round,四舍五入取整
Math.round(5.46539)
Math.round(4.849)

取整,四舍五入原则


  • Math.max,在一组数中找出最大的
Math.max(10, 21, 7, 24, 13)

  • Math.min,在一组数中找出最小的
Math.min(24, 18, 6, 19, 21)

  • Math.pow,幂方法
Math.pow(4, 2) // 求 4 的 2 次方
Math.pow(2, 3) // 求 2 的 3 次方

求某个数的多少次方


  • Math.sqrt,平方根
Math.sqrt(16)

求某数的平方根


数学对象提供了比较多的方法,这里不要求强记,通过演示数学对象的使用,加深对对象的理解。

在此我们特地讲解一下生成指定随机数的方法:

随机数生成方法:

在调用random方法的时候,会得到一个[0,1)的随机数,如果我们对其乘以N,那么就能得到[0,N)的随机数,也就是Math.random() * N

但是这样的随机数是包括小数的,此时我们就需要对这个结果取整,得到[0,N)的随机整数,即Math.floor(Math.random() * N)

如果我们想得到[M,N]的整数,就是Math.floor(Math.random() * (N - M)) + N,在此不过多推算了。


JavaScript对内存的分配

JavaScript中,主要有两个内存区域:栈区和堆区。而不同的数据类型,对内存的使用是不同的,主要区别为简单类型和复杂类型。

简单数据类型的内存分配

对于简单类型的数据,比如Number,Boolean,String,Undefined。

它们数据存储于栈区中,我们使用的变量,本身指向这个数据。

对于这样一串代码:

let a = 5;
  let b = false;
  let c = undefined;
  let d = "1234";

它的内存分配是这样的:


复杂数据类型的内存分配

对于复杂数据类型,比如对象,它会由两部分组成,分别是栈区的变量索引,以及堆区的数据实体。

比如对于下面的代码:

let person = {
    name: "张三",
    age: 18,
  }

它的内存分配是这样的:

那么这两种内存分配有啥区别?

首先明确一点,我们操作的变量,其数据是栈区的数据。

当我们进行变量赋值的时候,就会发生区别:

let a = 5;
let b = a;

这个过程中,a在栈区中的数据是5,于是b就得到5这个值:

而对于复杂数据类型:

let person = {
  name: "张三",
  age: 18,
}
let person2 = person;

person变量在栈区中的数据是指向堆区的索引,于是person2就得到了这个索引:

由于索引与person一致,所以最终person2和person指向同一个对象。

执行以下代码

let person = {
  name: "张三",
  age: 18,
}
let person2 = person;
delete person2.name;
console.log(person);

输出结果如何呢?

由于person2与person指向同一个对象,最后对person2改变,person也会改变:

最后person的name属性也没有了。


相关文章
|
16小时前
|
JavaScript 前端开发
js用Date对象处理时间
以上就是JavaScript中Date对象处理时间的一些基本方法。
5 0
|
16小时前
|
JavaScript 前端开发
在JavaScript中,函数原型(Function Prototype)是一个特殊的对象
【5月更文挑战第11天】JavaScript中的函数原型是一个特殊对象,它为所有函数实例提供共享的方法和属性。每个函数在创建时都有一个`prototype`属性,指向原型对象。利用原型,我们可以向所有实例添加方法和属性,实现继承。例如,我们定义一个`Person`函数,向其原型添加`greet`方法,然后创建实例`john`和`jane`,它们都能调用这个方法。尽管可以直接在原型上添加方法,但推荐在构造函数内部定义以封装数据和逻辑。
10 2
|
16小时前
|
JavaScript 前端开发
JavaScript 提供了多种方法来操作 DOM(文档对象模型)
【5月更文挑战第11天】JavaScript 用于DOM操作的方法包括获取元素(getElementById, getElementsByClassName等)、修改内容(innerHTML, innerText, textContent)、改变属性、添加/删除元素(appendChild, removeChild)和调整样式。此外,addEventListener用于监听事件。注意要考虑兼容性和性能当使用这些技术。
6 2
|
16小时前
|
存储 JavaScript 前端开发
JavaScript对象方法详解
JavaScript对象方法详解
16 1
|
16小时前
|
JavaScript
js多维数组去重并使具有相同属性的对象数量相加
js多维数组去重并使具有相同属性的对象数量相加
11 1
|
16小时前
|
前端开发 JavaScript 数据安全/隐私保护
前端javascript的DOM对象操作技巧,全场景解析(二)
前端javascript的DOM对象操作技巧,全场景解析(二)
|
16小时前
|
移动开发 缓存 JavaScript
前端javascript的DOM对象操作技巧,全场景解析(一)
前端javascript的DOM对象操作技巧,全场景解析(一)
|
16小时前
|
缓存 编解码 自然语言处理
前端javascript的BOM对象知识精讲
前端javascript的BOM对象知识精讲
|
16小时前
|
JavaScript 前端开发
JavaScript 日期对象
JavaScript 日期对象
|
16小时前
|
存储 JavaScript 前端开发
JavaScript对象
JavaScript对象