JS面向对象篇一、理解对象及属性特性(属性描述符)

本文内容
1、理解对象;
2、ECMAScript有两种属性类型:数据属性和访问器属性(getter和setter函数);
3、数据属性的属性特性:[[Configurable]]、[[Enumerable]]、[[Writable]]、[[value]];
4、访问器属性的属性特性:[[Configurable]]、[[Enumerable]]、[[get]]、[[set]];
5、Object.defineProperty()、Object.defineProperties()、Object.getOwnPropertyDescriptor()设置或读取属性特性(属性描述符)的方法

理解对象

ECMA-262把对象定义为:无序属性的集合,其属性可以包含基本值、对象或者函数。
也就是说对象是一组没有特定顺序的名值对,一个名字对应一个值,值可以是数据(包括基本值以及引用类型值)和函数,每一个名值对都是这个对象的属性。

var person = {
name: 'youyang',
age: 25,
job: 'coder',
sayName: function() {
console.log(this.name)
}
}

以上代码创建了一名为person的对象,它有四个属性:name、age、job和sayName。注意虽然通常我们说name、age、job为属性,而sayName称作person对象的方法,其实它也是属性,只不过值为函数而已。

属性类型及属性特性

1、首先需要明确javascript对象中有哪些属性类型?

ECMAScript中有两种属性:数据属性和访问器属性。

2、什么是属性特性?

每个对象的属性(包括方法)在创建时都带有一些特征值,ECMA-262定义这些特性值是为了实现javascript引擎用的,即内部使用的,所以该规范把它们放在两对方括号中:如[[Enumerable]]。

3、那么属性都有哪些描述行为的特性呢?不同的属性类型的属性特性又有什么不同呢?

数据属性

数据属性有四个描述其行为的特性:

  1. [[configurable]]:表示能否通过delete关键字删除属性从而重新定义属性,能否修改属性的特性(包括[[configurable]]特性本身以及下面三个其他特性),或者能否把属性修改为访问器属性。像上面例子中那样直接定义在对象上的属性默认值为true.
  2. [[Enumerable]]:是否可枚举(for-in循环中能否返回该属性),上面那样直接定义在对象上的属性默认值为true。
  3. [[Writable]]:是否可修改属性的值,默认为true;
  4. [[value]]:对应属性值,读取的时候从这里读取,写入的时候将新值保存在这里,默认值为undefined;
var obj = {
num: 10
}

这里创建了一个名为num的属性,它的 [[configurable]]、 [[Enumerable]]、 [[Writable]]均为true,而[[value]]为10。

访问器属性

相比数据属性,访问器属性没有[[value]]这一属性特性,而是拥有一对函数:getter()和setter(),在读取访问器属性的时候,调用getter(),该函数负责返回有效的值,在写入即设置属性的值的时候调用setter()并传入新值,由setter()负责执行处理数据的操作。

访问器属性包含4个属性特性:

  1. [[configurable]]:表示能否通过delete删除属性,能否修改属性的特性(包括[[configurable]]特性本身以及下面三个其他特性),或者能否把属性修改为数据属性。直接定义在对象上的属性默认值为true;
  2. [[Enumerable]]:是否可枚举(for-in循环中能否返回该属性),上面那样直接定义在对象上的属性默认值为true;
  3. [[Get]]:在读取属性时调用的函数,默认为undefined;
  4. [[Set]]:在写入属性时调用的函数,默认为undefined。

Object.defineProperty()

这个方法有两个作用,一个是修改属性的默认属性特性,另一个就是定义属性,因为如果你想在定义一个属性的同时指定它的一些属性特性那么就必须使用这个方法,并且当你想定义一个访问器属性时只能使用Object.defineProperty()来实现,因为访问器属性是不能直接定义的。
此方法接收的参数:对象,指定的属性名称,一个描述符对象(用来设置属性特性的对象)
使用方法如下:
1、要修改一个属性的默认特性

var obj = {
num: 10
}
Object.defineProperty(obj, 'num', {
value: 20,
writable: false
})
console.log(obj.num) // 20
obj.num = 30
console.log(obj.num) // 20

上面的例子中,我们将对象obj的属性num的[[writable]]是否可修改特性设置为了false,于是num属性不能被修改,当尝试为它写入新值(obj.num = 30)时,非严格模式下,此操作会被忽略,严格模式下则会报错。

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

var obj = {
num: 10
}
Object.defineProperty(obj, 'data', {
get: function() {
return this.num
},
set: function(newVal) {
if (newVal > 10) {
this.num = newVal
}
}
})
console.log(obj.data) // 10
obj.data = 20
console.log(obj.data) // 20
console.log(obj.num) // 20

getter和setter函数或许你常听说,但是并不知道它们到底是什么,因为我们确实在日常开发中很少有机会用到它们,但是在一些框架的源码中常见到它们的应用。

Object.defineProperties()

与Object.defineProperty()方法相同,Object.defineProperties()方法也有同样作用:设置和修改属性特性,只不过Object.defineProperties()方法可以设置多个属性。
使用方法如下:

var obj = {
num: 10
}
Object.defineProperties(obj, {
name: {
writable: false,
value: '张三'
},
data: {
get: function () {
return this.num
},
set: function (newVal) {
if (newVal > 10) {
this.num = newVal
}
}
}
})

