手记

理解JavaScript的对象

本章学习内容

  • 对象概念
  • 创建对象
  • 理解对象

一、对象概念

这小节主要需要理解一下对象的知识概念。

1.1.什么是对象?

在软件系统中,对象具有唯一的标识符,对象包括属性和方法,属性就是需要记忆的信息,方法就是对象能够提供的服务。

1.2.什么是面向对象程序设计?

面向对象程序设计是是一种程序开发的抽象方针,它可能包含数据、属性、代码与方法;面向对象具有封装,继承,多态特征。

在面向对象的软件中,对象是某一个类的实例,它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的重用性、灵活性和扩展性,对象里的程序可以访问及经常修改对象相关连的数据。

1.3.javascript引用类型

引用类型的值(对象)是引用类型的一个实例。有时候也被称为对象定义,因为它们描述的是一类对象所具有的属性和方法。

引用类型的值是保存在内存中的对象。与其他语言不同,JavaScript不允许直接访问内存中的位置,在操作对象时,实际上是在操作对象的引用而不是实际的对象。为此,引用类型的值是按引用访问。

二、创建对象

这小节主要学习JavaScript创建对象对象的方法。

  • 字面量
  • 构造函数
  • Object.create()
// 实例:

// 第一种:字面量
let obj1 = {name: 'bob'};
// 字面量创建对象实际上是new Object()的语法糖,简单来说:
// var obj1 = {} 实际是调用了: var obj1 = new Object();即
var obj2 = new Object({name: 'bob'});

// 第二种:构造函数
function Person(name){
    this.name = name;
}
let person = new Person('bob');

// 第三种:Object.create()
// Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__
let obj3 = Object.create({name: 'bob'});

三、理解对象

这小节主要理解ECMAScript中对象是如何设置属性和访问属性的,即使平常不用这样写代码(对象),但理解它对理解对象非常重要。ECMAScript中有两种属性:数据属性和访问器属性。

3.1.数据属性

数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4个描述其行为的特性。

  • [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
  • [[Enumerable]]:表示能否通过for-in循环返回属性。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
  • [[Writable]]:表示能否修改属性的值。像前面例子中那样直接在对象上定义的属性,它们的这个特性默认值为true。
  • [[Value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候,把新值保存在这个位置。这个特性的默认值为undefined。

要修改属性默认的特性,必须使用ECMAScript 5的Object.defineProperty()方法。这个方法接收三个参数:属性所在的对象、属性的名字和一个描述符对象。

// 实例:

var person = {}

Object.defineProperty(person, "name", {
    configurable: false, // 设置不能删除,其值默认值为true
    enumerable: true, // 设置不可迭代,其值默认值为true
    writable: false, // 设置只读,不可修改其值,其值默认值为true
    value: 'bob'
})

console.log(person.name); // bob

// 试图修改name的值
person.name = "lynn";
console.log(person.name); // 实际上是修改值失败的,因为设置了只读属性,仍然输出:bob

// 试图删除name值
delete person.name;
console.log(person); // 也不允许删除,因为设置了不能修改该属性,输出:{ name: 'bob' }

3.2.访问器属性

访问器属性有如下4个特性。

  • [[Configurable]]:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。对于直接在对象上定义的属性,这个特性的默认值为true。
  • [[Enumerable]]:表示能否通过for-in循环返回属性。对于直接在对象上定义的属性,这个特性的默认值为true。
  • [[Get]]:在读取属性时调用的函数。默认值为undefined。
  • [[Set]]:在写入属性时调用的函数。默认值为undefined。

访问器属性不能直接定义,必须使用Object.defineProperty()来定义。

// 实例:
var person = {
    _name: 'bob',
    likes: 'code'
}

Object.defineProperty(person, "name", {
    configurable: false, // 设置不能删除,其值默认值为true
    enumerable: true, // 设置不可迭代,其值默认值为true
    // 在读取属性时调用的函数
    get: function () {
        return this._name + " Get."
    },
    // 在写入属性时调用的函数
    set: function (newValue) {
        this._name = "I am " + newValue + ", My friend's name is Bob.";
    }
})

// 在读取属性时调用的函数
console.log(person.name); // bob Get.

// 在写入属性时调用的函数
person.name = 'lynn'
console.log(person.name); // I am lynn, My friend's name is Bob.

3.3.读取属性的特性

使用ECMAScript 5的Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述符。

这个方法接收两个参数:属性所在的对象和要读取其描述符的属性名称。返回值是一个对象,如果是访问器属性,这个对象的属性有configurable、enumerable、get和set;如果是数据属性,这个对象的属性有configurable、enumerable、writable和value。例如:

var person = {
    _name: 'bob',
    likes: 'code'
}

Object.defineProperty(person, "name", {
    configurable: true, // 设置不能删除,其值默认值为true
    enumerable: false, // 设置不可迭代,其值默认值为true
    // 在读取属性时调用的函数
    get: function () {
        return this._name + " Get."
    },
    // 在写入属性时调用的函数
    set: function (newValue) {
        this._name = "I am " + newValue + ", My friend's name is Bob.";
    }
})

var descriptor = Object.getOwnPropertyDescriptor(person, "_name");

console.log(descriptor.configurable); // true
console.log(descriptor.enumerable); // true
console.log(descriptor.value); // bob
console.log(typeof descriptor.get); // undefined

var descriptor2 = Object.getOwnPropertyDescriptor(person, "name");
console.log(descriptor2.configurable); // true
console.log(descriptor2.enumerable); // false
console.log(descriptor2.value);  // undefined
console.log(typeof descriptor2.get); // function

对于数据属性_name,value等于最初的值,configurable是false,而get等于undefined。对于访问器属性name,value等于undefined,enumerable是false,而get是一个指向getter函数的指针。

学习完本章,建议继续学习手记《理解JavaScript的构造函数、实例、原型与原型链》点击跳转 希望对你学习有帮助,Thanks!

2人推荐
随时随地看视频
慕课网APP

热门评论

貌似有好几处地方都写反了....比如那个只读属性,你却写成了允许修改......

查看全部评论