学习javascript这一篇就够了超详细笔记(建议收藏)下
7.数组及冒泡排序
数组导读
**学完要掌握的知识点
-能够知道为什么要有数组
-能够创建数组
-能够获取数组中的元素
-能够对数组进行遍历
-能够给数组新增一个元素
-能够独立完成冒泡排序的案例
**学习的知识点
* 数组的概念
* 创建数组
* 获取数组中的元素
* 遍历数组
* 数组中新增元素
* 数组案例
什么是数组以及创建方式
// 1.数组(Array): 就是一组数据的集合 存储在单个变量下的优雅方式
// 2.创建数组有两种方式
// 2.1 利用new 创建数组
var arr = new Array(); // 创建了一个空数组
// 2.2利用数组字面量创建数组 []
var arr = []; //创建了一个空的数组
var arr1 = [1, 5.2, 'fx', true];
// 3.我们数组里面的数据一定用逗号分割
// 4.数组里面的数据 比如 1,5.2 。。。我们成为数组元素
访问数组元素
// 1.获取数组元素 格式 数组名[索引号] 索引号从 0 开始 !!
var arr1 = ['刘亦菲', '刘诗诗', '迪丽热巴'];
console.log(arr1[0]);
console.log(arr1[1]);
console.log(arr1[2]);
console.log(arr1[3]); //因为没有这个数组元素 所以输出的结果是 undefined
练习-数组
var arr1 = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
console.log(arr1[6]);
遍历数组
// 遍历数组 就是把数组的元素从头到尾访问一次
var arr = ['one', 'two', 'three'];
for (var i = 0; i < 3; i++) {
console.log(arr[i]);
}
// 注意:
// 1.因为我们的数组索引号从零开始 所以i 必须从0 开始 i<3
// 2.输出的时候arr[i] i 计数器当索引号来用
练习-遍历数组
var arr = ['刘备', '关羽', '张飞'];
for (var i = 0; i < 3; i++) {
console.log(arr[i]);
}
数组长度
var arr = ['刘备', '关羽', '张飞', '赵云', '马超', '风向', '新成员'];
for (var i = 0; i < 6; i++) {
console.log(arr[i]);
}
console.log(arr.length);
for (var i = 0; i < arr.length; i++) {
console.log(arr[i]);
}
// 1.数组的长度是元素个数 不要跟索引号混淆
// 2.arr.length 动态检测数组元素的个数
案例-计算数组的和以及平均值
// 1.求数组[2,6,6.5,5] 里面所有元素的和以及平均值
// (1)声明一个求和变量 sum
// (2)遍历这个数组 把里面每个数组元素加到 sum 里面
// (3)用求和变量 sum 除以数组的长度就可以得到数组的平均值
var arr = [2, 6, 6, 5, 5];
var sum = 0;
var average = 0;
for (var i = 0; i < arr.length; i++) {
sum = sum + arr[i]; // !!!我们加的是数组元素 arr[i] 不是计数器 i
}
average = sum / arr.length;
console.log(sum, average); // 想要输出多个变量 用逗号分割即可
案例-求数组中的最值
// 求数组[2, 6, 1, 54, 36, 999, 1] 中的最大值
// 声明一个保存最大值的变量 max
// 默认最大值可以取数组中的第一个元素
// 遍历这个数组 把里面每个数祖元素和 max 相比较
// 如果这个数组元素大于 max 就把这个数组元素存到 max 里面 否则继续下一轮比较
// 最后输出 max
// var arr = [2, 6, 1, 54, 36, 999, 1];
// var max = arr[0];
// for (var i = 1; i < arr.length; i++) {
// if (arr[i] > max) {
// max = arr[i];
// }
// }
// console.log('数组中最大值是' + max);
var arr = [2, 6, 1, 54, 36, 999, 1];
var min = arr[0];
for (var i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
console.log('数组中最xiao值是' + min);
数组转换为字符串
// 将数组['red', 'blue', 'fxnb'] 转换为字符串 并且用 | 或其他符号分割
// 1.我们需要一个新变量用于存放转换完的字符串 str
// 2.遍历原来的数组 分别把里面数据取出来 加到字符串里面
// 3.同时在后面多加一个分隔符
var arr = ['red', 'blue', 'fxnb'];
var str = '';
var sep = '$'
for (var i = 0; i < arr.length; i++) {
str += arr[i] + sep;
}
console.log(str);
数组新增元素
// 1.新增数组元素 修改length 长度
var arr = ['red', 'blue', 'fxnb'];
console.log(arr.length);
arr.length = 5; // 把我们数组的长度修改为了 5 里面应该有5个元素
console.log(arr);
console.log(arr[3]); //undefined
console.log(arr[4]);//undefined
//2.新增数组元素 修改索引号 追加数组元素
var arr1 = ['red', 'blue', 'fxnb'];
arr1[3] = 'pink';
console.log(arr1);
arr1[4] = 'hotpink';
console.log(arr1);
arr1[0] = 'fxnb'; // 这里是替代原来的数组元素
console.log(arr1);
arr1 = '有点意思';
console.log(arr1); // 不要直接给 数组名赋值 否则里面的数组元素都没有了
数组存放1~10个值
// 新建一个数组 里面存放10个整数(1~10)
// 核心原里: 使用循环来追加数组
// 1.声明一个空数组 arr
// 2.循环中的计时器 i 可以作为数组元素存入
// 3.由于数组的索引号是从0开始的 因此计数器从0 开始更合适 存入的数组元素要+1
var arr = [];
for (var i = 0; i < 10; i++) {
// arr = i; 不要直接给数组名赋值 否则以前的元素都没了
arr[i] = i + 1;
}
console.log(arr);
筛选数组方法*
第一种
// 将数组[2,0,6,12,6,5,11,36] 中大于等于 10 的元素选出来 放入新数组
// 1.声明一个新的数组用于存放新数据 newArr
// 2.遍历原来的旧数组 找出大于等于10 的元素
// 3.依次追加给新数祖 newArr
var arr = [2, 0, 6, 12, 6, 5, 11, 36];
var newArr = [];
var j = 0;
for (var i = 0; i < arr.length; i++) {
if (arr[i] >= 10) {
// 新数祖索引号应该从0 开始 依次递增
newArr[j] = arr[i];
j++;
}
}
console.log(newArr);
第二种
var arr = [2, 0, 6, 12, 6, 5, 11, 36];
var newArr = [];
// 刚开始 newArr.length 就是0
for (var i = 0; i < arr.length; i++) {
if (arr[i] >= 10) {
// 新数祖索引号应该从0 开始 依次递增
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
// 拓展1 把小于10的选出来
var arr = [2, 0, 6, 12, 6, 5, 11, 36];
var newArr = [];
// 刚开始 newArr.length 就是0
for (var i = 0; i < arr.length; i++) {
if (arr[i] <= 10) {
// 新数祖索引号应该从0 开始 依次递增
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
删除数组指定元素(数组去重)*
// 将数组[2,0,6,1,77,0,52,0,12] 中的 0 去掉后 形成一个不包含 0 的新数祖
// 1.需要一个新数祖用于存放筛选之后的数据
// 2.遍历原来的数组 把不是 0 的数据添加到新数祖里面(此时要注意采用数组名 + 索引的格式接收数据)
// 3.新数祖里面的个数 用length 不断累加
var arr = [12, 0, 6, 1, 77, 0, 52, 0, 12];
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (arr[i] != 0) {
newArr[newArr.length] = arr[i];
}
}
console.log(newArr);
翻转数组*
// 将数组['1', '2', '3', '4', '5'] 的内容反过来存放
// 1.声明一个新数祖 newArr
// 2.把旧数组索引号第四个取过来(arr.length - 1) 给新数组索引号第 0 个元素(newArr.length)
// 3.我们采取 递减的方式 i--;
var arr = ['1', '2', '3', '4', '5'];
var newArr = [];
for (var i = arr.length - 1; i >= 0; i--) {
newArr[newArr.length] = arr[i];
}
console.log(newArr);
复习交换两个变量值
// 交换两个变量
var num1 = 2;
var num2 = 1;
var temp = 0;
temp = num1;
num1 = num2;
num2 = temp;
console.log(num1, num2);
冒泡排序
原理:
// * 冒泡排序是一种简单的排序算法 他重复的走访过要排序的数列 把一系列的数据按照一定的顺序进行排列显示(从小到大or 从大到小)
// (一次比较两个元素 如果他们的顺序错误就把他们交换过来)
// 走访数列的工作是重复的进行直到没
有再需要交换 也就是说该数列已排序完成 这个算法的名字由来是因为越小的元素会经由变换慢慢‘浮’到数列的顶端
//冒泡排序
var arr = [1, 2, 3, 4, 5];
for (var i = 0; i < arr.length - 1; i++) { //外层循环次数
for (var j = 0; j <= arr.length - i - 1; j++) { //里面的循环管 每一趟的交换次数
// 内部交换两个变量的值 前一个和后面一个数组元素相比较
if (arr[j] < arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
console.log(arr);
// ***冒泡算法
// 1.一共需要的趟数 我们用外层 for 循环
// - 五个数据我们一共走4趟 就是走的趟数比数组长度少 1
// - 长度就是 数组长度 减去 1 arr.length - 1
// 2.每一趟交换次数 我们用里层 for 循环
// - 第一趟 交换四次
// - 第二趟 交换三次
// - 第三趟 交换二次
// - 第四趟 交换一次
// - 长度就是 数组长度 减去 次数
// - 但是我们次数 是从0开始的 所以 最终 arr.length - i - 1
// 3.交换两个变量
8.函数及应用
函数导读
**学完应掌握知识点
- 能够说出为什么需要函数
- 能够根据语法书写函数
- 能够根据需求封装函数
- 能够说出形参和实参的传递过程
- 能够使用函数的返回值
- 能够使用argument 获取函数的参数
**学习的知识点
* 函数的概念
* 函数的使用
* 函数的参数
* 函数的返回值
* arguments的使用
* 函数案例
* 函数的两种声明方式
为什么需要函数
// 1.求1~100之间数的和
var sum = 0;
for (var i = 1; i <= 100; i++) {
sum += i;
}
console.log(sum);
// 2.求10~50之间数的和
var sum = 0;
for (var i = 10; i <= 50; i++) {
sum += i;
}
console.log(sum);
// 3.函数就是封装了一段可以被重复执行调用的代码块 目的: 就是让大量代码重复使用
function getSum(num1, num2) {
var sum = 0;
for (var i = num1; i <= num2; i++) {
sum += i;
}
console.log(sum);
}
getSum(20, 60000);
函数的使用
// 函数使用分为两步: 声明函数 和 调用函数
// 1.声明函数
// function 函数名() {
// 函数体
// }
function sayHi() {
console.log('hai');
}
// (1)function 声明函数的关键字 全部小写
// (2)函数是做某件事情 函数名一般是动词 sayHi
// (3)函数不调用自己不执行
// 2.调用函数
// 函数名();
sayHi();
// 调用函数的时候千万不要忘记加小括号
// 3.函数的封装
// - 函数的封装是把一个或者多个功能通过 函数的方式封装起来 对外只提供一个简单的函数接口
// - 简单理解:封装类似于将电脑配件整合组装到机箱中(类似快递打包)
案例-利用函数做一个1~100的累加和
function getSum() {
var sum = 0;
for (var i = 1; i <= 100; i++) {
sum += i;
}
console.log(sum);
}
getSum();
函数的参数
// 1.函数可以重复的相同的代码
function cook() {
console.log('酸辣土豆丝');
}
cook();
cook();
// 2.我们可以利用函数的参数实现函数重复不同的代码
// function 函数名(形参1, 形参2....) { // 在声明函数的小括号里面是 形参 (形式上的参数)
// }
// 函数名(实参1, 实参2....); // 在函数调用的小括号里面是实参(实际的参数)
// 3.形参和实参的执行过程
function cook(agu) { // 形参是用来接收实参的 agu = '爆炒蛤蟆' 形参类似以一个变量
console.log(agu);
}
cook('爆炒蛤蟆');
cook('红烧奥恩');
// 4.函数的参数可以有 也可以没有 个数不限
// **在声明函数时 可以在函数名称后面的小括号中添加一些参数 这些参数被称为形参 而在调用该函数时 同样也需要传递相应的参数 这些参数被称为实参
// 形参:形式上的参数 函数定义的时候 传递的参数 当前并不知道是什么
// 实参:实际上的参数 函数调用的时候传递的参数 实参是传递给形参的
// 参数的作用:在函数内部某些值不能固定 我们可以通过参数在调用函数时传递不同的值过去
案例-利用函数求两个数的和以及两个数之间的累加和
// 1.利用函数求任意两个数的和
function getSum(num1, num2) {
console.log(num1 + num2);
}
getSum(20, 8);
// 2.利用函数求任意两个数之间的和
function sum(start, end) {
var sum = 0;
for (var i = start; i <= end; i++) {
sum = sum + i;
}
console.log(sum);
}
sum(1, 100);
// 3.注意点
// (1)多个参数之间用逗号隔开
// (2)形参可以看做是不用声明的变量
函数的形参和实参的匹配问题
// 函数形参实参个数匹配
function getSum(num1, num2) {
console.log(num1 + num2);
}
// 1.如果实参的个数和形参的个数一致 则正常输出结果
getSum(1, 2);
// 2.如果实参的个数多于形参的个数 只会取到形参的个数
getSum(1, 2, 3);
// 3.如果实参的个数少于形参的个数
// 形参可以看做是不用声明的变量 num2 是一个变量但是没有接收值 结果就是undefined
getSum(1); //NaN
// 建议 尽量让形参和实参的个数相匹配
// ***小结
// - 函数可以带参数也可以不带
// - 声明函数的时候 函数名括号里是形参 形参的默认值为undefined
// - 调用函数的时候 函数名括号里面是实参
// - 多个参数中间用逗号分割
// - 形参的个数可以和实参个数不匹配 但是结果不可预计 我们尽量匹配
函数的返回值
// 1.函数是做某件事或者实现某种功能
// function cook(aru) {
// console.log(aru);
// }
// cook('大肘子');
// 2.函数的返回值格式
// function 函数名() {
// return 需要返回的结果;
// }
// 函数名();
// (1)我们函数只是实现某种功能 最终的结果需要返回给函数的调用者 函数名() 通过return 实现的
// (2)只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名() = return后面的结果
// 3.代码验证
function getResult() {
return 666;
}
getResult(); // getResult() = 666
console.log(getResult());
// function cook(aru) {
// return aru;
// }
// console.log(cook('大肘子'));
// 4.求任意两个数的和
function getSum(num1, num2) {
return num1 + num2;
}
console.log(getSum(25, 65));
案例-利用函数求两个数的最大值
// 利用函数 求两个数的最大值
function getMax(num1, num2) {
// if (num1 > num2) {
// return num1;
// } else {
// return num2;
// }
return num1 > num2 ? num1 : num2;
}
console.log(getMax(5, 1));
案例-利用函数求数组中的最大值
// 利用函数求数组 [5,45,26,748,21] 中的最大值
function getArrMax(arr) { // arr 接收一个数组 arr = [5,45,26,748,21]
var max = arr[0];
for (var i = 1; i <= arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
// console.log(getArrMax([5, 45, 26, 748, 21])); //实参是一个数组送过去
// 在我们实际开发里面 我们经常用一个变量来接收 函数的返回结果 使用更简单
var re = getArrMax([5, 45, 26, 748, 21]);
console.log(re);
return注意事项
// 函数返回值注意事项
// 1.return 终止函数
function getSum(num1, num2) {
return num1 + num2; // return后面的代码不会被执行
alert('我是不会被执行的');
}
console.log(getSum(2, 6));
// 2.return 只能返回一个值
function fn(num1, num2) {
return num1, num2; // 返回的结果是最后一个值 2
}
console.log(fn(1, 2));
// 3.我们求任意两个数的 加减乘除结果
function getResult(num1, num2) {
return [num1 + num2, num1 - num2, num1 * num2, num1 / num2];
}
var re = getResult(1, 2);// 返回的是一个数组
// 遍历一下输出结果
for (var i = 0; i < re.length; i++) {
console.log(re[i]);
}
// 4.我们的函数如果有 return 则返回的是 return 后面的值 如果函数没有 return 则返回undefined
function fun1() {
return 666;
}
console.log(fun1()); //返回值666
function fun2() {
}
console.log(fun2()); // 函数返回的结果是 undefined
// 5.break continue return 的区别
// - break 结束当前的循环体(如for while)
// - continue 跳出本次循环 继续执行下次循环(如for while)
// - return 不仅可以跳出循环 还能够返回return 语句中的值 同时还可以结束当前的函数体内的代码
案例-用函数求两个任意数的加减乘除
var num1 = prompt('请输入第一个数');
var num2 = prompt('请输入第二个数');
function sum(num1, num2) {
return ['加法结果:' + (parseFloat(num1) + parseFloat(num2)), ' ' + '减法结果:' + (parseFloat(num1) - parseFloat(num2)), ' ' + '乘法结果:' + (parseFloat(num1) * parseFloat(num2)), ' ' + '除法结果:' + (parseFloat(num1) / parseFloat(num2))];
}
alert(sum(num1, num2));
案例-用函数求两个数之间的最大值
var num1 = prompt('请输入第一个数');
var num2 = prompt('请输入第二个数');
function max(num1, num2) {
if (num1 > num2) {
return num1;
} else {
return num2;
}
return max;
}
alert('最大数为:' + max(num1, num2));
arguments的使用
// arguments 的使用 只有函数才有 arguments对象 而且是每个函数都内置好了这个arguments
function fn() {
// console.log(arguments); // 里面存储了所有传递过来的实参 arguments = [1,2,3]
// console.log(arguments.length);
// console.log(arguments[2]);
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
fn(1, 2, 3);
fn(1, 2, 3, 4, 5);
// 伪数组 并不是真正意义上的数组
// 1.具有数组中的length 属性
// 2.按照索引的方式进行存储的
// 3.他没有真正数组的一些方法 pop() push() 等等
案例-利用函数求任意个数的最大值
//利用函数求任一个数的最大值
function getMax() { //arguments = [1,2,3]
var max = arguments[0];
for(var i = 1; i < arguments.length; i++) {
if(max < arguments[i]) {
max = arguments[i];
}
}
return max;
}
console..log(get(1,2,3));
console..log(get(1,2,3,4,5,6));
案例-利用函数翻转数组
// 利用函数翻转任意数组 reverse 翻转
function reverse(arr){
var newArr = [];
for(var i = arr.length-1;i >= 0; i--){
newArr[newArr.length] = arr[i];
}
return newArr;
}
arr1 = reverse([1,2,3,4,5]);
console.log(arr1);
案例-函数封装冒泡排序
// 利用函数冒泡排序 sort 排序
function sort(arr){
for(var i = 0; i < arr.length-1;i++){
for(var j = 0; j < arr.length-1-i; j++){
if(arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
// 可以将数组打印出来
var arr1 = sort([25,4,2,56,7879]);
for(var i = 0; i < arr1.length;i++){
console.log(arr1[i]);
}
// 直接输出
var arr2 = sort([20,10,30,5,]);
console.log(arr2);
案例-利用函数判断闰年
// 利用函数判断闰年
function isRunYear(year){
var flag = false;
if(year % 4 == 0 && year % 100 != 0 || year % 100 ==0){
flag = ture;
}
return flag;
}
console.log(isRunYear(2000));
console.log(isRunYear(2001));
函数是可以调用另一个函数的
// 函数是可以调用函数的
function fn1(){
console.log('狂风');
fn2(); // 在fn1 函数里调用了fn2 函数
}
fn1();
function fn2(){
console.log('绝息斩');
}
function fn3(){
console.log('第一');
fn4();
console.log('第四');
}
function fn2(){
console.log('第二');
console.log('第三');
}
fn3();
输出二月份天数
// 用户输入年份 输出当前年份2月份的天数
function backDay(){
var year = prompt('请你输入年份:');
if(isRunYear(year)){
alert('当前年份是闰年2月份有29天');
} else {
alert('当前年份是平年二月份有28天');
}
}
backDay();
// 利用函数判断闰年
function isRunYear(year){
var flag = false;
if(year % 4 ==0 && year % 100 != 0 || year % 100 == 0){
flag = ture;
}
return flag;
}
函数的两种声明方式
//函数的两种声明方式
// 1.利用函数关键字自定义函数(命名函数)
function fn() {
console.log(112);
}
fn();
// 2.函数表达式(匿名函数)
// var 变量名 = function(){};
var fun = function (aru) {
console.log('我是函数表达式');
console.log(aru);
}
fun('22年8月9日晚23:12,自我感动中,fxnb');
// (1)fun是变量名 不是函数名
// (2)函数表达式声明方式跟声明变量差不多 只不过变量里面存的是值 而 函数表达式里面存的是函数
// (3)函数表达式也可以进行传递参数
9.作用域及预解析
作用域导读
***学完需要掌握的知识点
- 能够说出js的两种作用域
- 能够区分全局变量和局部变量
- 能够说出如何在作用域链中查找变量的值
**本章学习的知识点
* 作用域
* 变量的作用域
* 作用域链
js的作用域
// 1.js 作用域: 就是代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性 更重要的是减少命名冲突
// 2.js 的作用域(es6)之前: 全局作用域 局部作用域
// 3.全局作用域:整个script标签 或者是一个单独的js文件
var num = 10;
var num = 30;
console.log(num);
// 4.局部作用域(函数作用域)在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用
function fn() {
// 局部作用域
var num = 20;
console.log(num);
}
fn();
全局变量和局部变量
// 变量的作用域 根据作用域的不同我们变量分为全局变量和局部变量
// 1.全局变量:在全局作用域下的变量 在全局下都可以使用
var num = 10; //num就是一个全局变量
console.log(num);
function fn() {
console.log(num);
}
fn();
// 2.局部变量 在局部作用域下的变量 或 者在函数内部的变量就是 局部变量
// 注意!!函数的形参也可以看做是局部变量
function fun(aru) {
var num1 = 10; //num1就是局部变量 只能在函数内部使用
// 注意!! 如果在函数内部 没有声明直接赋值的变量也属于全局变量
num2 = 20;
}
fun();
// console.log(num1);
console.log(num2);
// 3.从执行效率来看全局变量和局部变量
// (1)全局变量只有浏览器关闭的时候才会销毁 比较占内存资源
// (2)局部变量当我们程序执行完毕就会销毁 比较节约内存资源
js没有块级作用域
// js 中没有块级作用域 js 的作用域: 全局作用域 局部作用域 现阶段我们js 没有块级作用域
// 我们js 也是在 es6 的时候新增的块级作用域
// 块级作用域 {} if{} for{}
// 在java里面
// if (xx) {
// int num = 10;
// }
// 这就是块级作用域 外面是不能调用num的
if (3 < 5) {
var num = 10;
}
console.log(num);
作用域链
// 作用域链 : 内部函数访问外部函数的变量 采取的方式链式查找的方式来决定取哪个值 这种结构我们称作用域链 其实就是就近原则 一层一层查找
var num = 10;
function fn() { // 外部函数
var num = 20;
function fun() { // 内部函数
console.log(num);
}
fun();
}
fn();
案例-作用域链
var a = 1;
function fn1() {
var a = 2;
var b = '22';
function fn2() {
var a = 3;
function fn3() {
var a = 4;
console.log(a);
console.log(b);
}
fn3();
}
fn2();
}
fn1();
预解析导读
***学完应掌握的知识点
* 能够知道解析器运行js分为那两步
* 能够说出变量提升的步骤和运行过程
* 能够说出函数提升的步骤和运行过程
**本章学习的知识点
- 预解析
- 变量预解析和函数预解析
- 预解析案例
预解析*
// 1问
// console.log(num); // 报错
// 2问
// console.log(num); // undefined 坑 1
// var num = 10;
//相当于执行了下列代码
// var num;
// console.log(num); //undefined
// num = 10;
// 3问
// fn();
// function fn() {
// console.log(11);
// }
// 4问
fun(); //报错 坑 2
var fun = function () {
console.log(22);
}
// 相当于执行了以下代码
// !函数表达式 调用必须写在函数表达式的下面
// var fun;
// fun();
// fun = function () {
// console.log(22);
// }
// 1.我们js 引擎运行js 分为两步: 预解析 代码执行
// (1).预解析 js引擎会把js 里面所有的 var 还有 function 提升到当前作用域的最前面
// (2).代码执行 按照代码书写的顺序从上往下执行
// 2.预解析分为 变量预解析(变量提升)和 函数预解析(函数提升)
//(1)变量提升 就是把所有的变量声明提升到当前作用域的最前面 不提升赋值操作
// (2)函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数
案例-预解析
// 案例1
// var num = 10;
// fun();
// function fun() {
// console.log(num);
// var num = 20;
// }
// 相当于执行了下面代码
// var num;
// function fun() {
// var num;
// console.log(num);
// num = 20;
// }
// num = 10;
// fun(); 结果是 undefined
// 案例2
// var num = 10;
// function fn() {
// console.log(num);
// var num = 20;
// console.log(num);
// }
// fn();
// 相当于执行以下操作
// var num;
// function fn() {
// var num;
// console.log(num);
// num = 20;
// console.log(num);
// }
// num = 10;
// fn(); 结果是 20
// 案例3
// var a = 18;
// f1();
// function f1() {
// var b = 9;
// console.log(a);
// console.log(b);
// var a = '123';
// }
// 相当于执行以下操作
// var a;
// function f1() {
// var b;
// var a;
// b = 9;
// console.log(a);
// console.log(b);
// a = '123';
// }
// a = 18;
// f1(); 结果是 9
// 案例4
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {
var a = b = c = 9;
console.log(a);
console.log(b);
console.log(c);
}
// 相当于执行以下操作
// function f1() {
// var a;
// a = b = c = 9;
// // 相当于 var a = 9; b = 9; c = 9; b 和 c 直接赋值 没有var 声明 当全局变量看
// // 集体声明 var a = 9, b = 9, c = 9;
// console.log(a);
// console.log(b);
// console.log(c);
// }
// f1();
// console.log(c);
// console.log(b);
// console.log(a);
// var a 是局部变量 而b和c是全部变量 所以最后一个输出a 会报错
10.对象
对象导读
***学完应掌握的知识点
- 能够说出为什么需要对象
- 能够使用字面量创建对象
- 能够使用构造函数创建对象
- 能够说出new的执行过程
- 能够遍历对象
***本章学习的知识点
* 对象
* 创建对象的三种方式
* new关键字
* 遍历对象属性
什么是对象&为什么需要对象
*** 什么是对象?
* 在js中 对象是一组无序的相关属性和方法的集合 所有的的事物都是对象 例如字符串 数值 数组 函数等
对象是由属性和方法组成的
- 属性:事物的 特征 在对象中用 属性 来表示(常用名词) 比如手机的厚度 宽度 颜色 屏幕尺寸
- 方法:事物的 行为 在对象中用方法来表示(常用动词) 比如可以打电话 发短信
*** 为什么需要对象?
* 保存一个值时 可以使用 变量 保存多个值(一组值)时 可以用 数组 如果要保存一个人的完整信息呢?
例如 将‘张三’的个人信息保存在数组的方式为:
var arr = [‘张三’,‘男’,128,154];
分不清各个参数什么意思
* js中的对象表达结构更清晰 更强大 张三的个人信息在对象中的表达结构如下:
张三.姓名 = ‘张三’; person.name =‘张三’;
张三.性别 = ‘男’; person.sex =‘男’;
张三.年龄 = 128; person.age =128;
张三.身高 = 154; person.height =154;
利用对象字面量创建对象
// 1.利用对象字面量创建对象 {}
// var obj = {}; // 创建了一个空对象
var obj = {
uname:'大黄',
type:'土狗',
age:'5岁',
color:'棕红色',
bark:function(){
console.log('汪汪~');
},
showFilm:function(){
console.log('演电影');
}
}
// (1)里面的属性或者方法我们采用键值对的形式 键 属性名: 值:属性值
// (2)多个属性或者方法中间用逗号隔开的
// (3)方法冒号后面的是一个匿名函数
// 2.使用对象
// (1)调用对象的属性 我们采用 对象名.属性名 .我们理解为 的
console.log(obj.uname);
// (2)调用属性还有一种方法 对象名['属性名']
console.log(obj['age']);
// (3)调用对象的方法 bark 对象名.方法名() 千万别忘记添加小括号
obj.bark();
变量 属性 函数 方法的区别
// 变量 属性 函数 方法 的区别
// 1.变量和属性的相同点 他们都是用来存储数据的
var num = 10;
var obj = {
age: 10,
// 方法
fn: function () {
console.log(66);
}
}
// 函数
function fn() {
}
console.log(obj.age);
// console.log(age);
// 变量 单独声明并赋值 使用的时候直接写变量名 单独存在
// 属性 在对象里面的 不需要声明的 使用的时候必须是 对象.属性
// 2.函数和方法的相同点 都是实现某种功能 做某件事
// 函数 是单独声明 并且调用的 函数名() 单独存在的
// 方法 在对象里面 调用的时候 对象.方法()
// ***结
// - 变量 单独声明赋值 单独存在
// - 属性 对象里面的变量称为属性 不需要声明 用来描述该对象的特征
// - 函数 单独存在的 通过 '函数名()' 的方式就可以调用
// - 方法 对象里面的函数称为方法 方法不需要声明 使用'对象.方法名()'的方式就可以调用 方法用来描述该对象的行为和功能
利用new Object创建对象
// 利用new Object 创建对象
var obj = new Object(); //创建了一个空的对象
obj.uname = '风向';
obj.sex = '帅';
obj.skill = function(){
console.log('螺旋丸');
}
// (1)利用 等号 = 赋值的方法 添加对象的属性和方法
// (2)每个属性和方法之间用 分号结束
console.log(obj.uname);
console.log(obj.sex);
obj.skill();
我们为甚需要构造函数
// 我们为什么需要使用构造函数
// 就是因为我们前面两种创建对象的方式一次只能创建一个对象
var ys = {
uname: '亚索',
age: 36,
feng: function () {
console.log('狂风绝息斩');
}
}
var ye = {
uname: '永恩',
age: 38,
feng: function () {
console.log('双剑华斩');
}
}
// 因为我们一次创建一个对象 里面很多的属性和方法是大量相同的 我们只能复制
// 因此我们可以利用函数的方法 重复这些相同的代码 我们就把这个函数称为 构造函数
// 又因为这个函数不一样 里面封装的不是普通代码 而是 对象
// 构造函数 就是把我们对象里面的一些相同的属性和方法抽象出来封装到函数里面
构造函数创建对象
// 利用构造函数创建对象
// 我们需要创建四大天王的对象 相同的属性:名字 年龄 性别 相同的办法:唱歌
// 构造函数的语法格式
// function 构造函数名(){
// this.属性 = 值;
// this.方法 = function(){}
// }
// new 构造函数名();
function Star(uname,age,sex){
this.uname = uname;
this.age = age;
this.sex = sex;
}
var ldh = new Star('刘德华','18','男');//调用函数返回的是一个对象
console.log(ldh.uname);
console.log(ldh.sex);
// 1.构造函数名字首字母要大写
// 2.我们构造函数不需要return 就可以返回结果
// 3.我们调用构造函数 必须使用 new
构造函数创建对象案例
//首先创造一个函数
function Role (uname,typy,attack){
this.uname = uname;
this.type = type;
this.attack = function(skill){
console.log(skill);
}
}
var houyi = new Role('后裔','射手型');
console.log(houyi.uname);
console.log(houyi['type']);
houyi.attack('超级大鸟');
构造函数与对象的区别
// 构造函数和对象
// 1.构造函数 明星 泛指的某一大类 它类似于 java 语言里的 类(class)
function Star(uname, age, sex) {
this.uname = uname;
this.age = age;
this.sex = sex;
this.sing = function (sang) {
console.log(sang);
}
}
// 2.对象 特指 是一个具体的事物 刘德华 == {uname: '刘德华', age: 18, sex: '男', sing: ƒ}
var ldh = new Star('刘德华', 18, '男'); //调用函数返回的是一个对象
console.log(ldh);
// 3.我们利用构造函数创建对象的过程我们也称为对象的实例化
new关键字执行过程
// new 关键字执行过程 (首先new 和构造函数确认了眼神)
// 1.new 构造函数可以在内存中创建了一个空的对象 (他俩生了一个小宝宝)
// 2.this 就会指向刚才创建的空对象 (这个宝宝必须是亲生的 this指向)
// 3.执行构造函数里面的代码 给这个空对象添加属性和方法 (教孩子读书一肚子知识)
// 4.返回这个对象 不需要return (长大回报父母)
function Star(uname, age, sex) {
this.uname = uname;
this.age = age;
this.sex = sex;
this.sing = function (sang) {
console.log(sang);
}
}
var fx = new Star('风向', '男', 18);
遍历对象
var obj = {
uname:'风向',
age:'18'
}
// console.log(obj.uname);
// console.log(obj.age);
// console.log(obj.sex);
// for in 遍历我们的对象
// for (变量 in 对象) {
// }
for(var k in obj){
console.log(k); //k 变量 输出 得到的是 属性名
console.log(obj[k]); //obj[k] 输出的到的是 属性值
}
// 我们使用for in 里面的变量 我们喜欢写 k 或者 key
对象小结
* 对象可以让代码结构更清晰
* 对象是复杂数据类型object
* 本质:对象就是一组无序的相关属性和方法的集合
* 构造函数泛指某一大类 比如苹果 不管是红色苹果还是绿色苹果 都统称为苹果
* 对象实例特指一个事物 比如这个苹果 正在上课的fx
* for in 语句用于对对象的属性进行循环操作
对象作业
//1.电脑对象 (字面量创建对象)
var computer = {
color:'gray',
brand:'戴尔',
movies:function(){
console.log('喜洋洋');
}
}
console.log(conputer.brand);
console.log(conputer['color']);
computer.movies();
//2.按钮对象 (new object创建对象)
var button = new Object();
button.width = 20;
button.height = 10;
button.bgc = '绿色';
button.click = function(){
console.log('点击了');
}
console.log(button.bgc);
buttoin.click();
//3.车子对象 (构造函数创建对象)
function Car(color,brand,attack){
this.color = color;
this.brand = brand;
this.attack = function(skill){
console.log(skill);
}
}
//公交车
var bus = new('red','东风小康');
console.log(bus.color);
bus.attack('乘客你好');
(翻转数组)函数翻转数组作业
//翻转任意数组
function reverse(arr){
var newArr = [];
for(var i = arr.length-1;i--){
newArr[newArr.length] = arr[i];
}
return newArr;
}
var arr1 = reverse([1,2,3]);
console.log(arr1);
(冒泡排序)函数对数字数组排序作业
function sort(arr){
for(var i = 0; i<arr.length-1;i++){
for(var j = 0; j <arr.length - 1 - i;j++){
if(arr[j]>arr[j + 1]){
temp = arr[1];
arr[1] = arr[j+1];
arr[j+1] = temp;
}
}
}
return arr;
}
var re = sout([500,300,50,20]);
//上例子从小到大排序的
简易计算机
while(true){
var items = prompt('欢迎使用风向简易计算机'+'\n'+'请输入以下序列号以执行操作'+'\n'+'1.加法运算'+'\n'+'2.减法运算'+'3.乘法运算'+'\n'+'4.除法运算'+'\n'+'退出计算机');
switch(parseFloat(items)){
case 1:
var num1 = prmpt('请输入第一个数');
var num2 = prmpt('请输入第二个数');
alert(parseFloat(num1)+parseFloat(num2));
break;
case 2:
var num1 = prmpt('请输入第一个数');
var num2 = prmpt('请输入第二个数');
alert(parseFloat(num1)-parseFloat(num2));
break;
case 3:
alert('欢迎使用风向计算机,再见');
break;
default:
alert('睁开眼睛~!~');
}
if(items == 3) {
break;
}
}
11.内置对象及案例
内置对象导读
***学完应掌握的知识点
- 能够说出什么是内置对象
- 能够根据文档查询指定API的使用方法
- 能够使用Math对象的常用方法
- 能够使用Date对象的常用方法
- 能够使用Array对象的常用方法
- 能够使用String对象的常用方法
**本章学习的知识点
* 内置对象
* 查文档
* Math对象
* 日期对象
* 数组对象
* 字符串对象
什么是内置对象
- js中的对象分为3种:自定义对象 内置对象 浏览器对象
* 前面两种对象是js基础内容 属于ECMAScript; 第三个浏览器对象属于我们js独有的 我们js API讲解
* 内置对象就是指js语言自带的一些对象 这些对象供开发者使用 并提供了一些常用的或者是最基本而必要的功能(属性和方法)
* 内置对象最大的优点就是帮助我们快速开发
* js提供了多个内置对象:Math Date Array String等
学会查阅MDN文档
**如何学习对象中的方法
1.查阅该方法的功能
2.查看里面参数的意义和类型
3.查看返回值的意义和类型
4.通过demo进行测试
数学对象max最大值方法
// Math 数学对象 不是一个构造函数 所以我们不需要new 来调用 而是直接使用里面的属性和方法即可
console.log(Math.PI); // 一个属性 圆周率
console.log(Math.max(99, 20, 1)); // 99 Math.max 意思就是最大数
console.log(Math.min(99, 20, 1)); // 1
console.log(Math.max(99, 'fengxiang', 1)); // NaN
console.log(Math.max()); // -Infinity 没有元素的话就是无穷小
封装自己的数学对象
//利用对象封装自己的数学对象 里面有PI 最大值 最小值
var myMath = {
PI:3.14159265,
max:function(){
var max = arguments[0];
for(var i = 1; i<arguments.length; i++){
if(arguments[i] > max){
max = arguments[i];
}
}
return max;
},
min:function(){
var min = arguments[0];
for(var i = 1; i<arguments.length; i++){
if(arguments[i] < min){
min = arguments[i];
}
}
return min;
}
}
console.log(myMath.PI);
console.log(myMath.max(55,33,66,99));
console.log(myMath.min(55,33,66,99));
Math绝对值和三个取整方法
//1.绝对值方法
console.log(Math.abs(1)); //1
console.log(Math.abs(-1)); //1
console.log(Math.abs('-1')); //1 隐式转换 会把字符串型 -1 转换为数字型
console.log(Math.abs('fx')); // NaN 不是一个数字
// 2.三个取整方法
//(1)Manth.floor() floor 地板 向下取整 往小了取值
console.log(Math.floor(1.1)); // 1
console.log(Math.floor(1.9)); // 1
//(2)Manth.ceil() ceil 天花板 向上取整 往大了取值
console.log(Math.ceil(1.1)); // 2
console.log(Math.ceil(1.9)); // 2
// (3)Math.round() 四舍五入 其他数字都是四舍五入 但是 .5 特殊 它往大了取
console.log(Math.round(1.1)); // 1
console.log(Math.round(1.5)); // 2
console.log(Math.round(1.9)); // 2
console.log(Math.round(-1.1)); // -1
console.log(Math.round(-1.5)); // -1 这个结果是-1
Math随机数取值方法
// 1.Math 对象随机数方法 radom() 返回一个随机的小数 0 =< x < 1 大于等于0 小于1的哦
// 2.这个代码里面不跟参数
// 3.代码验证
console.log(Math.random());
// 4.我们想要得到两个数之间的随机整数 并且 包括这两个整数
// Math.floor(Math.random() * (max-min +1)) +min; !! 公式
function getRandom(min,max){
return Math.floor(Math.random() * (max - min +1)) + min;
}
console.log(getRandom(1,10));
// 5.随机点名
var arr = ['影流之主', '海兽祭司', '披甲龙龟', '疾风剑豪', '流浪法师', '暗裔剑魔', '抱歉什么都没抽到'];
// console.log(arr[0]);
alert(arr[getRandom(0, 6)]);
猜数字游戏
// 猜数字游戏
// 1.随机生成一个1~10的整数 我们需要用到 Math.random() 方法
// 2.需要一直猜到正确为止 所以需要一致循环
// 3.while 循环更简单
// 4.核心算法:使用if else if 多分枝语句来判断大于 小于 等于
function getRandom(min,max){
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var random = getRrandom(1,50);
while(ture){
var num = prompt('请输入1~50的数字:');
if(num > random) {
alert('猜大了');
}else if(num < random) {
alert('猜小了');
}else {
alert('恭喜你猜对了');
}
}
猜数字游戏进阶
//加了限定条件
function getRandom(min,max){
return Math.floor(Math.random() * (max - min + 1)) +min;
}
var random = getRandom(1,50);
var i = 1;
while(i <= 5) {
var num = prompt('欢迎来到猜数字游戏 请猜出一个1~30之间的数字 你有5次机会o~');
if(num > random){
alert('大了');
}else if(num<random){
alert('小了');
}else {
alert('恭喜你答对了');
}
i++;
}
alert('很遗憾,次数用完了');
Date日期对象的使用
// Date() 日期对象 是一个构造函数 必须使用new 来调用创建我们的我们的日期对象
var arr = new Array(); //创建一个数组
var obj = new Object(); //创建一个对象实例
// 1.使用 Date 如果没有参数 返回当前系统的当前时间
var date = new Date();
console.log(date);
// 2.参数常用的写法 数字型 2019,10,01 或者是 字符型 '2019-10-01 8:8:8' (字符串比较常用)
var date1 = new Date(2022,09,19);
console.log(date1); //返回的是 10月 不是9月,数字型多加了一月
var date2 = new Date('2019-09-19');
console.log(date2);
格式化日期 年月日 星期
var date = new.Date();
console.log(date.getFullYear()); //返回当前日期的年 2019
console.log(date.getMonth()); // 月份,返回的月份小一个月 记得月份加一
console.log(date.getDate()); // 返回的是 几号
console.log(date.getDay()); // 周一返回的是1 周六返回的是6 周日返回的是0 因为是从周日开始 从0
// 我们写一个当前的时间
var year = date.getFullYear();
var month = date.getMonth() + 1;
var dates = date.getDate();
arr = ['周日','周一','周二','周三','周四','周五','周六'];
var day = date.getday();
console.log('今天是:' + year + '年' + month + '月' + dates + '日' + arr[day]);
格式化日期 时分秒
// 格式化日期 时分秒
var date = new Date();
console.log(date.getHours()); // 时
console.log(date.getMinutes()); // 分
console.log(date.getSeconds()); //秒
// 要求封装一个函数返回当前的时分秒 格式 08:08:08
function getTime() {
var time = new Date();
var h = time.getHours();
h = h < 10 ? '0' + h : h;
var m = time.getMinutes();
m = m < 10 ? '0' + m : m;
var s = time.getSeconds();
s = s < 10 ? '0' + s : s;
return h + ':' + m + ':' + s;
}
console.log(getTime());
Date总的毫秒数(时间戳)
// 获得Date 总的毫秒数 (时间戳) 不是当前时间的毫秒数 而是距离1970年1月1日过了多少毫秒数
// 1.通过 valueOf() getTime()
var date = new Date();
console.log(date.valueOf()); // 就是 我们现在时间 距离1970.1.1总的毫秒数
console.log(date.getTime());
// 2.简单的写法 (最常用的写法)
var date1 = +new Date(); //+new Date() 返回的就是总的毫秒数
console.log(date1);
// 3.h5新增的 获得总的毫秒数
console.log(Date.now());
倒计时效果
// 倒计时效果
// 1.核心算法: 输入的时间减去现在的时间就是现在的时间 即倒计时 但是不能拿着时分秒相减 比如 05 分 减去 25 分 结果会是负数的
// 2.用时间戳来做 用户输入时间总的毫秒数 减去现在时间的总的毫秒数 得到的就是剩余时间的毫秒数
// 3.把剩余时间总的毫秒数转换为天、时、分、秒 (时间戳转换为时分秒)
// 转换公式如下
// d = parseInt(总秒数 / 60 / 60 / 24); //计算天数
// h = parseInt(总秒数 / 60 / 60 % 24); //计算小时
// m = parseInt(总秒数 / 60 % 60); //计算分数
// s = parseInt(总秒数 % 60); //计算当前秒数
function countDown(time) {
var nowTime = +new Date(); // 返回的是当前时间总的毫秒数
var inputTime = +new Date(time); //返回的是用户输入时间总的毫秒数count
var times = (inputTime - nowTime) / 1000; //time是剩余时间总的毫秒
var d = parseInt(times / 60 / 60 / 24); //天
d = d < 10 ? '0' + d : d;
var h = parseInt(times / 60 / 60 % 24); //时
h = h < 10 ? '0' + h : h;
var m = parseInt(times / 60 % 60); //分
m = m < 10 ? '0' + m : m;
var s = parseInt(times % 60); //秒
s = s < 10 ? '0' + s : s;
return d + '天' + h + '时' + m + '分' + s + '秒';
}
console.log(countDown('2022-8-15 15:00:00'));
var date = new Date();
console.log(date);
数组创建的两种方式
// 创建数组的两种方式
// 1.利用数组字面量
var arr = [1,2,3];
console.log(arr[0]);
// 2.利用 new Array()
// var arr1 = new Array(); //创建了一个空数组
var arr1 = new Array(2); // 这个2 表达 数组的长度为2 里面有2个空数组元素
var arr1 = new Array(2,3); // 等价于[2,3] 这样写表示 里面有2个数组元素 是2 和 3
检测是否为数组的两种方式
//翻转数组
function reverse(arr){
if(arr instanceof Array){
var newArray = [];
for(var i = arr.length -1; i >= 0 ; i--){
newArray[newArray.length] = arr[i];
}
return newArray;
}else {
return '这个不是数组'
}
}
console.log(reverse([1, 2, 3]));
console.log(reverse(1, 2, 3))
//检测是否为数组
// (1)instanceof 运算符 他可以用来检测是否为数组
var arr = [];
var obj = {};
console.log(arr instanceof Array);
console.log(obj instanceof Array);
// (2)Array.isArray(参数); h5 新增的方法 ie9版本以上才支持
console.log(Array.isArray(arr));
console.log(Array.isArray(obj));
添加数组元素
// 添加删除数组元素方法
// 1. push() 在我们数组的末尾 添加一个或者多个数组元素 push 推
var arr = [1, 2, 3];
// arr.push(4, 'fxnb');
console.log(arr.push(4, 'fxnb'));
console.log(arr);
// (1)push 是可以给数组 后面 追加新的元素
// (2)push() 参数直接写 数组元素就可以了
// (3)push完毕之后 返回的结果是 新数组的长度
// (4)原数组也会发生变化
// 2.unshift 在我们数组的开头 添加一个或者多个元素
console.log(arr.unshift('red', 'purple'));
console.log(arr);
// (1)unshift 是可以给数组 前面 追加新的元素
// (2)unshift() 参数直接写 数组元素就可以了
// (3)unshift完毕之后 返回的结果是 新数组的长度
// (4)原数组也会发生变化
// 删除数组的方法
// 3.pop() 他可以删除数组的最后 一 个元素
// arr.pop();
console.log(arr.pop());
console.log(arr);
// (1)pop 是可以删除数组的最后一个元素 记住一次只能删除一个元素
// (2)pop() 没有参数
// (3)pop完毕之后 返回的结果是 删除的那个参数
// (4)原数组也会发生变化
// 4.shift() 他可以删除数组的 第一 个元素
// arr.shift();
console.log(arr.shift());
console.log(arr);
// (1)shift 是可以删除数组的第一个元素 记住一次只能删除一个元素
// (2)shift() 没有参数
// (3)shift完毕之后 返回的结果是 删除的那个参数
// (4)原数组也会发生变化
筛选数组
// 有一个包含工资的数组[1500,2000,1200,6500,100], 要求把超过2000的删除 剩余的放到新数组里面
var arr = [1500,2000,1200,6500,100];
var newArray = [];
for(var i = 0; i < arr.length; i++){
if(arr[i] < 2000){
//newArray[newArray.length] = arr[i];
newArray.push(arr[i]);
}
}
console.log(newArray);
数组排序
// 数组排序
// 1. 翻转数组
// (1)原版写法
var arr = ['feng', 'xiang', 'niu', 'bi'];
var newArray = [];
for (var i = arr.length - 1; i >= 0; i--) {
// newArray[newArray.length] = arr[i];
newArray.push(arr[i]);
}
console.log(newArray);
// (2)利用内置对象写法 ~摊手
// var arr = ['feng', 'xiang', 'niu', 'bi'];
// arr.reverse();
// console.log(arr);
// 2.冒泡排序
// (1)原版双重for循环写法
// var arr1 = [52, 32, 6, 8, 64];
// for (var i = 0; i < arr1.length - 1; i++) {
// for (var j = 0; j < arr1.length - 1 - i; j++) {
// if (arr1[j] > arr1[j + 1]) {
// temp = arr[j];
// arr1[j] = arr1[j + 1];
// arr1[j + 1] = temp;
// }
// }
// }
// console.log(arr1);
// (2)利用内置对象写法
var arr1 = [52, 32, 6, 8, 64];
arr1.sort(function (a, b) {
// return a - b; 升序的排列
return b - a; //降序的排列
})
console.log(arr1);
获取数组元素索引号
// 返回数组元素索引号方法 indexOf(数组元素) 作用就是返回该数组元素的索引号 从前面开始查找
// 它只返回第一个满足条件的索引号
// 如果在该数组里面找不到元素 则返回 -1
// var arr = ['fengx', 'ldh', 'zxy', 'hg'];
var arr = ['fengx', 'ldh', 'zxy'];
console.log(arr.indexOf('hg'));
// 返回数组元素索引号方法 lastIndexOf(数组元素) 作用就是返回该数组元素的索引号 从 后面 开始查找
var arr = ['fengx', 'ldh', 'zxy', 'hg', 'hg'];
console.log(arr.lastIndexOf('hg')); // 4
案例-数组去重
// 数组去重 ['c','s','d','s'] 要求去除数组中的重复元素
// 1.目标: 把旧数组里面不重复的元素选取出来放到新数组里面 重复的元素只保留一个 放到新数组中去重
// 2.核心算法: 我们遍历数组 然后拿着旧数组元素去查询新数组 如果钙元素在新数组里面没有出现过 我们就添加 否则不添加
// 3.我们怎么知道该元素有没有存在? 利用 新数组.indexOf(数组元素) 如果返回值为 -1 就说明 新数祖里面没有该元素
// 封装一个 去重的函数 unique 独一无二的
function unique(arr) {
var newArray = [];
for (var i = 0; i < arr.length; i++) {
if (newArray.indexOf(arr[i]) === -1) {
newArray.push(arr[i]);
}
}
return newArray;
}
var demo = unique(['fx', 'fx', 'nb']);
console.log(demo);
数组转为字符串
// 数组转换为字符串
// 1. toString() 将我们的数组转换为字符串
var arr = [1, 2, 3];
console.log(arr.toString()); // 1,2,3
// 2.join(分隔符) 可以设置元素中间分割符
var arr1 = ['geek', 'fx'];
console.log(arr1.join()); // geek,fx 默认逗号
console.log(arr1.join('-')); // geek-fx
连接数组
// 连接两个或者多个数组 不影响原素组 返回值为一个新数组
// 语法:var 新数组 = 一个数组.concat(一个数组 或值);
var arr1 = ['风中传来苦咸'];
// var arr2 = ['那是悔恨的滋味吗?'];
var arr2 = '乌拉';
var arr3 = arr1.concat(arr2)
console.log(arr3);
splice数组删除增加元素
// 语法: 数组删除.splice(第几个开始, 删除个数); 返回值是删除项目的新数组 注意 这个会影响原数组
// 段删除 如果有两个值 那么意思就是从第几个开始 删除几个
var arr1 = [1, 2, 3, 4, 5, 6];
arr1.splice(3, 2);
console.log(arr1);
// 域删除 如果只有一个值 那么意思就是从第 n 个开始 包括n n以后的全部删除
var arr2 = [1, 2, 3, 4, 5, 6];
arr2.splice(2);
console.log(arr2);
// 添加元素 如果删除值参数 后面还加有 其他值或字符串 那么会在删除值指定位置添加该值或字符串
var arr3 = [1, 2, 3, 4, 5, 6];
arr3.splice(3, 0, '木头人');
console.log(arr3);
// 替换元素 如在指定位置删除一个或多个值 并后加一个或多个值 即可替换
var arr4 = [1, 2, 3, 4, 5, 6];
arr4.splice(3, 2, 'four', 'five');
console.log(arr4);
基本包装类型
// 基本包装类型
var str = 'andy';
console.log(str.length);
// 对象 才有 属性和方法 复杂数据类型才有 属性和方法
// 简单数据类型为什么有length 属性呢?
// 基本包装类型:就是把简单数据类型 包装成为了 复杂数据类型
// 三步
// (1)把简单数据类型包装成为复杂数据类型
var temp = new String('andy');
// (2)把临时变量的值 给 str
str = temp;
// (3)销毁这个临时变量
temp = null;
字符串不可变
// 字符串的不可变性
var str = 'andy';
console.log(str);
str = 'sally';
console.log(str);
// 看到了吗? 虽然看上去可以改变内容 但其实就是地址变了 内存中新开辟了一个内存空间 所以不要大量的拼接或赋值
// 因为我们字符串的不可变 所以不要大量的拼接字符串
// 卡顿
var str = '';
for (var i = 0; i < 100; i++) {
str += i;
}
console.log(str);
根据字符返回位置
// 字符串对象 根据字符返回位置 str.indexOf('要查找的字符',[起始的位置])
var str = '空有认知不付诸实际行动,而次打空';
console.log(str.indexOf('空', 3)); //从索引号是 3 的位置开始往后查找
求某个字符出现的位置及次数
// 查找字符串"abcoefoxydanodao" 中所有o出现的位置以及次数
// 核心算法:先查找第一个o 出现的位置
// 然后 只要indexOf 返回的结果不是 -1 就继续往后查找
// 因为indexOf 只能查找第一个 所以后面的查找 一定是当前索引号+1 从而继续查找
// var str = "abcoefoxydanodao";
// var num = 0;
// var index = str.indexOf('o');
// while (index !== -1) {
// console.log(index);
// num++;
// index = str.indexOf('o', index + 1);
// }
// console.log('o出现的次数是:' + num);
//求某个数组元素 出现的位置及次数
var arr = ['red', 'blue', 'red', 'green', 'pink', 'red'];
var num = 0;
var index = arr.indexOf('red');
while (index !== -1) {
console.log(index);
num++;
index = arr.indexOf('red', index + 1);
}
console.log('red出现的次数为' + num);
根据位置返回字符
// 根据位置返回字符
// 1.charAt(index) 根据位置返回字符
var str = 'fxnb';
console.log(str.charAt(3));
// 遍历所有的字符
for (var i = 0; i <= str.length; i++) {
console.log(str.charAt(i));
}
// 2.charCodeAt(index) 返回响应索引号的字符ASCII值 目的:判断用户按下了那个键
console.log(str.charCodeAt(0)); // 97
// 3.str[index] H5 新增的
console.log(str[0]);
统计出现最多的字符
// 有一个对象 来判断是否有该属性 对象['属性名']
var o = {
age: 18
}
if (o['age']) {
console.log('里面有该属性');
} else {
console.log('没有该属性');
}
// 判断一个字符串 'abhccdevvc' 中出现次数最多的字符 并统计次数
// o.a = 1
// o.b = 1
// o.c = 3
// 核心算法: 利用charAt() 遍历这个字符串
// 把每个字符都存储给对象 如果对象没有该属性 就为 1 如果存在了就 + 1
// 遍历对象 得到最大值和该字符
var str = 'abhccdevvc';
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);
拼接以及截取字符串
// 1.concat('拼接字符串1','字符串2'....)
var str = 'fengxiang';
console.log(str.concat('niubi'));
// 2.substr ('截取的起始位置','截取几个字符');
var str1 = '反抗永世不予!';
console.log(str1.substr(2, 2)); // 第一个是2 是索引号的 2 从第几个开始 第二个2 是取几个字符
替换以及转化为数组
// 1.替换字符 replace('被替换的字符','替换为的字符') 它只会替换第一个字符
var str = 'andyandy';
console.log(str.replace('a', 'b'));
// 有一个字符串 'abcoefoxyozzopp' 要求把里面所有的 o 替换为 *
var str1 = 'abcoefoxyozzopp';
while (str1.indexOf('o') !== -1) {
str1 = str1.replace('o', '*');
}
console.log(str1);
// 2.字符转换为数组 split('分隔符') 前面我们学过join 把数组转换为字符串
var str2 = 'red,pink,blue';
console.log(str2.split(','));
var str3 = 'red&pink&blue';
console.log(str3.split('&'));
课后作业
// 给定一个字符串 如 'abaasdffggghhjjkkgfddsss344343'
var str = 'abaasdffggghhjjkkgfddssss344343';
// 1.字符串长度
console.log(str.length);
// 2.取出指定位置的字符 如:0,3,5,9等
console.log(str[0]);
console.log(str.charAt(3));
console.log(str[5]);
console.log(str[9]);
// 3.查找指定字符是否在以上字符串中存在 如:i,c,b 等
function search(zhi) {
if (str.indexOf(zhi) === -1) {
console.log('不存在');
} else {
console.log('存在');
}
}
search('i');
search('c');
search('b');
// 4.替换指定字符 如:g替换为22 ss替换为b等
// while (str.indexOf('g') !== -1) {
// str = str.replace('g', '22');
// }
// console.log(str);
// 5.截取指定开始位置到结束位置的字符串 如:取得1~5的字符串
// console.log(str.substr(1, 5));
// 6.找到以上字符串中出现次数最多的字符和出现的次数
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);
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);
12.简单类型和复杂类型
简单数据类型
***学完应掌握的知识点
- 能够说出简单数据类型的内存分配
- 能够说出复杂数据类型的内存分配
- 能够说出简单类型如何传参
- 能够说出复杂类型如何传参
***本章学习的知识点
* 简单类型与复杂类型
* 堆和栈
* 简单类型的内存分配
* 复杂类型的内存分配
* 简单类型传参
* 复杂类型传参
数据类型内存分配
// 简单数据类型null 返回的是一个空的对象 object
var timer = null;
console.log(typeof timer);
// 如果有个变量 我们以后打算存储为对象 暂时没想好放啥 这个时候就给null
// 1.简单数据类型 是存放在栈里面 里面直接开辟一个空间存放的是 值
// 2.复杂数据类型 首先在栈里面存放地址 用十六进制表示 然后这个地址指向堆里面的数据
简单数据类型传参
// 函数的形参也可以看做是一个变量 当我们把一个值类型变量作为参数传给函数的形参时 其实是把变量在栈空间里的值复制了一份给形参 那么在方法内部对相残做任何修改 都不会影响到外部变量
function fn(a) {
a++;
console.log(a);
}
var x = 10;
fn(x);
console.log(x);
复杂数据类型传参
// 函数的形参也可以看做是一个变量 当我们把引用类型变量传给形参时 其实是把变量在栈空间里保存的堆地址复制给了形参 形参和实参其实保存的是同一个堆地址 所以操作的是同一个对象
function Person(name) {
this.name = name;
}
function f1(x) { // x = p
console.log(x.name); //2.这个输出什么? 刘德华
x.name = '张学友';
console.log(x.name); // 3.这个输出什么? 张学友
}
var p = new Person('刘德华');
console.log(p.name); // 1.这个输出什么? 刘德华
f1(p);
console.log(p.name); // 4.这个输出什么? 张学友!!