Javascript学习小计(4)—数组/运算符

Javascript学习小计(4)—数组/运算符

数组

任何类型的数据都可以放入数组

任何类型的数据,都可以放入数组。

var arr = [
  {a: 1},
  [1, 2, 3],
  function() {return true;}
];

arr[0] // Object {a: 1}
arr[1] // [1, 2, 3]
arr[2] // function (){return true;}

上面数组arr的3个成员依次是对象、数组、函数。

数组本质是一种特殊的对象

本质上,数组属于一种特殊的对象typeof运算符会返回数组的类型是object

typeof [1, 2, 3] // "object"

上面代码表明,typeof运算符认为数组的类型就是对象。

数组的特殊性体现在,它的键名是按次序排列的一组整数(0,1,2…)。

var arr = ['a', 'b', 'c'];

Object.keys(arr)
// ["0", "1", "2"]

上面代码中,Object.keys方法返回数组的所有键名。可以看到数组的键名就是整数0、1、2。

上一章说过,对象有两种读取成员的方法:点结构(object.key)和方括号结构object[key])。但是,对于数值的键名,不能使用点结构。

var arr = [1, 2, 3];
arr.0 // SyntaxError

上面代码中,arr.0的写法不合法,因为单独的数值不能作为标识符(identifier)。所以,数组成员只能用方括号arr[0]表示(方括号是运算符,可以接受数值)。

length属性

length属性是可写的。如果人为设置一个小于当前成员个数的值,该数组的成员数量会自动减少到length设置的值。

var arr = [ 'a', 'b', 'c' ];
arr.length // 3

arr.length = 2;
arr // ["a", "b"]

上面代码表示,当数组的length属性设为2(即最大的整数键只能是1)那么整数键2(值为c)就已经不在数组中了,被自动删除了。

清空数组的一个有效方法,就是将length属性设为0。

值得注意的是,由于数组本质上是一种对象,所以可以为数组添加属性但是这不影响length属性的值。

var a = [];

a['p'] = 'abc';
a.length // 0

a[2.1] = 'abc';
a.length // 0

上面代码将数组的键分别设为字符串和小数,结果都不影响length属性。因为,length属性的值就是等于最大的数字键加1,而这个数组没有整数键,所以length属性保持为0

in 运算符

检查某个键名是否存在的运算符in,适用于对象,也适用于数组。

var arr = [ 'a', 'b', 'c' ];
2 in arr  // true
'2' in arr // true
4 in arr // false

上面代码表明,数组存在键名为2的键。由于键名都是字符串,所以数值2会自动转成字符串。

注意,如果数组的某个位置是空位in运算符返回false

var arr = [];
arr[100] = 'a';

100 in arr // true
1 in arr // false

上面代码中,数组arr只有一个成员arr[100],其他位置的键名都会返回false

遍历

组的某个位置是空位,与某个位置是undefined**,**是不一样的。如果是空位,使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过。

var a = [, , ,];

a.forEach(function (x, i) {
  console.log(i + '. ' + x);
})
// 不产生任何输出

for (var i in a) {
  console.log(i);
}
// 不产生任何输出

Object.keys(a)
// []

如果某个位置是undefined,遍历的时候就不会被跳过。

var a = [undefined, undefined, undefined];

a.forEach(function (x, i) {
  console.log(i + '. ' + x);
});
// 0. undefined
// 1. undefined
// 2. undefined

for (var i in a) {
  console.log(i);
}
// 0
// 1
// 2

Object.keys(a)
// ['0', '1', '2']

这就是说,空位就是数组没有这个元素,所以不会被遍历到,而undefined则表示数组有这个元素,值是undefined,所以遍历不会跳过。

类似数组的对象

如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,语法上称为“类似数组的对象”(array-like object)。

var obj = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
};

obj[0] // 'a'
obj[1] // 'b'
obj.length // 3
obj.push('d') // TypeError: obj.push is not a function

