资讯专栏INFORMATION COLUMN

重温JS基础--JS中的对象属性

jerryloveemily / 2133人阅读

摘要:数据属性有个描述其行为的特性表示能否通过删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。总结一波关于这些内容主要讲的就是在的对象属性可以分为两类,一类就是数据属性,一类就是访问器属性。

前言

面向对象的语言都有一个的概念,通过类可以创建任意多个具有相同属性和方法的对象。

JavaScript中把对象定义为无序属性的集合,属性可以包含基本值,对象或者函数。也可以将对象理解为一组没有特定顺序的值。

每个对象都是基于一个引用类型创建的。

一. 理解对象

之前说过创建对象的最简单的方式就是创建一个Object实例,然后为它添加属性和方法:

var person = new Object()
person.name = "Nicholas"
person.age = "29"
person.sayName = function () {
    alert(this.name)
}

如上,创建了一个名为person的对象,然后为它添加了两个属性和一个方法。
还有一种是就是通过对象字面量的方式创建对象,如下:

var person = {
    name: "Nicholas",
    age: 29,
    sayName: function(){
        alert(this.name)
    }
}
1. 属性类型

JavaScript第五版在定义属性内部才用的特性描述了属性的各种特征。定义这些特性是为了给JavaScript引擎用的,因此在JavaScript中不能直接访问它们。为了表示特性是内部值,该规范把它们放在了两对儿方括号中,例如:[[Enumerable]]。
JavaScript中有两种属性:数据属性和访问器属性

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