以上代码使用Object.defineProperties()定义了一个数据属性和一个访问器属性。

Object.getOwnPropertyDescriptor()

这个方法的作用就是获取指定属性的属性描述符,所谓属性描述符就是我们之前一直提到的属性特性。
接收两个参数:属性所在对象和指定属性名称
返回值:一个对象,如果是访问器属性,对象的属性包括:configurable,enumerable,get和set,如果是数据属性,则返回的这个对象的属性有:configurable,enumerable,writable,value。

var obj = {
num: 10
}
console.log(Object.getOwnPropertyDescriptor(obj, 'num')) // {value: 10, writable: true, enumerable: true, configurable: true}

原文地址:https://www.cnblogs.com/youyang-2018/p/11764050.html

时间: 2024-10-17 14:21:30

JS面向对象篇一、理解对象及属性特性(属性描述符)的相关文章

JS面向对象设计(1)-理解对象

不同于其他面向对象语言(OO,Object-Oriented),JS的ECMAScript没有类的概念, 它把对象定义为"无序属性(基本值.对象.函数)的集合",类似于散列表. 每个对象都是基于一个引用类型(原生类型.自定义类型)创建的. 1. 理解对象 创建自定义对象(Object构造函数.对象字面量). // Object构造函数:创建一个Object实例,再为实例添加属性和方法. var person = new Object(); person.name = "xia

面向对象学习篇[1]-理解对象

对象即多个属性和方法的一个集合体 属性类型 1 数据属性:数据属性包含一个数据值的位置,在这个位置可以读取和写入值.数据属性有4个描述其行为的特性a) [[Configurable]] 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性,这个特性的默认值为trueb) [[Enumerable]] 表示能否通过 for-in 循环返回属性,这个特性的默认值为truec) [[Writable]] 表示能否修改属性的值,这个特性的默认值为trued

JS面向对象(3) -- Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法

相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对象之间的赋值,for...in语句,delete使用,成员方法,json对象的使用,prototype的使用,原型继承与原型链 JS面向对象(3) -- Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法 1.Object类 在JS中,Object是所有类的基

03.JavaScript 面向对象精要--理解对象

JavaScript 面向对象精要--理解对象 尽管JavaScript里有大量内建引用类型,很可能你还是会频繁的创建自己的对象.JavaScript中的对象是动态的. 一.定义属性 当一个属性第1次被添加给对象时JavaScript在对上上调用了一个名为 [[Put]]的内部方法,该方法会在对象上创建一个新节点保存属性,就像 哈希表上第一次添加一个键一样这个操作不仅指定了初始值 也定义了属性的一些特征 1.1 [[Put]]内部方法 [[Put]]在对象上创建一个自有属性 1.2 [[Set]

javascript面向对象系列1——理解对象

[对象定义]无序属性的集合,其属性可以包含基本值.对象或者函数 //简单的对象实例 var person = new Object(); person.name = "Nicholas"; person.age = 29; person.job = "Software Engineer"; person.sayName = function(){ alert(this.name); } [内部属性类型]内部属性无法直接访问,ECMAScript5把它们放在两对方括号

【转】java提高篇(二)-----理解java的三大特性之继承

[转]java提高篇(二)-----理解java的三大特性之继承 原文地址:http://www.cnblogs.com/chenssy/p/3354884.html 在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句话中最引人注目的是"复用代码",尽可能的复用代码使我们程序员一直在追求的,现在我来介绍一种复用代码的方式,也是java三大

Java提高篇之理解java的三大特性——继承

在<Think in java>中有这样一句话:复用代码是Java众多引人注目的功能之一.但要想成为极具革命性的语言,仅仅能够复制代码并对加以改变是不够的,它还必须能够做更多的事情.在这句话中最引人注目的是"复用代码",尽可能的复用代码使我们程序员一直在追求的,现在我来介绍一种复用代码的方式,也是java三大特性之一-继承. 继承 在讲解之前我们先看一个例子,该例子是前篇博文(java提高篇之理解java的三大特性--封装)的. 从这里我们可以看出,Wife.Husband

Python__new__方法、定制属性访问、描述符与装饰器

__new__方法的运行顺序 装饰器的概念的用法 三个内置装饰器 类中属性的访问过程 __new__方法 创建实例的方法 __new__方法是在类创建实例的时候自动调用的 实例是通过类里面的__new__方法创建出来的 先调用__new__方法创建实例,再调用 __init__方法初始化实例 __new__方法,后面括号里的cls代表的是类本身 必须有返回值 父类名.__new__(cls) 单例模式 创建多个实例的时候,每个实例所指向的内存地址不同 单例模式让多个实例引用的是同一个实例,是一个

JS面向对象篇二、什么是原型?原型对象与实例对象、构造函数的关系及相关方法

本文内容: 1.构造函数.原型对象与实例对象之间的关系: 2.isPrototypeOf()和Object.getPrototypeOf(); 3.实例对象上与原型对象上同名的属性处理: 4.hasOwnProperty()方法和in操作符判断属性来自实例对象本身还是它的原型对象: 5.for-in.Object.keys()和Object.getOwnPropertyNames()方法获取实例对象或者原型对象上的属性: 6.需注意的特殊问题 构造函数.原型对象与实例对象 function Pe