JavaScript学习笔记(一) 对象

简介: JavaScript学习笔记(一) 对象

对象是属性的无序集合,所谓的属性其实也就是我们常用的键值对类型


1、创建对象


(1)对象直接量


对象直接量由若干组键值对组成,键与值之间用冒号分隔,键值对之间用逗号分隔,所有键值对用大括号括起来

其中,对象直接量中的键可以是任意字符串,值可以是任何数据类型

但是需要注意,如果键是一个合法的标识符并且不是一个保留字,那么允许不加引号,反之必须要加括号

var person = {
    name: {
        'first-name': 'Steve',
        'last-name': 'Jobs'
    },
    isMale: true,
    age: 48
}


(2)new Object()


可以使用 new 运算符加上 Object 构造函数创建一个对象

var emptyObject = new Object() // 创建一个空对象


(3)Object.create()


可以使用 Object 对象的内置方法创建一个对象,传入一个原型对象作为新创建对象的原型

var emptyObject = Object.create(Object.prototype) // 创建一个空对象


2、属性访问与设置


(1)属性访问


有两种方式可以获取属性的值,一是使用方括号运算符,二是使用点运算符,两者都是 通过键索引值


  • 方括号运算符([]):方括号运算符内可以是表达式,表达式必须返回一个可以转换为字符串的值
  • 点运算符(.):点运算符右侧必须是一个标识符,标识符必须是合法的且不是一个保留字
> var person = {
    name: {
        'first-name': 'Steve',
        'last-name': 'Jobs'
    },
    isMale: true,
    age: 48
}
> person['name']
// { 'first-name': 'Steve', 'last-name': 'Jobs' }
> person['name']['first-name']
// 'Steve'
> person.name
// { 'first-name': 'Steve', 'last-name': 'Jobs' }
> person.name.first-name
// ReferenceError: name is not defined


如果在对象的自有属性和继承属性中都没有找到指定的键,那么就会返回 undefined

什么是对象的自有属性和继承属性?

  • 自有属性:直接在对象中定义的属性
  • 继承属性:在对象的原型对象中定义的属性
> person.alias
// undefined

⭐ 小技巧:使用 || 运算符设置默认值,可以避免直接返回 undefined

> person.alias || 'alias'
// 'alias'


如果对象不存在,那么就会报一个 TypeError 的错误

> person['alias']['first-name']
// TypeError: Cannot read property 'first_name' of undefined


⭐ 小技巧:使用 && 运算符设置短路条件,可以避免程序直接报错

> person && person['alias'] && person['alias']['first-name']
// undefined


(2)属性设置


如果对象中存在指定的键,那么更新其值;如果没有指定的键,那么新的属性将会添加到对象中

> person.age = 49
> person.age
// 49
> person.alias = 'Stephen'
> person.alias
// 'Stephen'


这里给大家出一道题目,请写出下面程序的执行结果

let a = { a: 10 }
let b = { b: 10 }
let c = { a: 10 }
c[b] = 20
console.log(c[a])


输出的结果是 20,大家答对了吗

程序的前三条赋值语句不难理解,解题的关键在于 c[b] = 20

由于变量 b 被定义为对象,因此它需要先转化为字符串才能作为对象的属性使用

所以,赋值的结果应该是 c['[object Object]'] = 20

同理的道理,变量 a 也被定义为对象,因此它也需要先转化为字符串才能作为对象的属性使用

所以,访问的语句其实是 c['[object Object]']


3、属性检测与遍历


(1)属性检测


JavaScript提供三种方法 检测某个属性是否在特定的对象中,但是它们之间也有一些区别:

  • in:检测指定属性是否为特定对象的自有属性或继承属性
  • hasOwnProperty():检测指定属性是否为特定对象的自有属性
  • propertyIsEnumerable():检测指定属性是否为特定对象的自有属性,并且其可枚举性为 true


什么是属性的可枚举性?

属性的特性之一,用来描述属性是否可以用一般的遍历操作获取到值


> var person = {
    name: {
        'first-name': 'Steve',
        'last-name': 'Jobs'
    },
    isMale: true,
    age: 48
}
> 'name' in person // name 属性存在于自有属性
// true
> 'toString' in person // toString 属性存在于继承属性
// true
> 'fabrication' in person // fabrication 属性既不存在于自有属性,也不存在于继承属性
// false


(2)属性遍历


既然讲到属性的可枚举性,这里顺便提一下如何 遍历对象的属性,JavaScript 同样提供三种方法遍历属性:

  • for/in:遍历对象所有可枚举的属性,包括自有属性和继承属性
  • Object.keys():返回一个数组,数组中的元素是对象中可枚举的自有属性的名称
  • Object.getOwnPropertyNames():返回一个数组,数组中的元素是对象中所有自有属性的名称


> var person = {
    name: {
        'first-name': 'Steve',
        'last-name': 'Jobs'
    },
    isMale: true,
    age: 48
}
> Object.defineProperty(person, 'isMale', {
    enumerable: false // 将 person 对象的 isMale 属性设为不可枚举
})
> for (var prop in person) {
    console.log(prop)
}
// name
// age
> Object.keys(person)
// [ 'name', 'age' ]
> Object.getOwnPropertyNames(person)
// [ 'name', 'isMale', 'age' ]


4、存取器属性


好,现在我们重新总结一下什么是对象的属性?对象的属性是由键、值、特性三个部分组成的

其中,属性的值可以用一个或两个方法代替,这些方法就是 getter 和 setter 方法


如果属性同时具有 getter 和 setter 方法,那么它是一个读/写属性

如果属性只有 getter 方法,那么它是一个只读属性,设置只读属性不起作用

如果属性只有 setter 方法,那么它是一个只写属性,读取只写属性总是返回 undefined


