目录
| 函数
声明与调用
参数
返回值
arguments(JS特有知识点)
命名函数 和 匿名函数
| 作用域
全局和局部、JS5没有块级作用域
就近原则:作用域链
| 预解析(重要)
导论:四种语句位置导致的现象
上述现象的原理:JS编译的流程【重点!】
预解析相关面试考核点
| 自定义对象
创建对象
使用对象的属性、方法
【辨析】变量、属性、函数、方法
new 关键字执行的四个步骤
对象的遍历 使用for...in...
总结
| 内置对象
官方API
数学对象Math
日期对象Date
数组对象 Array
基本包装类型 & 字符串不可变
字符串对象 String
[案例] 统计出现次数最多的字符
| 函数
声明与调用
参数
-
JS的形参声明,不需要声明类型! 直接写变量名即可
函数形参和实参个数不匹配问题
经过测试,在函数形参中修改数组的元素,相当于修改数组对应地址的元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var nums = [1,2,3];
alert(nums);// 1 2 3
changeArrayElements(nums);
function changeArrayElements(array) {
array[1] = 5;
}
alert(nums);// 1 5 3
</script>
</head>
<body>
</body>
</html>
返回值
注意一下JS返回值 和Java的不同点
-
不需要在函数声明的语句中写返回类型
-
只需要写return XXX; 即可
-
JS中所有函数都有返回值!若不写return,也会有默认的返回值:undefined
-
return 语句之后的代码不被执行。return 只能返回一个值。如果用逗号隔开多个值,以最后一个为准。
代码示例
function getStr(){
return 'AAA';
}
function getUndefined(){
}
alert(getStr()); //AAA
alert(getUndefined()); //undefined
arguments(JS特有知识点)
-
arguments的作用:存储所有传递过来的实参。
-
本质是一个对象。有点类似于Java的map
-
所有的JS函数都内置了这个对象,放心使用!
介绍
示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
useArguments(1,2,3,4);
// 若形参的个数不确定,则我们干脆不写形参了。这样的话,我们的JS会自动帮我们把传进来的形参,放进arguments[]数组中
function useArguments() {
// arguments的本质是一个对象。有点类似于Java的map
console.log(arguments); //Arguments { 0: 1, 1: 2, 2: 3, 3: 4, … }
}
</script>
</head>
<body>
</body>
</html>
命名函数 和 匿名函数
介绍
命名函数:
匿名函数:
注意事项
-
对于命名函数,调用函数的代码既可以放到声明函数的前面,也可以放在声明函数的后面;
对于匿名函数,函数调用的代码必须写到函数体后面
-
匿名函数声明 var XXX = function(){...}; 此时XXX存储的是一个函数
| 作用域
全局和局部、JS5没有块级作用域
-
JS的作用域和Java差不多,都是全局是全局作用域,函数内是局部作用域
-
但是JS有一种特殊情况:在函数内部声明的变量也是全局变量。 如下
-
需要特别注意的是:JS5除了函数外,其它的都不是块级作用域!即:if、for中定义的变量,是全局变量! JS6后,if、for里的变量才是局部变量。
就近原则:作用域链
说人话就是:有两个同名变量,函数中调用这个名字的变量的时候,到底用哪一个变量? 就近原则
示例
| 预解析(重要)
导论:四种语句位置导致的现象
JS是一门解释型语言,即:逐行运行,逐行编译。因此,这对于代码顺序的要求有些严格。下面给出一些例子
上述现象的原理:JS编译的流程【重点!】
知识点【重点!】
四种语句位置现象的解释
第二种情况undefined的原因:JS预编译,把变量声明var nume提升到当前作用域最前面,但是赋值操作没有提升,所以相当于没有赋值,输出undefined
第三种情况:命名函数的调用在声明语句的前后都可以生效的原因:JS会把函数声明提升到当前作用域的最前面,然后调用语句都是在预编译之后的函数声明语句后面的位置,因此都可以调用~
第四种情况报错的原理:先声明了一个fun的变量,但是并没有赋值函数体,此时调用了fun(),但是JS认为此时JS是一个变量而不是一个函数,因此输出“这不是一个函数”的报错
预解析相关面试考核点
上面的代码预解析后为:
变量提升:声明提到最前面,但是不赋值;函数提升:函数声明提到最前面,但是不调用
var num;
function fun() {
var num;
console.log(num);
num = 20;
}
num = 10;
fun();
最终输出的是:undefined
var a=b=c=9; 相当于 var a=9 ; b=9 ; c=9; a是局部变量,b和c是全局变量
上面的代码预解析后为:
//函数提升
function f1() {
//变量提升
var a;
a=b=c=9;
console.log(a);
console.log(b);
console.log(c);
}
f1(); //9 9 9
console.log(c);// 9
console.log(b);// 9
console.log(a);// 局部变量,报错
| 自定义对象
创建对象
利用字面量创建对象
-
{ } 里面采取键值对的形式表示。var只需要在对象外面声明。 对象内的属性使用键值对【冒号】链接。 对象内的是匿名函数
-
注意对象名后面和花括号之间是 = 属性名和属性值之间是 : 属性值后面是, 而不是;
利用 new Object 创建对象
Object是固定写法。注意O是大写
-
利用等号追加赋值,且后面是分号结尾
-
JS中的对象,可以往里面追加属性
//new关键字定义对象
var obj2 = new Object();
obj2.name = 'Klee2';
obj2.age = 10;
obj2.f2 = function() {
alert('Hi~ ');
}
obj2['name'];
obj2.f2();
利用构造函数创建对象(常用)
-
构造函数不需要写return
//构造函数定义对象
function Person(name , age , sex) {
this.name = name;
this.age = age;
this.sex = sex;
this.f3 = function() {
alert('name = '+name+';age = '+age+';sex = '+sex);
}
}
obj3 = new Person('Klee3 , 12 , Women');
console.log(obj3.name);
obj3.f3();
使用对象的属性、方法
第一种方法 调用方法一
对象名.属性名;
第二种方法 调用属性
对象名['属性名'];
使用对象的函数
-
注意:匿名函数(方法)的调用,需要在属性名后面加上一个()哦
-
定义在对象外的function被称为【函数】,定义在对象内的function被称为【方法】
对象名.函数名();
代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//字面量定义对象
var obj1 = {
name : 'Klee',
age : 9,
f1 : function() {
alert('I\'m Klee');
}
}
//调用对象
console.log(obj1.name); //klee
console.log(obj1['name']); //klee
obj1.f1();
</script>
</head>
<body>
</body>
</html>
【辨析】变量、属性、函数、方法
变量:使用 var 关键字单独声明和赋值。如 var num = 10;
属性:在类中,无需关键字 var 声明,且使用键值对进行赋值。 如 var obj = { num : 10; }
函数:单独声明和调用。调用的时候单独使用 函数名( );
方法:在对象里面声明,相当于匿名函数。 调用的时候通过 对象名.方法名( );
new 关键字执行的四个步骤
对象的遍历 使用for...in...
总结
| 内置对象
官方API
授人以鱼不如授人以渔,以后可以来这里查找一些JS的内置对象
MDN: MDN Web Docs
数学对象Math
Math可以直接调用里面的方法。Math不需要构造函数创建对象
基本运算
随机函数
示例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var nums = [-1,0,2,3,3];
//基本运算
console.log(Math.PI); //3.1415...
console.log(Math.floor(2.33)); //向下取整 2
console.log(Math.ceil(2.33)); //向上取整 3
console.log(Math.round(-2.5)); //变大的四舍五入 -2
console.log(Math.round(2.5)); //变大的四舍五入 3
console.log(Math.abs(-2.3)); //绝对值 2.3
console.log(Math.max(3,4,5)); //最大值 3
console.log(Math.min(-1,1,0)); //最小值 -1
console.log(Math.max()); //没有参数 则Math.max返回 -Infinity
console.log(Math.max(1,'Klee'));; //有非数字,则返回 NaN
console.log(Math.min()); //没有参数 则Math.min返回 Infinity
// 函数:获取[min,max]的整数。 Math.Random()获取 [0,1)的小数
function getRandom(min , max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
console.log(getRandom(20,40));
</script>
</head>
<body>
</body>
</html>
日期对象Date
日期对象Date需要通过构造函数创建对象,需要实例化后才能使用
创建日期对象
日期对象格式化
-
默认格式:很丑,我们需要学会格式化时间。
-
需要获取日期指定的部分,所以我们要手动的得到这种格式
获取日期总毫秒
-
Date 对象是基于1970年1月1日(世界标准时间)起的毫秒数
-
我们经常利用总的毫秒数来计算时间,因为它更精确
上述三个知识点的代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
//构造日期对象
var date1 = new Date();//构造函数没有参数,则返回当前时间
console.log(date1);
//构造函数有参数,数字格式的时间 XXXX,XX,XX 则产生对应时间的date(JS的月份从0开始,数字为n,则JS认为是n+1月)
var date2 = new Date(2001,1,1);
console.log(date2); //返回的是Febrary 2月【即通过数字型格式参数赋值的月份,比规定的要大一个月】
var date3 = new Date('2001-1-1 8:8:8');//使用字符串时间的格式 'XXXX-XX-XX XX:XX:XX' (推荐!!!!)
console.log(date3); //通过字符串格式产生的date对象,月份和参数一致
//日期格式化
var year = date1.getFullYear();
var month = date1.getMonth();
var day = date1.getDate();
console.log('今天是'+year+'年'+month+'月'+day+'日'); //今天是2022年4月23日【错误!需要注意,获取到的month从0开始,因此需要加1】
console.log('今天是'+year+'年'+(month+1)+'月'+day+'日'); //今天是2022年5月23日 正确
//当前日期的毫秒值(距1970.1.1)
var date4 = new Date();
console.log(date4.valueOf()); //1653310553063
console.log(date4.getTime()); //1653310553063
var dateTime = +new Date(); //+new Date() 返回的就是总的毫秒数
console.log(dateTime); //1653310553063
var dateTime2 = Date.now();//Html5新方法 有兼容问题
console.log(dateTime2); //1653310553063
</script>
</head>
<body>
</body>
</html>
数组对象 Array
判断是否为数组
-
instanceof 运算符,可以判断一个对象是否属于某种类型
-
Array.isArray()用于判断一个对象是否为数组,isArray() 是 HTML5 中提供的方法
var arr = [1, 23];
var obj = {};
console.log(arr instanceof Array); // true
console.log(obj instanceof Array); // false
console.log(Array.isArray(arr)); // true
console.log(Array.isArray(obj)); // false
向数组增删元素
数组排序
数组索引方法
数组转为字符串
其它操作
上述操作的所有代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var nums = [1,2,3,4,5,6];
//判断是否为数组
console.log(nums instanceof Array);//true
console.log(Array.isArray(nums));//true
console.log(nums.toString());//1 2 3 4 5 6
//push向末尾增加一个 / 多个元素(改变原数组)
nums.push(7,8);
console.log(nums.toString()); //1 2 3 4 5 6 7 8
//pop删除最后一个元素(改变原数组)
nums.pop();
console.log(nums.toString());//1 2 3 4 5 6 7
//unshift向开头增加一个 / 多个元素(改变原数组)
nums.unshift(-2,-1,0);
console.log(nums.toString());//-2 -1 0 1 2 3 4 5 6 7
//shift删除第一个元素(改变原数组)
nums.shift();
console.log(nums.toString());//-1 0 1 2 3 4 5 6 7
//数组reverse()颠倒数组(改变原数组)
var nums2 = nums.reverse();
console.log(nums2.toString());//7,6,5,4,3,2,1,0,-1
console.log(nums.toString());//7,6,5,4,3,2,1,0,-1
//数组sort( )排序数组
var nums3 = [3,5,2,4,5,6,5,3,2,4,4,2];
nums3.sort();
console.log(nums3.toString());//2,2,2,3,3,4,4,4,5,5,5,6
//使用indexOf()查找元素的第一个索引
console.log(nums3.indexOf(3));//3 即:元素3第一次出现的索引是3
//使用lastIndexOf()查找元素的最后一个索引
console.log(nums3.lastIndexOf(5));//10
//除了toString,join('分隔符') 也可以把数组转为字符串
console.log(nums3.join(' | '));//2 | 2 | 2 | 3 | 3 | 4 | 4 | 4 | 5 | 5 | 5 | 6
//concat()用来连接两个数组为一个新数组
var nums4 = [1,2];
var nums5 = [3,4];
var nums6 = nums4.concat(nums5);
console.log(nums6.toString());//1,2,3,4
//slice(beginIndex , endIndex)返回被截取项目的新数组,返回的是 [begin , end) 上的元素
var nums7 = nums6.slice(1,3);
console.log(nums7.toString());//2,3
//splice(开始的索引数 , 要删除的个数)
var nums8 = [1,2,3,4,5,6];
nums8.splice(2,3);//从索引2开始,删除3个数
console.log(nums8.toString());//1,2,6
</script>
</head>
<body>
</body>
</html>
基本包装类型 & 字符串不可变
基本包装类型
字符串不可变
字符串对象 String
正如前面所说,字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串
根据字符返回位置
应用
根据位置返回字符(重点)
ASCII表
字符串操作方法
替换索引的字符
把数组 → 字符串
array.join('');
上述语法的详细代码示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var str1 = 'Klee';
//根据字符返回位置
console.log(str1.indexOf('K'));//0
console.log(str1.indexOf('K',1));//('K',1)代表从索引=1的地方开始查找。因为没有找到K 所以返回的是 -1
console.log(str1.lastIndexOf('e'));//3
//根据位置返回字符
var c1 = str1.charAt(0);
console.log(c1);//K
var c2 = str1[0];
console.log(c2);//K H5、IE8+、CharAt支持
//根据位置返回字符的ASCII码
console.log(str1.charCodeAt(0));//75 (K的ASCII码是75)
//substr(开始索引,字符个数) 截取字符串
console.log(str1.substr(1,2));//le
//replace(被替换字符串 ,要替换的字符串)
console.log(str1.replace('le','el'));//leke
</script>
</head>
<body>
</body>
</html>
[案例] 统计出现次数最多的字符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
// 有一个对象 来判断是否有该属性 对象['属性名']
var o = {
age: 18
}
if (o['sex']) {
console.log('里面有该属性');
} else {
console.log('没有该属性');
}
// 判断一个字符串 'abcoefoxyozzopp' 中出现次数最多的字符,并统计其次数。
// o.a = 1
// o.b = 1
// o.c = 1
// o.o = 4
// 核心算法:利用 charAt() 遍历这个字符串
// 把每个字符都存储给对象, 如果对象没有该属性,就为1,如果存在了就 +1
// 遍历对象,得到最大值和该字符
var str = 'abcoefoxyozzopp';
var o = {};
for (var i = 0; i < str.length; i++) {
var chars = str.charAt(i); // chars 是 字符串的每一个字符
if (o[chars]) { // o[chars] 得到的是属性值
o[chars]++;
} else {
o[chars] = 1;
}
}
console.log(o);
// 2. 遍历对象
var max = 0;
var ch = '';
for (var k in o) {
// k 得到是 属性名
// o[k] 得到的是属性值
if (o[k] > max) {
max = o[k];
ch = k;
}
}
console.log(max);
console.log('最多的字符是' + ch);
</script>
</head>
<body>
</body>
</html>