Javascript之谈对象
谈谈如何理解对象
使用预定义对象只是面向对象语言的能力的一部分,
ECMAScript真正强大之处在于能够创建自己专用的类和对象。面向对象的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。由于ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数。”严格来讲,这就相当于说对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射到一个值。正因为这样(以及其他将要讨论的原因),我们可以把ECMAScript的对象想象成散列表:无非就是一组名值对,其中值可以是数据或函数。每个对象都是基于一个引用类型创建的,这个引用类型可以是原生类型,也可以是开发人员定义的类型。
创建自定义对象的最简单方式就是创建一个 Object 的实例,然后再为它添加属性和方法:
let car = new Object();
car.wheel = 4;
car.run = function() {
console.log(this.wheel + ' wheels is running!');
}
属性类型
ECMA-262第 5 版在定义只有内部才用的特性时,描述了属性的各种特征。ECMA-262定义这些特性是为了实现JavaScript引擎用的,因此在JavaScript中不能直接访问它们。为了表示特性是内部值,该规范把它们放在了两对儿方括号中,例如[[Enumerable]]。
ECMAScript 中有两种属性:数据属性 和 访问器属性。
** 数据属性 **
数据属性包含一个数据值的位置, 在这个位置可以读取值也能写入, 它有4个特性:
[[Configurable]]: 表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性[[Enumerable]]: 表示能否通过for-in循环返回属性[[Writable]]: 表示能否修改属性的[[Value]]: 包含这个属性的数据值, 读属性值的时候从这里读, 写入的时候把新值保存在这, 默认值是undefined
像上面那样直接创建的属性, 包括字面量形式创建的, 除了 [[Value]] 的值被设置成指定的值, 其他的默认值都是 true, 如果要修改属性默认的特性, 需要调用 Object.defineProperty() 方法, 该方法接受3个参数, 属性所在的对象, 属性名, 描述对象, Demo 如下:
let car = {brand: 'Ferrari'};
Object.defineProperty(car, 'brand', {
writable: false
});
car.brand = 'BMW'; // 严格模式这样赋值会报错, 非严格模式下会忽略该赋值
console.log(car.brand); // Ferrari
configurable 也遵循上面的规则, 一旦把属性定义为不可配置就再也不能把它变回可配的了, Object.defineProperty() 只能修改属性的 writable 特性, 其他的修改都会导致错误, 在调用 Object.defineProperty() 时, 如果明确指定 configurable, writable, value, enumerable, 他们的默认值都是 false
** 访问器属性 **
访问器属性不包含数据值, 它包含 getter 和 setter 函数, 这两个函数也不是必须的, 在读取访问器属性时会调用 getter, 写入时调用 setter, 访问器属性有4个特性:
[[Configurable]]: 表示是否能通过dlelete删除属性, 能否修改属性的特性, 能否把属性修改为数据属性, 直接在对象上定义的属性这个特性默认是true[[Enumerable]]: 表示能否通过for-in循环返回属性, 直接定义在对象上的属性这个特性默认是true[[Get]]: 读取属性是调用的函数, 默认是undefined[[Set]]: 写入属性时调用的函数, 默认是undefined
访问器属性不能直接定义, 必须使用 Object.defineProperty() 定义, Demo 如下:
let car = {
_speed: 20,
level: 1
};
Object.defineProperty(car, 'speed', {
get: function() {
return this._speed;
},
set: function(value) {
if(value > 500 || value < 0) {
return console.log('您的车子速度异常');
}
this._speed = value;
this.level = Math.round((value - 20) / 50);
}
});
car.speed = 200;
console.log(car.level); // 4
** 定义多个属性**
为对象定义多个属性可以调用 Object.defineProperties() 方法, 与 Object.defineProperty() 方法不同, 该方法接受2个参数: 要定义属性的对象, 要添加的属性描述集合, Demo 如下:
let car = {};
Object.defineProperties(car, {
_speed: {
value: 20,
configurable: true,
writable: true
},
level: {
value: 1,
configurable: true,
writable: true
},
speed: {
get: function() {
return this._speed;
},
set: function(value) {
if(value > 500 || value < 0) {
return console.log('您的车子速度异常');
}
this._speed = value;
this.level = Math.round((value - 20) / 50);
}
}
});
小结
- 对象的属性分为两种:
数据属性和访问器属性(函数类型的我们称之为对象的方法) - 介绍了
Object.defineProperty()和Object.defineProperties()的使用, 前者接受3个参数, 后者接受2个 - 介绍了访问器属性的使用, 设置一个属性的值会导致其他属性联动的时候我们可以使用访问器属性
Javascript之谈对象的更多相关文章
- 关于JavaScript对象,你所不知道的事(一)- 先谈对象
这篇博文的主要目的是为了填坑,很久之前我发表了一篇名为关于JavaScript对象中的一切(一) - 对象属性的文章,想要谈一谈JavaScript对象,可那时只是贴了一张关于这个主题的思维导图,今天 ...
- javascript是判断对象是否是数组
JS中的数据类型: 2大类 原始类型:值保存在变量本地的数据类型 5种:Number String Boolean undefined null Number:8bytes 舍入误差-->四舍五 ...
- JavaScript 基础回顾——对象
JavaScript是基于对象的解释性语言,全部数据都是对象.在 JavaScript 中并没有 class 的概念,但是可以通过对象和类的模拟来实现面向对象编程. 1.对象 在JavaScript中 ...
- javascript中的对象,原型,原型链和面向对象
一.javascript中的属性.方法 1.首先,关于javascript中的函数/“方法”,说明两点: 1)如果访问的对象属性是一个函数,有些开发者容易认为该函数属于这个对象,因此把“属性访问”叫做 ...
- Javascript 中判断对象为空
发现了一个巧妙的实现: 需要检查一个对象(Object)是否为空,即不包含任何元素.Javascript 中的对象就是一个字典,其中包含了一系列的键值对(Key Value Pair).检查一个对象是 ...
- JavaScript 中的对象
JavaScript 中的对象 在 JavaScript 中,对象是数据(变量),拥有属性和方法. JavaScript 中的所有事物都是对象:字符串.数字.数组.日期,等等. 访问对象的属性 访 ...
- 使用JavaScript的history对象来实现页面前进后退(go/back/forward)。
我们都知道JavaScript有history对象,主要是用来记录浏览器窗口的浏览记录.但是,JS脚本是不允许访问到这个记录里面的内容(隐私). 常见的用法是: history.back();//返回 ...
- javascript类型系统——Math对象
× 目录 [1]常量 [2]函数 前面的话 javascript使用算术运算符实现基本的算术运算,如果要实现更加复杂的算术运算,需要通过Math对象定义的常量和函数来实现.和其他对象不同,Math只是 ...
- javascript中Date对象的应用——简易日历的实现
× 目录 [1]效果 [2]HTML [3]CSS[4]JS 前面的话 简易日历作为javascript中Date对象的常见应用,用途较广泛.本文将详细说明简易日历的实现思路 效果演示 HTML说明 ...
随机推荐
- Ansible笔记(2)--配置清单
一.Ansible Inventory配置及详解 Inventory是ansible管理主机信息的配置文件,默认存放在/etc/ansible/hosts.在使用时通过 -i 或 --inventor ...
- 给Java新手的一些建议----Java知识点归纳(J2EE and Web 部分)
J2EE(Java2 Enterprise Edition) 刚出现时一般会用于开发企业内部的应用系统,特别是web应用,所以渐渐,有些人就会把J2EE和web模式画上了等号.但是其实 J2EE 里面 ...
- 郭盛华现身北京机场,颇有IT男的风范,网友:疑似被招安了
郭盛华纵横互联网江湖数十年,他白手起家,凭着过人的勇敢.智慧和绝技,身经百战,显赫辉煌,成为中外闻名的互联网安全领域大师级人物. 郭盛华的网络技术指导方面经验丰富实力深厚.他是中国互联网安全领域的传奇 ...
- Python---进阶---多线程---threading
一. 使用多线程去播放两个播放列表,一个是movie,一个是music _thread threading ------------------------------------------ imp ...
- LeetCode--008--字符串转换整数 (atoi)(python)
示例 1: 输入: "42"输出: 42示例 2: 输入: " -42"输出: -42解释: 第一个非空白字符为 '-', 它是一个负号. 我们尽可能将负号与 ...
- 【FJ省队训练&&NOIP夏令营】酱油&&滚粗记
FJOI2016省队训练滚粗记 2016.07.03~2016.07.06(Day1~5) 在学校期末考.因为才省选二试too young too simple爆蛋了所以下半个学期只能滚回去读文化课, ...
- 终于决定要开始写自己的博客了,先Mark一下
终于决定要开始写了,但事实是,打开就觉得浪费时间,懒癌犯了
- 「HNOI2016」矿区
https://loj.ac/problem/2052 题解 平面图转对偶图.. 首先我们转的话需要给所有的平面标号,然后找到每条边看看他们隔开了哪两个平面. 做法就是对每个点维护它的所有排好序的出边 ...
- [ethereum源码分析](5) 创建新账号
前言 在上一章我们介绍了 ethereum运行开启console 的过程,那么在这一章我们将会介绍如何在以太坊中创建一个新的账号.以下的理解可能存在错误,如果各位大虾发现错误,还望指正. 指令分析 指 ...
- JPA Hibernate 等面向对象持久化框架难以解决的问题
1+N查询性能问题 单个更新实体对象,而不是使用单调语句 在Java端做了很重的数据处理,数据库端反而很少 多层次 fetch inner join 难以实现 关联映射难以自定义条件 级联操作难以掌控 ...