JavaScript 系列博客(四)

JavaScript 系列博客之(四)

前言

本篇介绍 JavaScript 中的对象。在第一篇博客中已经说到 JavaScript 是一种‘’对象模型‘’语言。所以可以这样说,对象是 JavaScript 语言的核心概念,也是最重要的数据类型。

概述

生成方法

在 JavaScript 中声称对象相当方便,直接定义一个空字典就 ok。想要添加属性或者方法的话可以在定义结束之后动态添加。注意:对象时无序的复合数据集合。

上面代码中,大括号就可以直接定义一个对象,被赋值给变量 a,所以 a 就指向一个对象。该对象为一个空对象,但是会有一些默认的方法,像 constructor 是构造方法,想要动态的添加属性和方法就是这个方法的功劳。

在这里添加了一个属性为name,那么 name 是键名(成员名称),字符串 musibii 是键值(成员的值)。键名与键值之间用冒号分隔。如果再添加一个属性,那么属性之间使用逗号分隔。

键名

对象的所有键名都是字符串(ES6又引入了 Symbol 值也可以作为键名:还没了解过),所以加不加引号都可以。如果键名是数值,会被自动转为字符串。如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),且也不是数字,则必须加上引号,否则会报错。

对象的每一个键名又称为‘’属性‘’,它的键值可以是任何数据类型。如果一个属性的值为函数,通常把这个属性称为方法,调用方法和函数一样。

特别的如果属性的值指向的还是一个对象,那么就行成了链式引用。对象的属性之间用逗号分隔,最后一个属性后面可以加逗号,也可以不加。

对象的引用

如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有的引用。和 JavaScript 中的基本数据类型不一样,复合数据类型是传址传递。

a 和 b指向同一个对象,因此为其中任何一个变量添加属性,另一个变脸都可以读写该属性。如果取消某一个对象的引用,不会影响到其他变量。

这种引用只局限于对象,在之前的博客也提到,两个变量指向同一个原始类型(基本数据类型)的值,那么变量只是对值得拷贝(传值传递)。

属性的操作

属性的读取

读取对象的属性,有两种方法,一种是使用点运算符;另一种是使用方括号运算符。(在 python 中,字典只能通过方括号取值;对象只可以通过点运算符取值。不过可以通过自定义字典类改写 getattr 魔术方法改变。)

注意:如果使用方括号运算符,键名必须放在引号里面,否则会被当做变量处理。

var foo = ‘bar‘;

var obj = {
    foo: 1,
    bar: 2
};

obj.foo // 1
obj[foo]// 2

上面代码中,引用对象obj 的 foo 属性时,如果使用点运算符,foo 就是字符串;如果使用方括号运算符,但是不使用引号,那么 foo 就是一个变量,指向字符串 bar。

方括号运算符内部还可以使用表达式:

obj[‘hello‘ + ‘world‘]
obj[3 + 3]

数字键可以不加引号,因为会自动转为字符串。

var obj = {
    0.7: ‘hello world‘
};
obj[‘0.7‘] // ‘Hello World‘
obj[0.7] // ‘Hello World‘

上面代码对象的数字键0.7加不加引号都可以,因为会自动转为字符串。

var obj = {
    123: ‘Hello musibii‘
};

obj.123 // 报错
obj[123] // ‘Hello musibii‘

如果对数值键名123使用点运算符,会报错,使用方括号运算符才是正确的方式。

属性的赋值

点运算符和方括号运算符,不仅可以用来读取值,还可以用来赋值。

JavaScript 允许属性的后绑定,也就是说可以在任意时刻新增属性,没必要在定义对象的时候就把属性全都定义好。

属性的查看

查看一个对象的所有属性使用 Object.keys 方法。

var obj = {
    key1: 1,
    key2: 2
};

Object.keys(obj); // [key1, key2]

属性的删除

delete 命令用于删除对象的属性,删除成功后返回 true。

var obj = {
    p: 1;
}

delete obj.p; // true
obj.p // undefined
Object.keys(obj) // []

上述代码中,delete 命令删除对象 obj 的 p 属性。删除后,再读取 p 属性就会返回 undefined,而且 Object.keys 方法的返回值也不再包括该属性。

注意:删除一个不存在的属性,delete 不会报错而是返回 true。因此不能根据 delete 命令的结果认为某个属性的存在。(那么到底哪种方式才可以证明某个属性的存在与否)

