《JavaScript核心概念及实践》——2.3 运算符

2.3 运算符

运算符,通常是容易被忽略的一个内容,但是一些比较古怪的语法现象仍然可能需要用到运算符的结合率或者其作用来进行解释。JavaScript中,运算符是一定需要注意的地方,有很多具有JavaScript编程经验的人仍然免不了被搞得晕头转向。

我们在这一节主要讲解这样几个运算符,诸如算术运算、位运算等和其他的主流程序设计语言类似,在这里不做讨论。

2.3.1 中括号运算符([])
中括号([])运算符可用在数组对象和对象上,从数组中按下标取值。

var array = ["one", "two", "three", "four"];
array[0]

而[]同样可以作用于对象,一般而言,对象中的属性的值是通过点(.)运算符来取值,如:

var object = {
    field : "self",
    printInfo : function(){
        print(this.field);
    }
}

object.field;
object.printInfo();

但是考虑到这样一种情况,我们在遍历一个对象的时候,对其中的属性的键(key)是一无所知的,我们怎么通过点(.)来访问呢?这时候我们就可以使用[]运算符。

for(var key in object){
    print(key + ":" + object[key]);
}

运行结果如下。

field:slef
printInfo:function (){
        print(this.field);
}

2.3.2 点运算符(.)
点运算符的左边为一个对象(属性的集合),右边为属性名,应该注意的是右边的值除了作为左边的对象的属性外,同时还可能是它自己的右边的值的对象。

var object = {
    field : "self",
    printInfo : function(){
        print(this.field);
    },
    outter:{
        inner : "inner text",
        printInnerText : function(){
            print(this.inner);
        }
    }
}

object.outter.printInnerText();

这个例子中,outter作为object的属性,同时又是printInnerText()的对象。

但是点(.)运算符并不总是可用的,考虑这样一种情况,如果一个对象的属性本身就包含点(.)的键(self.ref),点运算符就无能为力了。

var ref = {
    id : "reference1",
    func : function(){
        return this.id;
    }
};

var obj = {
    id : "object1",
    "self.ref" : ref
};

当我们尝试访问obj的“self.ref”这个属性的时候:obj.self.ref,解释器会以为obj中有个名为self的属性,而self对象又有个ref的属性,这样会发生不可预知的错误,一个好的解决方法是使用中括号([])运算符来访问。

print(obj["self.ref"].func());
在这种情况下,中括号运算符成为唯一可行的方式,因此,建议在不知道对象的内部结构的时候(比如要遍历对象来获取某个属性的值),一定要使用中括号运算符,这样可以避免一些意想不到的问题。

2.3.3 相等与等同运算符
运算符==读作相等,而运算符===则读作等同。这两种运算符都是在JavaScript代码中经常见到的,但是意义则不完全相同,简而言之,相等运算符会对两边的操作数做类型转换,而等同则不会。我们还是通过例子来说明。

print(1 == true);
print(1 === true);
print("" == false);
print("" === false);

print(null == undefined);
print(null === undefined);

运行结果如下。

true
false
true
false
true
false

相等和等同运算符的规则分别如下。

相等运算符
如果操作数具有相同的类型,则判断其等同性,如果两个操作数的值相等,则返回true(相等),否则返回false(不相等)。

如果操作数的类型不同,则按照这样的情况来判断:

  • null和undefined相等;
  •  其中一个是数字,另一个是字符串,则将字符串转换为数字,再做比较;
  •  其中一个是true,先转换成1(false则转换为0)再做比较;
  •  如果一个值是对象,另一个是数字/字符串,则将对象转换为原始值(通过toString()或者valueOf()方法);
  •  其他情况,则直接返回false。

等同运算符
如果操作数的类型不同,则不进行值的判断,直接返回false。