由这两个方法定义的属性称为 存取器属性,而其它由简单的值定义的属性称为 数据属性

> var square = {
    // 数据属性
    x: 5.0,
    // 存取器属性
    get area(){ // 当读取存取器属性的值时,调用 getter 方法
        console.log('I am in getter')
        return Math.pow(this.x, 2)
    },
    set area(value){ // 当设置存取器属性的值时,调用 setter 方法
        console.log('I am in setter')
        this.x = Math.sqrt(value)
    }
}
> square.area
// I am in getter
// 25
> square.area = 16
// I am in setter
> square.x
// 4


5、属性的特性


(1)属性的特性


除了在前文提到的可枚举性之外,对象的属性还有其它的特性,比如说可枚举性、可配置性等等

如果我们把数据属性的值看作是一个特性,那么数据属性总有具有四个特性,分别是

  • 值(value):数据属性的值,默认为 undefined
  • 可写性(writable):是否可以修改属性的值,默认为 true
  • 可枚举性(enumerable):是否可以通过 for/in 循环获取到值,默认为 true
  • 可配置性(configurable):是否可以删除和修改属性,默认为 true

如果我们把存取器属性的 getter 和 setter 方法也看作是特性,那么存取器属性同样具有四个特性,分别是

  • 读取(getter):在读取属性时调用的函数,默认为 undefined
  • 设置(setter):在设置属性时调用的函数,默认为 undefined
  • 可枚举性(enumerable):是否可以通过 for/in 循环获取到值,默认为 true
  • 可配置性(configurable):是否可以删除和修改属性,默认为 true

至此,我们对属性又有一个不同的理解:对象的属性是由一个名字(键)和四个特性组成的


(2)属性描述符


可以使用属性描述符(property descriptor)对属性特性进行查询和设置操作

属性描述符是一个对象,这个对象的属性与它们描述的特性是同名的


  • 可以使用 Object.getOwnPropertyDescriptor() 方法获取自有属性的描述符
> var square = {
    // 数据属性
    x: 5.0,
    // 存取器属性
    get area(){
        console.log('I am in getter')
        return Math.pow(this.x, 2)
    },
    set area(value){
        console.log('I am in setter')
        this.x = Math.sqrt(value)
    }
}
> Object.getOwnPropertyDescriptor(square, "x") // 数据属性
// { value: 5, writable: true, enumerable: true, configurable: true }
> Object.getOwnPropertyDescriptor(square, "area") // 存取器属性
// {
//     get: [Function: get area],
//     set: [Function: set area],
//     enumerable: true,
//     configurable: true
// }


  • 可以使用 Object.defineProperty() 方法设置属性的特性
> var square = {}
> Object.defineProperty(square, 'x', { // 数据属性的属性描述符对象
    value: 5,
    writable: true,
    enumerable: true,
    configurable: true
})
> Object.defineProperty(square, 'area', { // 存取器属性的属性描述符对象
    get: function() { return Math.pow(this.x, 2) },
    set: function(value) { this.x = Math.sqrt(value) },
    enumerable: true,
    configurable: true
})



目录
相关文章
|
1天前
|
JSON JavaScript 数据格式
1.js动态的往json数据添加新属性和值 2.JSON 和 JS 对象互转 3.对象转化为数组
1.js动态的往json数据添加新属性和值 2.JSON 和 JS 对象互转 3.对象转化为数组
|
11天前
|
XML JavaScript 前端开发
JavaScript简介&引入方式(JavaScript基础语法、JavaScript对象、BOM、DOM、事件监听)
JavaScript简介&引入方式(JavaScript基础语法、JavaScript对象、BOM、DOM、事件监听)
13 2
|
12天前
|
Web App开发 JavaScript 前端开发
JavaScript 中的 Range 和 Selection 对象
JavaScript 中的 `Range` 和 `Selection` 对象用于处理文本选择。`Range` 表示文档中选定的区域,而 `Selection` 表示用户选择的文本或光标位置。`Range` 可以创建并设置于任何元素或文本,具有多个属性(如 `startContainer`, `endContainer`, `collapsed`)和方法(如 `cloneContents`, `deleteContents`)。`Selection` 提供了获取和操作用户选择的方法,如 `anchorNode`, `focusNode` 和 `addRange`。两者在所有现代浏览器中基本兼容。
5 1
JavaScript 中的 Range 和 Selection 对象
|
14天前
|
JSON JavaScript 安全
向js发送含有NSDictionary对象或NSArray对象的消息
向js发送含有NSDictionary对象或NSArray对象的消息
25 0
|
15天前
|
前端开发 JavaScript
前端 JS 经典:判断对象属性是否存在
前端 JS 经典:判断对象属性是否存在
20 0
|
18天前
|
JSON 前端开发 JavaScript
前端 JS 经典:JSON 对象
前端 JS 经典:JSON 对象
19 0
|
18天前
|
前端开发 JavaScript
前端 js 经典:原型对象和原型链
前端 js 经典:原型对象和原型链
25 1
|
19天前
|
JavaScript 前端开发 流计算
使用JavaScript 中的Math对象和勾股定理公式,计算鼠标的位置与页面图片中心点的距离,根据距离对页面上的图片进行放大或缩小处理
使用JavaScript 中的Math对象和勾股定理公式,计算鼠标的位置与页面图片中心点的距离,根据距离对页面上的图片进行放大或缩小处理
|
19天前
|
JSON JavaScript 前端开发
js将json字符串还原为json对象
【5月更文挑战第14天】js将json字符串还原为json对象
45 1
|
19天前
|
设计模式 存储 消息中间件
JavaScript观察者模式:实现对象间的事件通信!
JavaScript观察者模式:实现对象间的事件通信!