如果删除属性时返回 false那就说明该属性存在,但是不可以删除。

var obj = Object.defineProperty({}, ‘p‘, {
    value: ‘musibii‘,
    configurable: false
});

obj.p // ‘musibii‘
delete obj.p // false

上述代码中,通过 Object 的defineProperty方法给对象 obj创建了一个属性,属性的configurable(可配置) 的值为 false,这样的一个属性就是不可以删除的。

另外需要注意的是,delete 命令只能删除对象本身的属性,无法删除继承的属性。

可以看出虽然 delete 命令返回 true,但是删除的属性依然存在。但是如果通过 proto 删除的话就可以删除。

判断属性的存在

in 运算符用于检出对象是否包含某个属性(注意,检查的是键名,不是键值)。如果包含就返回 true,否则就返回 false。它的左边是一个字符串,表示属性名,右边则是一个对象。

var obj = {p: 1};
‘p‘ in obj //true
‘toString‘ in obj // true

拿上面删除的 constructor 来说:

in 运算符的一个问题是,它不能识别哪些属性时对象自身的,哪些属性是继承的。就像上面,对象 obj 本身并没有 toString 属性,但是 in 运算符会返回 true,因为这个属性是继承的。

这时可以通过对象的 hasOwnProperty 方法判断,是否为对象自身属性

var obj = {};
if (‘toString‘ in obj) {
    console.log(obj.hasOwnProperty(‘toString‘)); // fasle
}

属性遍历

for...in 循环用来遍历一个对象的所有属性。

for...in 循环有两个注意点;

  • 它遍历的是对象所有可遍历的属性,会跳过不可遍历的属性;
  • 它不仅遍历对象自身的属性,还遍历继承的属性。

如果继承的属性是可遍历的,那么就会被 for...in 循环遍历到。但是,一般情况下,都是只想遍历对象自身的属性,所以使用 for...in 的时候,应该结合使用 hasOwnProperty 方法,在循环内部判断一下,某个属性是否为对象自身的属性。

var person = {name: ‘老张‘};

for (var key in person) {
    if (person.hasOwnProperty(key)) {
        console.log(key);
    }
} // name

with 语句

with 语句的格式如下:

with (对象) {
    语句;
}

它的作用是操作同一个对象的多个属性时,提供一些书写的方便。

注意:如果 with 区块内部有变量的赋值操作,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。

var obj = {};
with (obj) {
    p1 = 4,
    p2 = 5
}

obj.p1 // undefined
p1 // 4

上面代码中,对象 obj 并没有 p1属性,对 p1赋值等于创造了一个全局变量 p1.正确的写法应该是,先定义对象 obj 的属性 p1,然后在 with 区块内操作它。

这是因为 with 区块没有改变作用域,它的内部依然是当前作用域。这造成了with 语句的一个很大的弊病,就是绑定对象不明确。

with (obj) {
    console.log(x);
}

单纯从上面的代码块,根本无法判断 x 到底是全局变量,还是对象 obj 的一个属性。这非常不利于代码的除错和模块化,编译器也无法对这段代码进行优化,只能留到运行时判断,这就拖慢了运行速度。因此,建议不要使用 with 语句,可以考虑用一个临时变量代替 with。

with (obj1.obj2.obj3) {
    console.log(p1 + p2);
}
// 可以写为
var temp = obj1.obj2.obj3;
console.log(temp.p1 + temp.p2);

原文地址:https://www.cnblogs.com/zuanzuan/p/10161642.html

时间: 2024-10-10 06:07:42

JavaScript 系列博客(四)的相关文章

JavaScript 系列博客(五)

JavaScript 系列博客(五) 前言 本篇博客学习 js 选择器来控制 css 和 html.使用事件(钩子函数)来处理事件完成后完成指定功能以及js 事件控制页面内容. js 选择器 在学习 js 选择器前需要了解几个概念. 节点(一):在文档(document)中出现的所有内容都是 document 中的节点. 节点(二):标签节点(元素 element) | 注释节点 | 文本节点 | <!doctype>节点. js 选择器是将 js 与 html 建立起连接的桥梁,就好比 cs

JavaScript 系列博客(七)

JavaScript 系列博客(八) 前言 本篇博客介绍页面节点概念.文档结构以及如何使用 js 操作文档节点还有事件 target 以及 BOM 操作. 节点 dom与dom属性 // DOM: 文档对象模型 => 提高给用户操作document obj的标准接口 // DOM树: 以document为根, 树状展开所有子节点 节点分类 // 节点分类: 6个 // document | doctype | element | text | attr | comment 节点常规操作 var

