基础数据类型
- Number,数值类型,包含整数和浮点数。其中包含一个特殊的数值类型
NaN
,它表示一个非数值类型的数值,但它的数据类型属于数值类型。 - Boolean,布尔值,true和false
- String,字符串
- undefined,内置的一个特殊类型,表示未定的类型
- null,内置的一个特殊类型,表示对象为null(空)
注:基础数据类型的值不可变。如果赋值,其实是重新创建一个新的对象。
字符串
substr(a,b)
从下标a位开始截取,共截取b个长度的字符;
substring(a,b)
从下表a未开始截取,共截取b-a个长度的字符,包含a小标不包含b下标的字符;
str[0]
可以直接从字符串中获取指定下表的字符,一个字符串可以当字符数组使用;
indexOf(a)
获取字符串指定下标的字符;
length
返回字符串长度。无法更改
流程控制
if判断
与java
用法一致。
循环
以下3个循环与java
中的用法一致。
-
for循环
-
while循环
-
**do{}while()**循环
JavaScript特有的循环
forEach 循环。
有2中循环方式,只是传入的函数参数不同(1个或3个)。
//forEach 循环标准写法,传入一个函数,用于执行循环体
// 第一种,只传入一个参数,则该参数的值为数组的值
let ints = [1,2,4,5,6,7,8,9,23,12,125,89];
ints.forEach(function (value) {
console.log(value);
});
//forEach循环,传入的函数为3个参数时,则参数分别为当前循环的值,当前循环的下标和数组本身
ints.forEach(function (value, index, array) {
console.log('value:'+value+',index:'+index+',array:'+array);
})
//传入的函数可以简写,类似于java中的 lambda 表达式
ints.forEach(value => console.log(value));
ints.forEach((value, index, array) => console.log('value:'+value+',index:'+index+',array:'+array));
for in 循环。
注:for in 循环中,循环的得到的变量为数组的下标。
// 其中的 index 为数组的下标
for (const index in ints) {
console.log('index:' + index + ', value=' + ints[index]);
}
for of 循环
注:for of 循环中,循环的得到的变量为数组中实际的值。
// 其中的 value 为数组的实际值
for (const value of ints) {
console.log('value=' + value);
}
Map和Set
Map
存储一个键值对[key, value]对象的集合容器,且其中的key不能重复,如果key相同,则覆盖旧的对象。与java
中的map
基本类似。
//定义map,并传入一个数组来初始化内容
let map1 = new Map([['a',22],['b',23],['c',24]]);
//从map中获取数据
console.log(map1.get('a'));
//向map添加数据
map1.set('e', 12);
//删除map中的数据
map1.delete('c');
//判断某个key是否存在
map1.has("d");
//map遍历1
console.log('map.forEach()-------------');
map1.forEach(value => console.log(value));
map1.forEach((value, key) => console.log(value + ',' + key));
map1.forEach((value, key, map) => console.log(value + ',' + key + ',' + map));
//map遍历2,迭代器
console.log('map.entries()-------------');
for (const entry of map1.entries()) {
//其中的 entry 为map中一个元素的数组形式,如:[key,value]
console.log(entry[0] + ', ' + entry[1]);
};
//map特殊遍历1,key 的遍历
console.log('map.keys()-------------');
for (const key of map1.keys()) {
console.log(key);
};
//map特殊遍历2,value 的遍历
console.log('map.values()-------------');
for (const value of map1.values()) {
console.log(value);
};
Set
存储一个无序不重复的集合容器。与java
中的Set
基本类似。
//Set,创建,并初始化数据
let set1 = new Set([1, 1, 1, 2, 2, 3, 4, 5, 5, 6]);
//添加元素
set1.add(3);
//删除元素
set1.delete(6);
//判断是否存在指定的元素
set1.has(6);
//循环
console.log('set.forEach()-------------');
set1.forEach(value => console.log(value));
set1.forEach((value, value2) => console.log(value + ', ' + value2));
set1.forEach((value, value2, set) => console.log(value + ', ' + value2 + ', ' + set));
console.log('for of set ()-------------');
for (let value of set1) {
console.log(value);
}
console.log('for of set.values()-------------');
for (let value of set1.values()) {
console.log(value);
}
console.log('for of set.entries()-------------');
for (const entry of set1.entries()) {
//其中的 entry 为map中一个元素的数组形式,如:[key,value],而在set中,返回的数组entry数组的key和value是一样的
console.log(entry[0] + ', ' + entry[1]);
};
函数
定义函数
//定义函数1,标准写法
function abs1(x) {
if (x > 0) {
return x;
} else {
return -x;
}
}
//定义函数2,类似与java的匿名类
let abs2 = function (x) {
if (x > 0) {
return x;
} else {
return -x;
}
}
调用函数
//直接调用即可,2者调用方式一样
abs1(10);
abs2(10);
函数内置的对象
arguments
arguments
是函数内置的一个对象,用于表示实际调用该函数时所传入的参数一个数组。数组的内容为传入的参数的值,数组的长度为传入的参数的个数。
注:在JavaScript
中,调用函数时,可以传入任意个数的参数,不管被调用的函数定义时有几个参数。
//函数内置的 arguments 测试
function f1(x) {
let len = arguments.length;
console.log('arguments.length:' + len);
for (let i = 0; i < len; i++) {
console.log(arguments[i]);
}
};
//调用函数,传入特意个数的参数,此时,arguments.length=3,并且会打印出3个参数的内容
f1(1, 2, 43);
rest 可变长度参数
reset
是在函数定义时使用可变参数的一种语(其实只是可变参数的一种官方叫法,并不属于关键字),其格式为:…参数名。当调用函数时传入的参数个数超过函数所定义的参数个数,则按顺序将值赋值给对应参数,剩余的参数全部由可变参数来接受,成为一个数组,结构与函数内置的arguments
对象类似。
注:可变参数必须写在函数参数列表中最后一个,一个函数也可以没有其它参数,有且仅有一个可变参数,如:function fun(…params)。
//rest 可变参数测试
function f2(a, b, ...params) {
let len1 = arguments.length;
console.log('arguments.length:' + len1);
for (let i = 0; i < len1; i++) {
//会打印所有参数
console.log(arguments[i]);
}
let len2 = params.length;
console.log('params.length:' + len2);
for (let i = 0; i < len2; i++) {
//只打印a,b参数之后的参数
console.log(params[i]);
}
};
//调用函数后,函数的参数值更别为:a=1,b=2,params=[4,7,9]
f2(1, 2, 4, 7, 9);
变量
定义变量
在JavaScript中定义变量不需要指明数据类型,而是在执行时JavaScript引擎动态的判断数据类型。
在定义时,使用var
或let
来定义变量,如:var a =1; let b=‘A’;。
JS执行引擎在执行时,会将代码块中的所有定义变量自动提取到代码块内的第一行,但只是将定义移动到第一行,给变量的赋值的代码的位置是不会变的。因此在js中,哪怕一个变量在代码块后面才声明,但是在前面仍然可以使用,只是在前面使用时,它的值为
undefined
。例如:
function f1(){
let a=1;
console.log(a);
let b='a';
}
//实际js引擎在执行时,会将代码调整为如下顺序
function f1(){
let a,b;
a=1;
console.log(a);
b='a';
}
建议:将所有变量都放在代码块内第一行,能赋值的就在定义时直接赋值,不能赋值的就只做定义。这样可能有利于提高js的性能。
var 与 let 区别
var 关键字在定义变量后,出了当前内部的代码块仍然可以使用,作用域比较大。
function f1() {
//使用var在循环内定义的变量i
for (var i = 0; i < 3; i++) {
console.log(`inner for:` + i);
}
//出了循环后,仍然可以使用变量i,但是仅限在函数f1()内可以用,除了函数则无法使用变量i
console.log(`outer for:` + i);
};
f1();
let 关键字在定义变量后,则只在所定义的代码块中有效,作用域比较小。
function f2() {
//使用let在循环内定义的变量j
for (let j = 0; j < 3; j++) {
console.log(`inner for:` + j);
}
//出了循环后,则无法在使用变量j,此语句会报错:Uncaught ReferenceError: i is not defined
console.log(`outer for:` + j);
};
f2();
建议:尽量使用let
来定义变量,已降低变量的作用域。
只读变量(常量)
只读变量也叫常量,它只能在定义时进行一次赋值,之后则不能再进行赋值。它使用关键字 const 来定义
//定义一个常量,且必须进行赋值
const PI=3.14159;
//常量无法进行第二次赋值,此语句会报错:Uncaught TypeError: Assignment to constant variable.
// PI = 2222;
全局变量
全局变量默认绑定在window
下。js实际上只有一个全局作用域——window,任何全局变量都会绑定到window对象下。如:
//定义了一个全局变量
var a=1;
function f1(){
console.log(a);
}
consloe.log(a)
//通过window对象也可以访问a,因此说明全局变量默认都绑定在window对象下
window.a;
建议:由于全局变量都是绑定到window
下,因此很容易导致变量冲突,因此产生了一种约定成熟规范。使用一个自己的全局对象变量,然后在该全局对象变量中进行属性的增删改查操作。如:
//定义一个全局变量对象
var MY_APP_INFO = {};
//然后在其它地方使用时,则只是对该全局对象变量的属性进行操作
MY_APP_INFO.name = 'aaaaa';
MY_APP_INFO.fun1 = function(a,b){.....};
....
方法
在对象中,只会包含属性和方法。
//定义一个对象,该对象包含属性和方法
let person = {
name: 'billy',
birth: 1990,
//定一个对象的方法
age: function () {
let year = new Date().getFullYear();
//此处的this表示person这个对象本身
return year - this.birth;
}
};
function getAge() {
let year = new Date().getFullYear();
//此处的this默认情况下表示调用该函数的那个对象
return year - this.birth;
};
//此时调用,则该函数中的this则指向window对象
getAge();
//定义一个对象,该对象包含属性和方法
let man = {
name: 'man billy',
birth: 2000,
//定义个一个方法,该方法指向外部的一个函数
age: getAge
}
this
默认指向
注:在函数中使用 this 关键字时,默认指向为调用该函数的对象。
更改 this 指向
若想在调用函数时,更改 this 的指向,则需要用到函数的 apply()
方法。
//在js中可以通过调用函数的 apply()方法来指定函数体内使用的this指向,下雨的语句则显示的把函数中this的指向了person对象,因此返回结果为30
let age = getAge.apply(person);
console.log(age);
注:apply()
方法有多个参数,若调用的函数需要传入参数,则可以添加参数。如:fun1.apply(obj,a,b.....)
对象
用户对象
定义对象
以大括号包括,对象里面以键值对的形式进行赋值,每个键值对中间用逗号隔开,最后一个键值对不用逗号。
let person={
name:'billy',
age:18,
email:'234234@qq.com'
}
修改对象属性
person.name = 'jgl'
注:若访问对象的一个属性不存在,也不会报错,只是返回undefined
。
删除对象属性
//删除person对象的emial属性
delete person.email
注:若删除一个对象不存在的属性,也不会报错,仍然会返回true。
增加对象属性
// 直接添加新属性
person.hhhh = '新属性';
判断对象是否包含某个属性
使用in
// 判断person中是否存在age属性,返回true
'age' in person;
// 继承至Object,因此也包含toString方法
'toString' in person;
使用hasOwnProperty()
xxx.hasOwnProperty('xxx')
用于判断对象是否存在自身定义的属性,不包含继承父类的属性
// 返回true,因为包含age属性
person.hasOwnProperty('age')
// 返回false,因为toString为父类属性,自身没有定义,当然如果重写toString,则会返回true
person.hasOwnProperty('toString')
对象的内置函数
valueOf()
对于基本数据类型,封装为对象后,调用该函数返回的是基本数据类型本身的数值。
对于其它对象,返回的是对象本身。但以下各种情况除外:
- NaN:返回的还是NaN
- null:调用该函数会报错;
- undefined:调用该函数为报错;
toString()
对于基本数据类型,封装为对象后,调用该函数返回的是基本数据类型本身的数值。
对于其它对象,一般返回为:[Object, Object]。但以下几种情况除外:
- NaN:返回的是NaN字符串,即:‘NaN’;
- null:调用该函数会报错;
- undefined:调用该函数为报错;
内置对象
Date
let date = new Date();
//获取日期的时间戳
console.log(date.getTime());;
//set新的时间戳来设置新的日期
date.setTime(11132132132);
//get 方法,返回的都是number类型
//年份
console.log(date.getFullYear());
//月份,注意:是从0开始的,因此实际月份需要加1,如:2020-11-23,则返回的月份为10
console.log(date.getMonth());
//日
console.log(date.getDay());
//小时
console.log(date.getHours());
//分钟
console.log(date.getMinutes());
//秒
console.log(date.getSeconds());
//毫秒
console.log(date.getMilliseconds());
//set 方法,与get对应
//to 转换方法,转为:2020/11/23 下午10:49:51
console.log(date.toLocaleString());
//返回:2020/11/23
console.log(date.toLocaleDateString());
//返回:下午10:49:51
console.log(date.toLocaleTimeString());
//...
JSON
//定义一个对象
let person = {
name:`billy`,
age:18,
city: [2, 10, 24]
};
//将对象转成json字符串,JSON.stringify()方法可以传入任何参数
let personString = JSON.stringify(person);
console.log(personString);
//将Json字符串转成Json对象,JSON.parse()方法只能传入字符串参数
let personJson2 = JSON.parse(personString);
console.log(personJson2);
对象原型
可以设置一个对象的原型(父类)来指定该对象的原型(继承)。
object.__proto__ = newObject
let person = {
name: 'human',
sex: 1,
run: function () {
console.log('run...');
}
};
let boy = {
name: 'billy'
};
//设置一个对象的原型,也就是相当于设置一个对象的父类,设置后,就会继承父类的属性和方法
boy.__proto__ = person;
//设置原型后,即可访问原型中的方法和属性
boy.run();
boy.sex;
数组
length
返回数组长度。可以更改。
indexOf(a)
返回数组中指定下标对应的值。
slice(a,b)
截取数组的一部分内容生成一个新的数组。从下标a开始截取,共截取b-a个长度的值,类似于string对象的substring方法,包含下标a的内容,不包含下标b的内容。
push(a…)和pop()
- push(a…):向数组的尾部压入新的内容(压栈),参数可以是多个,类似于list.add();
- pop():返回数组尾部的一个对象,并从数组中移除该对象,类似于出栈;
unshift(a…)和shift()
- unshift(a…):向数组的头部插入新的内容,参数可以是多个,类似于list.add(0, x);
- shift():返回数组头部的一个对象,并从数组中移除该对象;
sort()
升序排序
reverse()
元素反转。如:[1,2,3,4,5]变成[5,4,3,2,1];
concat([…])
向数组中添加其它数组。类似于集合的addAll();
concat()没有修改原数组,而是返回的是一个新的数组。
join(‘-’)
将数组的每个item拼接在一起,每个item中间用指定的字符连接。
如:arr=[‘a’,‘b’,‘c’],则arr.join(’-’) = ‘a-b-c’