如果操作数的类型相同,分下列情况来判断:

 - 都是数字的情况,如果值相同,则两者等同(有一个例外,就是NaN,NaN与其本身也不相等),否则不等同;

  •  都是字符串的情况,与其他程序设计语言一样,如果串的值不等,则不等同,否则等同;
  •  都是布尔值,且值均为true/false,则等同,否则不等同;
  •  如果两个操作数引用同一个对象(数组,函数),则两者完全等同,否则不等同;
  •  如果两个操作数均为null/undefined,则等同,否则不等同。

比如:

var obj = {
    id : "self",
    name : "object"
};

var oa = obj;
var ob = obj;

print(oa == ob);
print(oa === ob);

会返回:

true
true

再来看一个对象的例子。

var obj1 = {
    id : "self",
    name : "object",
    toString : function(){
        return "object 1";
    }
}

var obj2 = "object 1";

print(obj1 == obj2);
print(obj1 === obj2);

返回值为:

true
false

obj1是一个对象,而obj2是一个结构与之完全不同的字符串,而如果用相等操作符来判断,则两者是完全相同的,因为obj1重载了顶层对象的toString方法。

而不等(!=)和不等同(!==),则与相等(==)/等同(!==)相反。因此,在JavaScript中,使用相等/等同、不等/不等同的时候,一定要注意类型的转换,这里推荐使用等同/不等同来进行判断,这样可以避免一些难以调试的bug。

事实上,很多新手会犯的错误都与JavaScript自身的灵活性有关系,比如由于JavaScript的弱类型特性,解释器会在运行时进行类型的转换,这样会隐藏一些出错的可能性,又比如是采取中括号运算符还是使用点运算符,以及相等还是等同等,JavaScript本身不会强制限制开发者,但是有一个好的编码标准仍然是非常必要的。jslint是一个用于静态检查JavaScript代码的工具,开发者可以在运行代码之前使用jslint检查潜在的错误(这些错误一般不会导致语法错误,但是可能在运行时出现难以跟踪的问题)。

时间: 2024-10-03 08:36:09

《JavaScript核心概念及实践》——2.3 运算符的相关文章

《JavaScript核心概念及实践》——1.2 JavaScript语言特性

1.2 JavaScript语言特性 JavaScript是一门动态的.弱类型.基于原型的脚本语言.在JavaScript中"一切皆对象",在这一方面,它比其他的面向对象的语言来得更为彻底.即使作为代码本身载体的函数(function),也是对象,数据与代码的界限在JavaScript中已经相当模糊.虽然它被广泛应用在Web客户端,但是其应用范围远远未局限于此.下面就这几个特点分别介绍. 1.2.1 动态性动态性是指,在一个JavaScript对象中,要为一个属性赋值,我们不必事先创建

《JavaScript核心概念及实践》——第2章 基本概念 2.1 数据类型

第2章 基本概念 本章将聚焦于JavaScript中的基本概念,这些概念与传统语言有比较大的不同,因此单独列出一章来做专门描述.理解本章的概念对书中后续章节的概念,代码的行为等会有很大的帮助,读者不妨花比较多的时间阅读本章,即使你对JavaScript已经比较熟悉,也建议通读本章. 本章主要讲述JavaScript中的数据类型(基本类型与引用类型).变量(包括变量的作用域).操作符(主要是一些较为常见,但是不容易从字面上理解的操作符).由于JavaScript中的"一切皆对象",在掌握

《JavaScript核心概念及实践》——1.3 JavaScript应用范围

1.3 JavaScript应用范围 当JavaScript第一次出现的时候,是为了给页面带来更多的动态,使用户可以与页面进行交互.虽然JavaScript在Web客户端取得了很大的成功,但是ECMA标准并没有局限其应用范围.事实上,现在的JavaScript大多运行于客户端,但是仍有部分运行于服务器端,如Servlet.ASP等.当然,JavaScript作为一个独立的语言,同样可以运行在其他的应用程序中,比如Java版的JavaScript引擎Rhino.C语言版的SpiderMonkey等

