JavaScript
JS数组
avaScript的Array可以包含任意数据类型,并通过索引来访问每个元素。
要取得Array的长度,直接访问length属性:
ar arr = [1, 2, 3.14, 'Hello', null, true];
arr.length; // 6
请注意
直接给Array的length赋一个新的值会导致Array大小的变化:
var arr = [1, 2, 3];
arr.length; // 3
arr.length = 6;
arr; // arr变为[1, 2, 3, undefined, undefined, undefined]
arr.length = 2;
arr; // arr变为[1, 2]
请注意
如果通过索引赋值时,索引超过了范围,同样会引起Array大小的变化:
var arr = [1, 2, 3];
arr[5] = 'x';
arr; // arr变为[1, 2, 3, undefined, undefined, 'x']
数组方法
indexOf、slice、concat用法和String中一样
push和pop 从数组尾部插入、删除元素
var arr = [1, 2];
arr.push('A', 'B'); // 返回Array新的长度: 4
arr; // [1, 2, 'A', 'B']
arr.pop(); // pop()返回'B'
arr; // [1, 2, 'A']
arr.pop(); arr.pop(); arr.pop(); // 连续pop 3次
arr; // []
arr.pop(); // 空数组继续pop不会报错,而是返回undefined
arr; // []
unshift和shift 从数组头部插入、删除元素
var arr = [1, 2];
arr.unshift('A', 'B'); // 返回Array新的长度: 4
arr; // ['A', 'B', 1, 2]
arr.shift(); // 'A'
arr; // ['B', 1, 2]
arr.shift(); arr.shift(); arr.shift(); // 连续shift 3次
arr; // []
arr.shift(); // 空数组继续shift不会报错,而是返回undefined
arr; // []
sort 排序数组(从小到大)
reverse 翻转数组
splice 编辑数组
splice()
方法是修改Array的“万能方法”,它可以从指定的索引开始删除若干元素,然后再从该位置添加若干元素:
var arr = ['Microsoft', 'Apple', 'Yahoo', 'AOL', 'Excite', 'Oracle'];
// 从索引2开始删除3个元素,然后再添加两个元素:
arr.splice(2, 3, 'Google', 'Facebook'); // 返回删除的元素 ['Yahoo', 'AOL', 'Excite']
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
// 只删除,不添加:
arr.splice(2, 2); // ['Google', 'Facebook']
arr; // ['Microsoft', 'Apple', 'Oracle']
// 只添加,不删除:
arr.splice(2, 0, 'Google', 'Facebook'); // 返回[],因为没有删除任何元素
arr; // ['Microsoft', 'Apple', 'Google', 'Facebook', 'Oracle']
join 连接数组元素
join()
方法是一个非常实用的方法,它把当前Array的每个元素都用指定的字符串连接起来,然后返回连接后的字符串:
如果Array的元素不是字符串,将自动转换为字符串后再连接。
var arr = ['A', 'B', 'C', 1, 2, 3];
arr.join('-'); // 'A-B-C-1-2-3'
多维数组
如果数组的某个元素又是一个Array,则可以形成多维数组,例如:
var arr = [[1, 2, 3], [400, 500, 600], '-'];
数组相等判断的注意点
javascript是不能用 ==
或===
操作符直接比较两个数组是否相等的
只能使用循环,一个个判断两个数组是否完全相等
JS对象
JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成,用于描述现实世界中的某个对象。例如,为了描述“小明”这个淘气的小朋友,我们可以用若干键值对来描述他:
var xiaoming = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
height: 1.70,
weight: 65,
score: null
};
JavaScript用一个{...}
表示一个对象,键值对以xxx: xxx
形式申明,用,隔开。注意,最后一个键值对不需要在末尾加,如果加了,有的浏览器(如低版本的IE)将报错。
访问属性是通过.操作符完成的,但这要求属性名必须是一个有效的变量名。如果属性名包含特殊字符,就必须用’'括起来:
var xiaohong = {
name: '小红',
'middle-school': 'No.1 Middle School'
};
xiaohong的
属性名middle-school
不是一个有效的变量,就需要用’'括起来。访问这个属性也无法使用.操作符,必须用['xxx']
来访问:
xiaohong['middle-school']; // 'No.1 Middle School'
xiaohong['name']; // '小红'
xiaohong.name; // '小红'
由于JavaScript的对象是动态类型,你可以自由地给一个对象添加或删除属性:
var xiaoming = {
name: '小明'
};
xiaoming.age; // undefined
xiaoming.age = 18; // 新增一个age属性
xiaoming.age; // 18
delete xiaoming.age; // 删除age属性
xiaoming.age; // undefined
delete xiaoming['name']; // 删除name属性
xiaoming.name; // undefined
delete xiaoming.school; // 删除一个不存在的school属性也不会报错
如果我们要检测xiaoming
是否拥有某一属性,可以用in操作符:
var xiaoming = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
height: 1.70,
weight: 65,
score: null
};
'name' in xiaoming; // true
'grade' in xiaoming; // false
不过要小心,如果in
判断一个属性存在,这个属性不一定是xiaoming
的,它可能是xiaoming
继承得到的
技巧:要判断一个属性是否是xiaoming
自身拥有的,而不是继承得到的,可以用hasOwnProperty()
方法
注意点:
遍历对象属性时只能使用 ['xxx']
方法来访问
var xiaoming = {
name: '小明',
birth: 1990,
school: 'No.1 Middle School',
height: 1.70,
weight: 65,
score: null
};
for(var i in xiaoming){
console.log(`${i}:${xiaoming[i]}`);
}
//会正常输出结果
name:小明
birth:1990
school:No.1 Middle School
height:1.7
weight:65
score:null
如果是
for(var i in xiaoming){
console.log(`${i}:${xiaoming.i}`);
}
//输出结果为
name:undefined
birth:undefined
school:undefined
height:undefined
weight:undefined
score:undefined
之所以是这个结果,是因为前面的 i
会正常遍历对象的属性名,并输出。后面的 xiaoming.i
实际上是访问的 xiaoming
这个对象的 i
属性,因为没有所以才会输出 undefined
。
如果给变量增加 i 这个属性,就会发现,输出结果会打印 7 遍 i 这个属性对应的值。
JS类型转换:
参考菜鸟教程
https://www.runoob.com/js/js-type-conversion.html
//typeof操作符 判断数据类型
console.log(typeof "123");
console.log(typeof 3.14);
console.log(typeof NaN); //number
console.log(typeof false);
console.log(typeof [1, 2, 3, 4]); //object
console.log(typeof {
name: "123",
age: 18
}); //object
console.log(typeof new Date()); //object
console.log(typeof
function () {}
); //function
console.log(typeof mycar); //undefind
console.log(typeof null); //object
//注意:
//NaN typeof是number
// null typeof是object
//数组,日期typeof是object,无法通过typeof来判断他们的实际类型
一元运算符+
var y = "5"; // y 是一个字符串
var x = + y; // x 是一个数字
var y1 = "John"; // y1 是一个字符串
var x1 = + y; // x1 是一个数字 (NaN)
JS条件判断 和 逻辑判断:
===
叫做严格运算符,==
叫做相等运算符。
由于js的缺陷,条件判断尽量不要使用==
而要使用===
除了判断 x == null
,因为即将 x == null
是 x === null || x === undefined
的缩写
严格运算符(===)的运算规则如下:
(1)不同类型值
如果两个值的类型不同,直接返回false。
(2)同一类的原始类型值
同一类型的原始类型的值(数值、字符串、布尔值)比较时,值相同就返回true,值不同就返回false。
(3)同一类的复合类型值
两个复合类型(对象、数组、函数)的数据比较时,不是比较它们的值是否相等,而是比较它们是否指向同一个对象。
(4)undefined和null
undefined 和 null 与自身严格相等。
undefined === undefined//true
null === null //true
相等运算符(==)的运算规则如下:
相等运算符在比较相同类型的数据时,与严格相等运算符完全一样。
但在比较不同类型的数据时,相等运算符会先将数据进行类型转换,然后再用严格相等运算符比较。
类型转换规则如下:
(1)原始类型的值
原始类型的数据会转换成数值类型再进行比较。
(2)对象与原始类型值比较
对象(这里指广义的对象,包括数值和函数)与原始类型的值比较时,对象转化成原始类型的值,再进行比较。
(3)undefined和null
undefined和null与其他类型的值比较时,结果都为false,它们互相比较时结果为true。
相等运算符(==)的缺点
由于相等运算符隐藏的类型转换,会带来一些违反直觉的结果。
'' == '0' // false
0 == '' // true
0 == '0' // true
false == 'false' // false
false == '0' // true
false == undefined // false
false == null // false
null == undefined // true
' \t\r\n ' == 0 // true
==结果为true的表格
===结果为true的表格
与&& 或|| 非!和java类似
! NaN,返回值是true
! 对象,返回值是false
! undefined,返回值是true
JS String 注意点:
字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果:
var s = 'Test';
s[0] = 'X';
alert(s); // s仍然为'Test'
注意,调用这些方法本身不会改变原有字符串的内容,而是返回一个新字符串
charAt() 返回在指定位置的字符
indexOf() 返回某个指定的字符串值在字符串中首次出现的位置
includes() 查找字符串中是否包含指定的子字符串(注意末尾有s)
lastIndexOf() 从后向前搜索字符串,并从起始位置(0)开始计算返回字符串最后出现的位置
startsWith() 查看字符串是否以指定的子字符串开头
endsWith() 查看字符串是否以指定的子字符串结尾
repeat() 复制字符串指定次数,并将它们连接在一起返回
concat() 连接两个或更多字符串,并返回新的字符串
slice() 提取字符串的片断,并在新的字符串中返回被提取的部分
substr(x,length) 从索引x开始提取长度为length的字符串
substring(x,y) 提取字符串中位置为[x,y)字符
trim() 去除字符串两边的空白
split() 把字符串分割为字符串数组
toLowerCase() 把字符串转换为小写
toUpperCase() 把字符串转换为大写
fromCharCode() Unicode 编码 -> 字符
charCodeAt() 字符 -> Unicode 编码
toString() 返回一个字符串
valueOf() 返回某个字符串对象的原始值,该方法通常由 JavaScript 在后台自动进行调用,而不是显式地处于代码中。
正则相关:
replace() 在字符串中查找匹配的子串, 并替换与正则表达式匹配的子串
match() 查找找到一个或多个正则表达式的匹配
search() 查找与正则表达式相匹配的值
截取字符串的注意点
当传的参数都为正数的时候,substring和substr没有区别。当参数为负数时,三个函数的行为不尽相同。
- slice() - 将传入的负参数与字符串长度相加;
- substring() - 把所有的负值置为0;
- substr() - 将负的第一个参数与字符串长度相加,负的第二个参数置为0。
var str = 'hello world';
console.log(str.slice(-3)); // rld
console.log(str.substring(-3));// hello world
console.log(str.substr(-3));// rld
console.log(str.slice(3, -4)); // lo w
console.log(str.substring(3, -4)); // hel
console.log(str.substr(3, -4));// ""(空字符串)
运算过程如下:
slice(-3) => slice(8)
substring(-3) => substring(0)
substr(-3) => substr(8)
slice(3, -4) => slice(3, 7)
substring(3, -4) => substring(3, 0) =>substring(0, 3)
substr(3, -4) => substr(3, 0)
ES6中新增string特性:
多行字符串
由于多行字符串用\n写起来比较费事,ES6标准新增了一种多行字符串的表示方法,用反引号" ` "
console.log(`多行
字符串
测试`);
输出:
多行
字符串
测试
模板字符串
当有很多变量和字符串需要连接的时候,使用+
就很不方便,ES6新增了模板字符串
var name = '小明';
var age = 20;
var message = `你好, ${name}, 你今年${age}岁了!`;
alert(message);
输出
你好, 小明, 你今年20岁了!
JS函数
调用时参数个数和声明的参数个数可以不一致