上面代码中,对象obj就是一个类似数组的对象。但是,“类似数组的对象”并不是数组,因为它们不具备数组特有的方法。对象obj没有数组的push方法,使用该方法就会报错。

类似数组的对象”的根本特征,就是具有length属性。只要有length属性,就可以认为这个对象类似于数组。

运算符

算数运算符
加法运算符
基本规则

加法运算符(+)是最常见的运算符,用来求两个数值的和。

1 + 1 // 2

JavaScript 允许非数值的相加。

true + true // 2
1 + true // 2

比较特殊的是,如果是两个字符串相加,这时加法运算符会变成连接运算符,返回一个新的字符串,将两个原字符串连接在一起。

'a' + 'bc' // "abc"

如果一个运算子是字符串,另一个运算子是非字符串,这时非字符串会转成字符串,再连接在一起。

1 + 'a' // "1a"
false + 'a' // "falsea"

加法运算符是在运行时决定,到底是执行相加,还是执行连接。也就是说,运算子的不同,导致了不同的语法行为,这种现象称为“重载”(overload)。**由于加法运算符存在重载,可能执行两种运算,**使用的时候必须很小心。

'3' + 4 + 5 // "345"
3 + 4 + '5' // "75"

上面代码中,由于从左到右的运算次序,字符串的位置不同会导致不同的结果。

除了加法运算符,其他算术运算符(比如减法、除法和乘法)都不会发生重载。它们的规则是:所有运算子一律转为数值,再进行相应的数学运算

余数运算符

需要注意的是,运算结果的正负号由第一个运算子的正负号决定。

-1 % 2 // -1
1 % -2 // 1

所以,为了得到负数的正确余数值,可以先使用绝对值函数。

自增和自减运算符

自增和自减运算符,是一元运算符,只需要一个运算子。它们的作用是将运算子首先转为数值,然后加上1或者减去1。它们会修改原始变量。

var x = 1;
++x // 2
x // 2

--x // 1
x // 1

上面代码的变量x自增后,返回2,再进行自减,返回1。这两种情况都会使得,原始变量x的值发生改变。

运算之后,变量的值发生变化,这种效应叫做运算的副作用(side effect)。自增和自减运算符是仅有的两个具有副作用的运算符,其他运算符都不会改变变量的值。

指数运算符

指数运算符(**)完成指数运算,前一个运算子是底数,后一个运算子是指数。

2 ** 4 // 16

注意,指数运算符是右结合,而不是左结合。即多个指数运算符连用时,先进行最右边的计算。

// 相当于 2 ** (3 ** 2)
2 ** 3 ** 2
// 512

上面代码中,由于指数运算符是右结合,所以先计算第二个指数运算符,而不是第一个。

比较运算符
严格相等运算符

简单说,它们的区别是相等运算符(==)比较两个值是否相等,严格相等运算符(===)比较它们是否为“同一个值”。如果两个值不是同一类型,严格相等运算符(===)直接返回false,而相等运算符(==)会将它们转换成同一个类型,再用严格相等运算符进行比较。

(1)不同类型的值

如果两个值的类型不同,直接返回false

(2)同一类的原始类型值

同一类型的原始类型的值(数值、字符串、布尔值)比较时,值相同就返回true,值不同就返回false

1 === 0x1 // true

需要注意的是NaN与任何值都不相等(包括自身)。另外,正0等于负0

NaN === NaN  // false
+0 === -0 // true

(3)复合类型值

两个复合类型(对象、数组、函数)的数据比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个地址。

{} === {} // false
[] === [] // false
(function () {} === function () {}) // false

如果两个变量引用同一个对象,则它们相等。

var v1 = {};
var v2 = v1;
v1 === v2 // true

(4)undefined 和 null

undefinednull与自身严格相等。

undefined === undefined // true
null === null // true
布尔运算符
概述

布尔运算符用于将表达式转为布尔值,一共包含四个运算符。

  • 取反运算符:!
  • 且运算符:&&
  • 或运算符:||
  • 三元运算符:?:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值