(1)[[Configurable]]: 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性。对于直接定义在对象上的数据属性,该特性为true。
(2  [[Enumerable]]: 表示能否通过for-in循环遍历到属性。
(3)[[Writable]]: 表示能否修改属性的值。
(4)[[Value]]: 包含整个属性的数据值,读取属性的时候,从这个位置进行读取,写入属性值得时候,保存到该位置。

对于直接在对象上添加的属性,他们的[[Configurable]]、[[Enumerable]]、[[Writable]]特性都被设置为true。如:

var person = {
    name: "Nicholas"
}

如上,我们通过对象字面量的方法创建一个对象,创建一个name属性,为它指定的值为"Nicholas", 那么此时[[Value]]特性将被设置为"Nicholas",而对这个值得任何修改都将反应在这个位置上。其他的三个特性都默认为true。

要修改属性默认的特性可以使用Object.defineProperty()方法。这个方法接受三个参数:属性所在对象,属性的名字,一个描述符对象。其中描述符对象的属性必须是:configurable, enumerable, writable, value,设置其中一个或多个值,可以修改对应的特性。如下:

var person = {}

Object.defineProperty(person, "name", {
    wirtable: false,
    value: "Nicholas"
})
console.log(person.name) //"Nicholas"
person.name = "greg"
console.log(person.name) //"Nicholas"

如上,创建一个名为name的属性,将他的值设置为"Nicholas", 然后设置为只读,这个属性的值是不可修改的。类似的规则也适用于不可配置的属性:

var person = {}
Object.defineProperty(person, "name", {
    configurable: false,
    value: "Nicholas"
})
console.log(person.name) //"Nicholas"
delete person.name
console.log(person.name) //"Nicholas"

如上,把configurable设置为false,表示不能从对象中删除属性,所以看到删除name属性并没有起作用。而且,如果把属性定义为不可配置的,就不能把它变回可配置的了,此时再调用Object.defineProperty()方法除了只能修改writable,其他都会导致错误。

var person = {}
Object.defineProperty(person, "name", {
    configurable: false,
    value: "Nicholas"
})

Object.defineProperty(person, "name", {
    configurable: true,
    value: "Nicholas"
})

//报错:Cannot redefine property: name...

如上就会报错, 也就是多次调用Object.defineProperty()方法修改同一属性,但是把configurable特性设置为false之后就会有限制。

通过Object.defineProperty()创建一个新属性的时候,如果不指定configurable,enumberable 和writable特性的默认值都是false

访问器属性

访问器属性是不包含数据值的。它只包含两个函数,一个是gettersetter函数,不过这两个函数都不是必须的。在读取访问器属性的时候,会调用getter函数,这个函数返回该属性有效的值。在写入访问器属性的时候,会调用setter函数并传入新值,这个函数负责决定如何处理数据。访问器属性也具有4个特性:

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

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

var book = {
    _year: 2004,
    editor: 1
}
Object.defineProperty(book, "year", {  //定义了一个访问器属性year
    get: function() {
        return this._year
    },
    set: function(newVal) {
        if(newVal > 2004) {
            this._year = newVal
            this.editor = this.editor + newVal - 2004
        }
    }
})

book.year = 2005
console.log(book.year) //2005
console.log(book.editor) //2

如上,我们创建一个book对象,并且定义了两个默认的属性_year和editor。访问器属性则包含一个getter函数和一个setter函数。getter函数返回_year的值,而setter函数通过计算来确定正确的版本。使用访问器属性的常见方式,即设置一个属性的值会导致其他属性发生变化。

不一定要同时制定getter和setter。只指定getter以为着是不能写,尝试写入会忽略,在严格模式下会报错。同理,只设置setter函数的访问器属性不能读。

在此之前要创建访问器属性有两个非标准的方法,再这里稍微提一下:__defineGetter__和__defineSetter__。

var book = {
    _year: 2004,
    editor: 1
}

book.__defineGetter__("year", function(){
    return this.year
})
book.__defineSetter__("year", function(newval) {
    if(newval > 2005) {
        this._year = newval
        this.editor += newval - 2004
    }
})
2. 定义多个属性

ECMAScript5 定义了一个Object.defineProperties()方法,利用这个方法可以通过描述符一次定义多个属性。这个方法接受两个参数:第一个对象是要添加和修改其属性的对象,第二个对象的属性与第一个对象中要添加和修改的属性一一对应。如下例子:

var book = {}
Object.defineProperties(book, {
    _year: {
        writable: true,
        value: 2004
    },
    
    editor: {
        writable: true,
        value: 1
    },
    
    year: {
        get: function() {
            return this._year
        },
        set: function(newval) {
            if(newval > 2005) {
                this._year = 2005
                this.editor += newval - 2004
            }
        }
    }
})

如上,定义两个两个数据属性_year和editor,和一个访问器属性year。

3. 读取属性的特性

在ECMAScript5 中定义了一个Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述符,这个方法接受两个参数: 属性所在对象和要读取其描述符的属性名称。其返回值是一个对象,如果是访问器属性,这个对象有confiurable, enumerable, get, set。如果是数据属性那么就是configurable, enumberable, writeable, value。

var book = {}
Object.defineProperties(book, {
    _year: {
        writable: true,
        value: 2004
    },
    
    editor: {
        writable: true,
        value: 1
    },
    
    year: {
        get: function() {
            return this._year
        },
        set: function(newval) {
            if(newval > 2005) {
                this._year = 2005
                this.editor += newval - 2004
            }
        }
    }
})

var descriptor = Object.getOwnPropertyDescriptor(book, "_year");
console.log(descriptor.value) //2004
console.log(descriptor.configurable) //false
console.log(typeof descriptor.get) //"undefined"

var des = Object.getOwnPropertyDescriptor(book, "year")
console.log(des.value) //"undefined"
console.log(des.enumberable) //false
console.log(typeof descriptor.get) //"function"
总结一波

关于这些内容主要讲的就是:

在JavaScript的对象属性可以分为两类,一类就是数据属性,一类就是访问器属性。

数据属性有configurable, enumberable, wirtable, value四个特性。

访问器属性有configurable, enumberable, get, set四个特性。

访问器属性只能通过Object.defineProperty()方法进行设置。

还有Object.defineProperties()方法和Object.getOwnPropertyDescriptor()方法的作用。
...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/88791.html

相关文章

  • 重温基础】15.JS对象介绍

    摘要:构造函数通常首字母大写,用于区分普通函数。这种关系常被称为原型链,它解释了为何一个对象会拥有定义在其他对象中的属性和方法。中所有的对象,都有一个属性,指向实例对象的构造函数原型由于是个非标准属性,因此只有和两个浏览器支持,标准方法是。 从这篇文章开始,复习 MDN 中级教程 的内容了,在初级教程中,我和大家分享了一些比较简单基础的知识点,并放在我的 【Cute-JavaScript】系...

    booster 评论0 收藏0
  • 重温基础】22.内存管理

    摘要:内存泄露内存泄露概念在计算机科学中,内存泄漏指由于疏忽或错误造成程序未能释放已经不再使用的内存。判断内存泄漏,以字段为准。 本文是 重温基础 系列文章的第二十二篇。 今日感受:优化学习方法。 系列目录: 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理) 【重温基础】1-14篇 【重温基础】15.JS对象介绍 【重温基础】16.JSON对象介绍 【重温基础】1...

    Pandaaa 评论0 收藏0
  • 重温基础】16.JSON对象介绍

    摘要:系列目录复习资料资料整理个人整理重温基础篇重温基础对象介绍本章节复习的是中的关于对象相关知识。概念概念有三点全称对象表示法。对象没有分号,而对象有。序列化对象时,所有函数及原型成员都会被忽略,不体现在结果上。 本文是 重温基础 系列文章的第十六篇。今日感受:静。 系列目录: 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理) 【重温基础】1-14篇 【重温基础】15...

    0x584a 评论0 收藏0
  • 重温基础】14.元编程

    摘要:本文是重温基础系列文章的第十四篇。元,是指程序本身。有理解不到位,还请指点,具体详细的介绍,可以查看维基百科元编程。拦截,返回一个布尔值。 本文是 重温基础 系列文章的第十四篇。 这是第一个基础系列的最后一篇,后面会开始复习一些中级的知识了,欢迎持续关注呀! 接下来会统一整理到我的【Cute-JavaScript】的JavaScript基础系列中。 今日感受:独乐乐不如众乐乐...

    cc17 评论0 收藏0
  • 重温基础】6.数字

    摘要:本文是重温基础系列文章的第六篇。以指定的精度返回该数值对象的字符串表示,可接收一个参数,用来指定有效数个数的整数。 本文是 重温基础 系列文章的第六篇。今日感受:自己需要多总结,会有不同收获(比如今晚我做的转正总结)。 系列目录: 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理) 【重温基础】1.语法和数据类型 【重温基础】2.流程控制和错误处理 【重温基础】3.循环和...

    terro 评论0 收藏0
  • 重温基础】9.正则表达式

    摘要:前置知识中的正则表达式是用来匹配字符串中指定字符组合的模式。另外需要记住正则表达式也是对象。在正则表达式创建时更新,不执行。替换与正则表达式匹配的子串。查找以十六进制数规定的字符。正则表达式拓展介绍在中有两种情况。 本文是 重温基础 系列文章的第九篇。 今日感受:时间管理-角色管理法。 系列目录: 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理) 【重温基础】1.语...

    ispring 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<