博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
重温JS基础--JS中的对象属性
阅读量:6267 次
发布时间:2019-06-22

本文共 5529 字,大约阅读时间需要 18 分钟。

前言
  1. 面向对象的语言都有一个的概念,通过类可以创建任意多个具有相同属性和方法的对象。
  2. JavaScript中把对象定义为无序属性的集合,属性可以包含基本值,对象或者函数。也可以将对象理解为一组没有特定顺序的值。
  3. 每个对象都是基于一个引用类型创建的。
一. 理解对象

之前说过创建对象的最简单的方式就是创建一个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.nameconsole.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 = 2005console.log(book.year) //2005console.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) //2004console.log(descriptor.configurable) //falseconsole.log(typeof descriptor.get) //'undefined'var des = Object.getOwnPropertyDescriptor(book, 'year')console.log(des.value) //'undefined'console.log(des.enumberable) //falseconsole.log(typeof descriptor.get) //'function'
总结一波

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

  1. 在JavaScript的对象属性可以分为两类,一类就是数据属性,一类就是访问器属性。
  2. 数据属性有configurable, enumberable, wirtable, value四个特性。
  3. 访问器属性有configurable, enumberable, get, set四个特性。
  4. 访问器属性只能通过Object.defineProperty()方法进行设置。
  5. 还有Object.defineProperties()方法和Object.getOwnPropertyDescriptor()方法的作用。
    ...

转载地址:http://dyvpa.baihongyu.com/

你可能感兴趣的文章
iOS播放短的音效
查看>>
[java] java 线程join方法详解
查看>>
JQuery datepicker 用法
查看>>
golang(2):beego 环境搭建
查看>>
天津政府应急系统之GIS一张图(arcgis api for flex)讲解(十)态势标绘模块
查看>>
程序员社交宝典
查看>>
ABP理论学习之MVC控制器(新增)
查看>>
Netty中的三种Reactor(反应堆)
查看>>
网页内容的html标签补全和过滤的两种方法
查看>>
前端源码安全
查看>>
【CodeForces 618B】Guess the Permutation
查看>>
【转】如何实现一个配置中心
查看>>
Docker —— 用于统一开发和部署的轻量级 Linux 容器【转】
查看>>
Threejs 官网 - Three.js 的图形用户界面工具(GUI Tools with Three.js)
查看>>
Atitit.Java exe bat 作为windows系统服务程序运行
查看>>
session的生命周期
查看>>
数据库的本质、概念及其应用实践(二)
查看>>
iOS开发多线程--(NSOperation/Queue)
查看>>
php的ajax简单实例
查看>>
maven常用构建命令
查看>>