《JavaScript核心概念及实践》——第1章 概述 1.1 JavaScript简史

第1章 概述 1.1 JavaScript简史 20世纪90年代,在早期的Web站点上,所有的网页内容都是静态的.所谓静态是指除了点击超链接外,你无法通过任何方式同页面进行交互,比如让页面元素接受事件,修改字体等.但是人们又迫切地需要一种方式来打破这个局限,于是到了1996年,网景(Netscape)公司开始研发一种新的语言Mocha,并将其嵌入到自己的浏览器Netscape中.这种语言可以通过操纵DOM(Document Object Model,文档对象模型)来修改页面,并加入了对鼠标事件的

《Spark大数据分析:核心概念、技术及实践》大数据技术一览

本节书摘来自华章出版社<Spark大数据分析:核心概念.技术及实践>一书中的第1章,第1节,作者穆罕默德·古勒(Mohammed Guller)更多章节内容可以访问"华章计算机"公众号查看. 大数据技术一览 我们正处在大数据时代.数据不仅是任何组织的命脉,而且在指数级增长.今天所产生的数据比过去几年所产生的数据大好几个数量级.挑战在于如何从数据中获取商业价值.这就是大数据相关技术想要解决的问题.因此,大数据已成为过去几年最热门的技术趋势之一.一些非常活跃的开源项目都与大数据

《Spark大数据分析:核心概念、技术及实践》一1.2 数据序列化

  本节书摘来自华章出版社<Spark大数据分析:核心概念.技术及实践>一书中的第1章,第1.2节,作者[美] 穆罕默德·古勒(Mohammed Guller),更多章节内容可以访问"华章计算机"公众号查看. 1.2 数据序列化 数据有自己的生命周期,独立于创建或使用它的程序.大多数情况下,数据比创建它的应用存活得更久.一般来说,数据保存在硬盘上.有时,也会通过网络把数据从一个应用发送给另一个应用. 在硬盘上存储或通过网络发送的数据格式与数据在内存中的格式是不一样的.把内存

《Spark大数据分析:核心概念、技术及实践》Scala编程

本节书摘来自华章出版社<Spark大数据分析:核心概念.技术及实践>一书中的第1章,第2节,作者穆罕默德·古勒(Mohammed Guller)更多章节内容可以访问"华章计算机"公众号查看. Scala编程 Scala是当前热门的现代编程语言之一.它是编程语言界的凯迪拉克.它是一门强大且优美的语言.学会了它,对你的职业生涯大有裨益. 用不同的编程语言都可以编写大数据应用程序,比如Java.Python.C++.Scala等.Hadoop本身就是用Java编写的.尽管大多数的

《Spark大数据分析:核心概念、技术及实践》Spark Core

本节书摘来自华章出版社<Spark大数据分析:核心概念.技术及实践>一书中的第1章,第节,作者穆罕默德·古勒(Mohammed Guller)更多章节内容可以访问"华章计算机"公众号查看. Spark Core Spark是大数据领域最活跃的开源项目,甚至比Hadoop还要热门.如第1章所述,它被认为是Hadoop的继任者.Spark的使用率大幅增长.很多组织正在用Spark取代Hadoop. 从概念上看,Spark类似于Hadoop,它们都用于处理大数据.它们都能用商用硬

《Spark大数据分析:核心概念、技术及实践》一3.9 共享变量

 本节书摘来自华章出版社<Spark大数据分析:核心概念.技术及实践>一书中的第3章,第3.9节,作者[美] 穆罕默德·古勒(Mohammed Guller),更多章节内容可以访问"华章计算机"公众号查看. 3.9 共享变量 Spark使用的架构是无共享的.数据分布在集群的各个节点上,每个节点都有自己的CPU.内存和存储资源.没有全局的内存空间用于任务间共享.驱动程序和任务之间通过消息共享数据. 举例来说,如果一个RDD操作的函数参数是驱动程序中变量的引用,Spark会将这