Django 系列博客(十四)

Django 系列博客(十四) 前言 本篇博客介绍在 html 中使用 ajax 与后台进行数据交互. 什么是 ajax ajax(Asynchronous Javascript And XML)翻译成中文就是''异步 JavaScript 和 XML''.即使用 JavaScript 语言与服务器进行异步交互,传输的数据为 XML(现在更多地使用 json). 同步交互:客户端发出一个请求后,需要等待服务器响应结束,才能发出第二个请求: 异步交互:客户端发出一个请求后,无需等待服务器响应结束,

关于算法导论系列博客的说明

本系列博客主要为练习<算法导论(第三版)>的记录.发表目的在于希望通过大家的帮助,不断地改进程序,使其在时间和空间方面效率不断提高.由于水平有限,错误在所难免.但是,我一定尽力消除.另外, 欢迎大家指出错误,提出宝贵的建议,感谢大家的指点和帮助. 特别注明: 你们的评论对我是一种莫大的鼓励,哪怕一个字也好,万分感谢. 在开始之前,对各练习的程序作出统一说明,以后不再重复. 一  程序一般用C语言写,编译为GCC. 二   程序一般为子程序的形式,不提供调用主程序,只完成要求的功能. 三   不

Django 系列博客(二)

Django 系列博客(二) 前言 今天博客的内容为使用 Django 完成第一个 Django 页面,并进行一些简单页面的搭建和转跳. 命令行搭建 Django 项目 创建纯净虚拟环境 在上一篇博客中已经安装好了虚拟环境,所以用虚拟环境来安装指定版本的 Django.为了可以从头到尾的走一遍流程,我重新创建了一个虚拟环境. 激活虚拟环境并安装 Django 首先进入虚拟环境路径下的 bin 目录 使用命令激活虚拟环境 安装指定版本 Django 首先使用 pip3 list 命令查看 可以看到

Django 系列博客(七)

Django 系列博客(七) 前言 本篇博客介绍 Django 中的视图层中的相关参数,HttpRequest 对象.HttpResponse 对象.JsonResponse,以及视图层的两种响应方式 CBV 和 FBV,还有简单的文件上传. 视图函数 一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应.响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以.无论视图本身包含什么逻辑,都要返回

窥探Swift系列博客说明及其Swift版本间更新

Swift到目前为止仍在更新,每次更新都会推陈出新,一些Swift旧版本中的东西在新Swift中并不适用,而且新版本的Swift会添加新的功能.到目前为止,Swift为2.1版本.去年翻译的Swift书籍是1.0版本,所以上面一些东西并不在适用.虽然Swift语言仍在更新,但是其整体的基础框架已经形成,大的改动应该不会有,版本的更新更多的是语言新功能的添加和完善,所以并不用担心现在学的Swift会过时.更新也就是在原有的基础上去更新,所以学学Swift还是很有必要的.新的Swift版本中引入了好

Linux系列博客开篇

自从决定做开发,已经好久没有配置过Linux系统了.再不尝试着写一下博客,可能真的要还给老师了.本着一边复习,一边记录的原则,将一些Linux的配置和维护记录在此,不要贻笑大方才好. 为了完成接下来的这些博客,我可能会参考众多前辈的文章,我会尽量留下参考的出处,但是要是因为某些原因未能留下出处,还请原作者见谅.您可以联系我,我将及时改正. 按照我的计划,我会从Linux的安装.基本配置.常用命令开始,一直写到各种网络服务以及Linux存储集群.数据库集群等.基本思路按照尚观主机班的培训思路,不过

MVC系列博客之排球计分(一)需求分析

项目简介: 这是MVC系列博客之排球计分程序,该程序可以是对教练或者裁判使用的,让教练有权限对队员进行查询得分情况,让教练对队员的优势劣势进行了解,以便对队伍进行调整. 让裁判更好的判定比赛输赢. 需求分析:     作为一名排球教练,我需要统计对方球队的队员信息,得分情况,技能得分,以便能做出针对性的训练. 进入本程序后,需要选择身份,然后就可以对队员信息进行操作了.(增删改查) 本身份只能对本队队员进行操作,要想操作对方队员,只能退出程序,重新选择身份. 作为一名裁判,我需要对场上两队得分进