本章学习内容
- 对象概念
- 创建对象
- 理解对象
一、对象概念
这小节主要需要理解一下对象的知识概念。
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!
热门评论
貌似有好几处地方都写反了....比如那个只读属性,你却写成了允许修改......