JavaScript基础

JavaScript基础

1. JavaScript简介

  • JavaScript,就是我们通常所说的JS,是一种嵌入到HTML页面中的脚本语言,由浏览器一边解释一边执行。
  • “HTML是网页的结构,CSS是网页的外观,而JavaScript是页面的行为。”

2. JavaScript的特点

  • 动态改变页面内容

HTML页面是静态的,一旦编写,内容是无法改变的。JavaScript可以弥补这个不足,可以将内容动态地显示在网页中。

  • 动态改变网页的外观

JavaScript通过修改网页元素的CSS样式,达到动态地改变网页的外观。

  • 验证表单数据

我们常见的在各大网站中的注册中的验证功能,就是JavaScript实现的。

  • 响应事件

JavaScript是基于事件的语言。例如点击一个按钮弹出一个对话框,就是鼠标点击触发的事件。

对于JavaScript的理解,就一句话:如果没有使用JavaScript,网页就是静态的,唯一的功能就是给用户浏览。加入了JavaScript,网页变得绚丽多彩起来。

3. JavaScript入门基础

3.1 Javascript基本使用

3.1.1 JavaScript在HTML的引用方式

(1)页头引入(head标签内);

<script>
     alert('沙漠骆驼')
</script>

(2)页中引入(body标签内);

(3)元素事件中引入(标签属性中引入);

<input type="button" value="唐伯虎" οnclick="alert('秋香姐')">

(4)引入外部JS文件 (script之间不可以再写东西了);

<script src="my.js"></script>
3.1.2 注释
  1. 单行注释 ctrl + /
  2. 多行注释 shift + alt + a

多行注释 vscode中修改多行注释的快捷键: ctrl + shift + /

3.1.3 输入输出语句
  • prompt 输入框

    
    prompt('请输入您的年龄');
    
  • alert 弹出警示框 输出的 展示给用户的

    alert('计算的结果是')
    
  • console 控制台输出 给程序员测试用的

    console.log('我是程序员能看到的')
    

3.2 Javascript数据结构

JavaScript的数据结构包括:标识符关键字常量变量等。

1. 标识符
  • 标识符,说白了,就是一个名字。在JavaScript中,变量和函数等都需要定义一个名字,这个名字就可以称为“标识符”。

  • 命名规范:

(1)第一个字符必须是字母、下划线(_)或美元符号这3种其中之一,其后的字符可以是字母、数字或下划线、美元符号;

(2)变量名不能包含空格、加号、减号等符号;

(3)标识符不能和JavaScript中用于其他目的的关键字同名;

2. 关键字

JavaScript关键字是指在JavaScript语言中有特定含义,成为JavaScript语法中一部分的那些字。

3. 常量

常量主要用于为程序提供固定和精确的值,包括数值和字符串,如数字、逻辑值真(true)、逻辑值假(false)等都是常量。

4. 变量

变量,顾名思义,就是指在程序运行过程中,其值是可以改变的。

  • 声明和赋值

    • 声明了一个age变量
      var age;

    • 声明了一个age变量
      age = 18;

    • 输出结果
      console.log(age);

    • 变量的初始化

      let myname = 'sheep';
      console.log(myname);
      
  • 声明变量的特殊情况

    • 只声明不赋值 结果是 undefined 未定义的

      let sex;
      console.log(sex);
      
    • 不声明不赋值 直接使用某个变量会报错

      console.log(tel);

    • 不声明直接赋值使用

      qq = 110;
      console.log(qq);
      
5. 声明变量 let
(1) let介绍

ES6引入了let,用let声明变量,解决了JavaScript没有块级作用域的问题(注:ES3的catch分句会产生块作用域)。

(2) 作用域

作用域简单的来说,就是一套寻找变量的规则,用于确定在何处以及如何查找变量

  • 当一个块或函数嵌套在另一个函数时,就发生了作用域嵌套=。如图所示,就有三个嵌套作用域:

    • 全局作用域,其中有一个标识符:foo(整个绿色区域)

    • foo创建的函数作用域,其中有三个标识符:a,bar和b(整个黄色区域)

    • bar创建的函数作用域,其中有一个标识符:c(蓝色区域)

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wpUYoWWr-1668609019253)(https://gitee.com/colohh/image_bed/raw/master/img/%E5%B5%8C%E5%A5%97%E4%BD%9C%E7%94%A8%E5%9F%9F.png)]

  • 如何在嵌套作用域中寻找变量呢:引擎从当前作用域开始查找变量,如果找不到,就会向上一级继续查找。当抵达最外层全局作用域时,无论找到还是没有找到,查找过程中都会停止。

(3) let 特点
  • 作用域只在他所在的代码块

    for(let i = 0 ; i<5 ; i++) {
        let i = 'cht';
        console.log(i); // cht *5
    }
    // console.log(i); //Error:i is not defined
    
  • let 不允许在相同的作用域内,重复声明同一个变量

  • let 声明不使用会报错

  • 不存在变量提升

    ES6明确规定,如果区块中存在let/const命令,这个区块用这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用的变量,就会报错

  • 外层作用域不能访问内层变量;内层变量可访问外层变量。

  • 不影响作用域链

    {
    	let school = 'china';
    	function fn(){
    	console.log(school);
    	}
    	fn();// china
    }
    

3.3 JavaScript数据类型

js是动态语言,变量的数据类型是可以变化的。只有程序在运行过程中,根据等号右边的值来确定

3.3.1 基本数据类型:
(1)数字型(Number型):如整型84,浮点型3.14;
let num = 10; // num 数字型 
let PI = 3.14 // PI 数字型
    1. 八进制 0 ~ 7 我们程序里面数字前面加0 表示八进制

      let num1 = 010;
      console.log(num1); //  010  八进制 转换为 10进制 就是  8 
      
    1. 十六进制 0 ~ 9 a ~ f #ffffff 数字的前面加 0x 表示十六进制

      var num3 = 0x9;
      console.log(num3);
      
    1. 数字型的最大值
      console.log(Number.MAX_VALUE);
    1. 数字型的最小值
      console.log(Number.MIN_VALUE);
    1. 无穷大
      console.log(Number.MAX_VALUE * 2); // Infinity 无穷大
    1. 无穷小
      console.log(-Number.MAX_VALUE * 2); // -Infinity 无穷大
    1. 非数字
      console.log('pink老师' - 100); // NaN

isNaN() 这个方法用来判断非数字 并且返回一个值 如果是数字返回的是 false 如果不是数字返回的是true

    console.log(isNaN(12)); // false
    console.log(isNaN('pink老师')); // true
(2)字符串型(String型):如"pink";

字符串的拼接:

    1. 检测获取字符串的长度 变量名.length
        let str = 'my name is andy';
        console.log(str.length);//15
    1. 字符串的拼接 +
        console.log('hello'+' '+'world');
        console.log('618'+'大促');

注意:字符串+其他类型 最后结果也一定是字符串型

console.log('12'+12);

例: 输出我今年age岁(”引引加加“)

console.log('我今年' + age + '岁')

变量不能写到字符串里面,是通过和字符串相连的方式实现的

(3)布尔型(Boolean型):true或fasle;
let flag = true;
let flag1 = false;

ture / false 参与加减法运算当 1 / 0来看

3.3.2 特殊数据类型:
(1)空值(null型);
	let space = null;
    console.log(space + 'pink'); // nullpink
    console.log(space + 1); // 1		
(2)未定义值(undefined型);
    let str;
    console.log(str);
    let variable = undefined;
    console.log(variable + 'pink'); // undefinedpink
    
    console.log(variable + 1); // NaN  undefined 和数字相加 最后的结果是 NaN
(3)转义字符;

\n 换行 ; \b 空格 ;杠’ 和杠" ; \b 空格;

3.3.3 获取变量数据类型 typeof 变量名
let num = 10;
console.log(typeof num);//number
3.3.4 数据类型转换
  • 转换成字符型
    1. 利用 变量.toString()

      let num = 10;
      let str =num.toString();
      console.log(str);
      console.log(typeof str);
      
    2. 利用 String(变量)

      console.log(String(num));

    3. !!利用 + 拼接字符串的方法实现转换效果 隐式转换

      let str1 =' '+num;
      console.log(str1);
      console.log(typeof str1);
      
  • 转换成数字型
    1. 将string类型转换成整型 parseInt(变量)

      console.log(parseInt('24.75'));//3 取整
      
      console.log(parseInt('120px'));//120 会自动去掉非整型部分
      
      console.log(parseInt('rem120px'));//NaN 读到第一个字符非数字型就不继续读了
      
    2. 将string类型转换成浮点型 parseFloat(变量)

      语法同parselnt

    3. 利用 Number(变量)

      let str2 = '123'
      
      console.log(Number(str2));
      
      console.log(Number('152'));
      
    4. 利用了算术运算 - * / 隐式转换

      console.log('12' - 0);//12
      
      console.log('123' - '120');//3
      
  • 转换为布尔型 Boolean(函数)

    “ " ”、“0”、“NaN”、“underfined”、“null”转换后值为false,其余都为true

    console.log(Boolean(null));//false
    console.log(Boolean('我很好'));//ture
    

3.4 运算符

也叫操作符

JavaScript的运算符按运算符类型可以分为以下5种:

(1)算术运算符

​ “+”-“*”/"

  • 浮点数在算数运算中会有误差,不能判断浮点数是否相等
  • 表达式和返回值

    • 表达式是由数字、运算符、变量等组成的式子 1+1
(2)递增和递减运算符
  • a. 前置递增(++num)

  • b.后置递增(num++)先返回原值,再自加

  • 例题:

let a = 10;
++a;
let b = ++a + 2;
console.log(b); // 14

let c = 10;
c++;
letlet d = c++ + 2; 
console.log(d); // 13

let e = 10;
let f = e++ + ++e;
console.log(f); // 22
(3)比较运算符;
  • 是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值(ture / false)作为比较运算的结果。

(4)逻辑运算符;

逻辑与 && 、逻辑或 || 、逻辑非 !

用来进行布尔值运算的运算符,其返回值也是布尔值。后面开发中经常用于多个条件的判断

  • 短路运算(逻辑中断)

    原理:当有多个表达式(值)时,左边的表达式可以确定结果时,就不再继续运算右边表达式的值;

    1. 逻辑从左往右数有错误的就输出错误的,全对就输出最后一个
      • 语法:表达式1 && 表达式2
      • 若表达式1为真,则返回表达式2
      • 若表达式1为假,则返回表达式1

    ​ 例:console.log(123 && 456);// 456

    console.log(0 && 456);// 0

    1. 逻辑从左往右数有正确的就输出正确的,全错就输出最后一个

      • 语法:表达式1 || 表达式2
      • 若表达式1为真,则返回表达式1
      • 若表达式1为假,则返回表达式2

      例:console.log(123 || 456);// 123

      console.log(0 || 456);// 456

      console.log(123 || 456 ||789);// 789

      // 经例:
      	let num = 0;
      	console.log(123 || num++);
      	//程序读到123为真后逻辑中断返回123,num++不执行,此时num为0
      	console.log(num);// 0
      
(5)赋值运算符

用来把数据赋值给变量的运算符

  • 自加 (自减、乘、除同理)
num = num + 1; // num++
num = num + 2;// num +=2

(6)运算符优先级

​ 熟练掌握优先级并计算以下案例:

3.5 流程控制分支结构

流程控制就是来控制代码按照什么结构顺序来执行

顺序结构/分支结构/循环结构

3.5.1 顺序流程控制
  • 按照代码先后顺序,依次执行
3.5.2 分支流程控制if语句
  • 分支结构

    • 从上到下的代码中,根据不同条件,执行不同路径代码(多选一),从而得到不同的结果。

    • 提供了两种分支结构语句

(1)if 语句
  • 双分支语句(if else语句)

    • 语法结构(2选1)

      if (条件表达式){
       //执行语句1;
      } else {
      //执行语句2;
      }
      
    • 执行思路:若 if 里的表达式结果为 ture ,则执行语句1,反之则执行语句2;( else 可以不写)

  • 多分支语句( if else if 语句)

    • 语法结构(多选1)

      if(条件表达式1{
      	//语句1;
      } else if(条件表达式2{
      	//语句2;
      } else if(条件表达式3{
      	//语句3;
      }else {
      	//最后的语句;
      }
      
    • 执行思路:若条件表达式 1 的结果为 ture ,则执行语句1,否则继续往下判断直到找到结果为ture的表达式,若全不满足,则输出最后的语句。

  • 补充:三元表达式

    • 由三元运算符组成的式子我们称为三元表达式

    • 语法结构

      • 条件表达式 ? 表达式1 :表达式2
    • 执行思路

      • 如果条件表达式结果为真,则返回表达式1的值;

      • 如果条件表达式结果为假,则返回表达式2的值。

        let num = 10;
        let result = num > 5 ? '是的' : '不是的';// 是的
        //等价于
        if(num > 5){
        	result ='是的';
        }else{
        	result ='不是的'}
        
(2)switch 语句

switch 语句也是多分支语句,它用于基于不同的条件来执行不同的代码。当要针对变量设置一系列的特定值的选项时,就可以使用switch。

  • 语法结构

    switch(表达式){
    	case value1://1
    		执行语句1;
    		break;
    	case value2://2
    		执行语句2;
    		break;
    	...
    	...
    	...
    	default:
    		执行最后的语句;
    }
    
  • 执行思路:利用表达式的值 和 case 后面的选项值 相匹配,如果匹配上,就执行该case里面的语句;如果都没匹配上,那么执行 default里面的语句

    • !!表达式的值和case的值相匹配的时候必须是全等 必须是值和数据类型都一致才可以

    • 如果当前的case里面没有break 则不会退出switch 而是继续执行下一个case

      (3)switch 和 if else if 的区别
  • 一般情况下,可以相互转换

  • switch…case 通常处理case为比较确定值的情况,而 if…else…语句更加灵活,常用于判断范围(大于或等于某个范围)

  • switch进行条件判断后直接执行到程序的条件语句,效率更高。而 if…else 语句有几种条件,就得判断几次

  • 分枝少时用 if…else…if ;分枝多用 switch…case

3.5.3 循环流程控制
(1)for循环
  • for重复执行某些代码,通常和计数有关

  • 语法结构

    for (初始化变量;条件表达式;操作表达式){
    	//循环体
    }
    
  • 初始化变量:就是用 var 声明的一个普通的变量,通常作为计数器使用

  • 条件表达式:用来决定每一次循环是否继续执行,就是终止的条件

  • 操作表达式:每次循环最后执行的代码 通常用于我们计数器变量进行更新(递增或者递减)

  • 代码体验 重复打印100句 你好

    for(var i = 1;i <= 100;i++){
    	alert('你好')
    }
    
(2)双重for循环
  • 语法结构

    for (外层的初始化变量;外层的条件表达式;外层的操作表达式){
    	for(里层的初始化变量;里层的条件表达式;里层的操作表达式){
    		//执行语句
    	}
    }
    
  • 我们可以把里面的循环看作是外层循环的语句

  • 外层每循环一次,里面的循环执行全部

  • 代码验证

    for (let i =1;i <= 3;i++){
        console.log('这是外层循环第'+ i +'次');
        for(let j = 1;j <= 3;j++){
    		console.log('这是内层循环第'+ i +'次');
    	}                     
    }
    
(3)while循环
  • 语法结构

    while(条件表达式){
    	//循环体
    }
    
  • 执行思路:当条件表达式为ture,则执行循环体;否则,退出循环

  • 代码验证

    let num = 1;
    while (num <= 100){
    	console.log('hello');
        num++;//防止死循环
    }
    
  • 里面应该也有计数器,初始化变量

  • 里面应该也有操作表达式,完成计数器的更新,防止死循环

(4)do while循环
  • 语法结构

    do {
    	//循环体
    }while(条件表达式)
    
  • 执行思路:跟while不同的地方在于 do while 先执行一次循环体,再判断条件,如果条件表达式结果为真,则继续执行循环体,否则退出循环。

  • do while 循环体至少执行一次

  • 代码验证

    let i = 1;
    do {
    	console.log('how are you');
    	i++;
    }while(i <= 100)
    
(5)循环小结
  • 如果是用来计数的、和数字相关的,三者使用基本相同,但是我们更喜欢用for
  • while 和 do…while 可以做更复杂的判断条件,比for循环灵活一些
  • while 和 do…while 执行顺序不一样,while 先判断后执行,do…while 先执行一次,再判断执行
(6)continue 关键字

用于立即跳出本次循环继续下一次循环

  • 代码实现

    for (let i = 1;i <= 5;i++){
        if (i == 3){
          continue;
         }
         console.log('我正在吃第'+ i +'个苹果') ;
    }
    
(7)break 关键字

用于立即跳出整个循环(循环结束)

  • 代码实现

    for (let i = 1;i <= 5;i++){
        if (i == 3){
          break;
         }
         console.log('我正在吃第'+ i +'个苹果') ;
    }
    

3.6 数组

数是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。数组是一种将一组数据存储在单个变量名下的优雅方式。

3.6.1 数组的创建方式
(1)利用 new 创建数组
let arr = new Array();//创建了一个空的数组
let arr1 = new Array(2);//这个 2 表示数组的长度为 2 ,里面有两个空的数组元素
let arr2 = new Array(2,3);//这样写表示 里面有两个数组元素 是 2 和 3
(2)利用数组字面量创建数组
let arr = [];//创建了一个空的数组
let arr1 = [1,2,'pink',ture];//我们数组里面的数据一定用逗号分隔
3.6.2 获取数组中的元素

数组的索引

索引(下标):用来访问数组元素的序号(数组下标从0开始

  • 获取数组元素

    • 格式: 数组名[索引号]

      //定义数组
      let arrStus = [1,2,3];
      //获取数组中的第二个元素
      alert(arrStus[2]);
      
3.6.3 遍历数组

遍历就是把数组中的每个元素从头到尾都访问一次(类似于我们每天早上学生的点名)

let arr = ['red','green','blue'];
for (let i = 0;i < arr.length;i++){
    console.log(arr[i]);
}
//1.因为我们的数组索引号从 0 开始,所以 i 必须从 0 开始  i < 3
//2.输出的时候 arr[i] i 计数器当索引号来用
//3.arr.length 动态监测数组元素的个数
3.6.4 数组中新增的元素

通过修改length长度以及索引号增加数组元素

(1)通过修改 length 长度新增数组元素
  • 可通过修改 length 长度来实现数组扩容的目的

  • length 属性是可读写的

    let arr = [1,2,3,4,5];
    arr.length = 7;
    console.log(arr[6]);//undefined
    console.log(arr[7]);//undefined
    
(2)修改索引号 追加数组元素
let arr1 = [1,2,3];
arr1[3] = 'pink';
console.log(arr1);
  • 不要直接给 数组名 赋值,否则里面的数组元素都会被覆盖
3.6.5 冒泡排序

冒泡排序:是一种算法,把一系列的数据按照一定的顺序进行排列显示(从小到大或从大到小)

原理:重复的走访要排列的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复的进行直到没有再需要交换的元素,也就是该数列已经排序完成。

let arr = [4,1,2,3,5];
for (let i = 0;i <= arr.length - 1;i++){
    for (let j = 0;j <= arr.length - i - 1;j++){
        if (arr[j] > arr[j + 1]){
            let temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j+1] = temp;
        }
    }
}
console.log(arr);

3.7 函数

3.7.1 函数的概念
  • 函数:就是封装了一段可被重复调用执行的代码块,通过此代码块可以实现大量代码的重复使用
3.7.2 函数的使用
  • 声明函数 (关键字 function)

        function 函数名(){
            //函数体
        }
    
    1. 函数是做某件事情,函数名一般是动词
    2. 函数不调用自己不执行
  • 调用函数

    	函数名();//调用函数的时候千万不要忘记加小括号
    
3.7.3 函数的封装
  • 把一个或多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口
3.7.4 函数的参数
(1)参数的作用:

函数内部有些值不固定,我们可以通过参数在调用函数时传递不同的值进去

  • 函数的参数可以有,也可以没有,个数不限

    function 函数名(形参1,形参2...{// 形参 形式上的参数
    	//函数体
    }
    函数名(实参1,实参2...// 实参 实际上的参数
    
(2)函数形参和实参个数不匹配问题
function getSum(num1,num2) {
	console.log(num1 + num2);
}
  • 如果实参和形参的个数一致,则正常输出结果

    getSum(1,2);// 3
    
  • 如果实参的个数多于形参的个数

    getSum(1,2,3);// 3
    
  • 如果实参的个数小于形参的个数

    形参可以看作是一个不用声明的变量,num2 是一个变量但是没有接受值 它的值就是undefined

    getSum(1);// NaN
    
3.7.5 函数的返回值

把输出语句写在函数内部是不合理的(比如console.log),这时候我们就需要返回值

(1)return 语句
  1. 我们函数只是实现某种功能,最终的结果需要返回给函数的调用者 函数名(),这是通过 return 来实现的

  2. 只要函数遇到 return,就把后面的结果返回给函数的调用者;相当于:函数名() = return 后面的结果

  3. 终止函数:return语句之后的代码不被执行

  4. return 只会返回一个结果(最后一个),若要返回多个结果,可用数组来实现

    return [num1+num2,num1-num2,num1*num2,num1/num2]

  • 格式

    function 函数名() {
    	return 需要返回的结果;
    }
    函数名();
    console.log(函数名());
    
  • 代码实操

    //求任意两个数的和
    function getSum(num1,num2){
        return num1 + num2;
    }
    console.log(getSum(1,2));
    
(2)函数的返回值注意事项
  • 函数如果有 return 则返回的是 return 后面的值;如果没有 return 则返回 undefined

    function fun1(){
    	return 666;
    }
    console.log(fun1());// 返回 666
    ------------
    function fun2(){
    
    }
    console.log(fun2());// 返回 undefined
    
(3)break ,cntinue ,return的区别
  • break:结束当前循环体
  • continue:跳出本次循环,继续执行下次循环
  • return:不仅可以退出循环,还能返回 return 语句中的值,同时还可以结束当前循环体内的代码
3.7.6 arguments 的使用
  • 在JS中,arguments 实际上是当前函数的一个内置对象,arguments 对象中存储了传递的所有实参

    • 当我们不确定有多少个参数传递的时候,可以用 arguments 来获取。
  • arguments 展示形式是一个伪数组,因此可以进行遍历。伪数组的特点:

    • 具有 length 属性
    • 按索引方式储存数据
    • 不具有数组的push,pop等方法
  • 代码实操

    //翻转数组
    function reverse(){
    	let newArr = [];
    	for (let i = arguments.length - 1;i >= 0; i--){
    		newArr[newArr.length] = arguments[i]
    	}
    	return newArr
    }
    let res = reverse('red','yellow','green','blue');
    console.log(res);
    
3.7.8 函数是可以相互调用的
function fn1(){
	console.log(11);
	fn(2);//在 fn1 函数里面调用了 fn2 函数
}
fn1();

function fn2(){
	console.log(22);
}
3.7.9 函数的两种声明方式
(1)利用函数关键字(function)自定义函数(命名函数)
function fn(){

}
fn();
(2)函数表达式(匿名函数)
  • 没有定义函数名,只有变量名
  • 函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数
let 变量名 = function(){
	console.log('我是函数表达式')}
变量名();

3.8 JS预解析

  • js 引擎运行 js 分为两步 :预解析、代码执行
  • 预解析分为 变量预解析(变量提升) 和函数与解析(函数提升)
    • 变量提升:就是把所有的变量提升到当前作用域的最前面,不提升赋值操作。
    • 函数提升:就是把所有的函数声明提升到当前作用域的最前面不调用函数
  • 预解析 js 会把里面所有的 var 还有 function 提升到当前作用域的最前面
  • es6 中使用 let ,没有变量提升

3.9 对象(object)

3.9.1 什么是对象

在 JS 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等

  • 对象是由属性方法组成的
    • 属性:事物的特征,在对象中用属性来表示(常用名词)
    • 方法:事物的行为,在对象中用方法来表示(常用动词)
3.9.2 创建对象的三种方式:
  • 利用字面量创建对象:就是花括号{}里包含了表达这个事物(对象)的属性和方法

    • 创建对象:

      • 里面的属性或者方法我们采取键值对的方式 属性名 :属性值

      • 多个属性方法或者方法中间用逗号隔开

      • 方法冒号后面跟的是个匿名函数

        let obj = {
        	uname:'小羊',
        	age:18,
        	sex:'男',
        	sayHi:function(){
        		console.log('hi~');
        	}
        }
        
    • 使用对象

      • 调用对象的属性,我们采用 对象名.属性名

        console.log(obj.uname);
        
      • 调用属性还有另外一种方法 对象名[‘属性名’]

        console.log(obj['age']);
        
      • 调用对象方法的方法 对象名.方法名 千万别忘记小括号

        obj.sayHi();
        
  • 利用 new Object 创建对象

    • 创建对象

      • 利用等号赋值的方法添加对象的属性和方法

      • 每个属性和方法之间用分号结束

        let obj = new Object;//创建了一个空的对象
        obj.uname = '小羊';
        obj.age = 18;
        obj.sex = '男';
        obj.sayHi = function() {
        	console.log('hi~')
        }
        
    • 使用对象

      • 同自变量调用对象一样
  • 利用构造函数创建对象

    为什么需要构造函数:前面两种方式一次只能创建一个对象

    因此我们可以利用函数的方法,重复这些相同的代码,我们就把这个函数称为 构造函数

    构造函数:就是把对象里一些相同的属性和方法抽象出来封装到函数里面

    • 构造函数的语法格式

      • 构造函数名首字母必须大写
      • 构造函数不需要返回 return 就可以返回结果
      function Star(uname,age,sex) {
      	this.name = uname;
      	this.age = age;
      	this.sex = sex;
      	this.sing = function(){
      		console.log()
      	}
      }
      
    • 调用构造函数(必须使用new)

    let ldh = new Star('刘德华',18,'男');
    console.log(ldh.name);
    console.log(ldg['age']);
    ldh.sing('冰雨');
    
  • 构造函数和对象

    • 我们利用构造函数创建对象的过程也称为对象的实例化

    • 构造函数 类似于 java 语言里面的类(Star)

      function Star(uname,age,sex) {
      	this.name = uname;
      	this.age = age;
      	this.sex = sex;
      	this.sing = function(){
      		console.log()
      	}
      }
      
    • 对象 是一个具体的事物 类似于类的实例化(ldh):

      let ldh = new Star('刘德华',18,'男');
      
3.9.3 变量、属性、函数、方法的区别
  • 变量和属性

    • 相同点:都是用来存储数据的
    • 不同点:
      • 变量是单独声明并赋值,使用时可以直接写变量名(单独存在);
      • 属性是在对象里面的,不需要声明,使用时必须是 对象.属性
  • 函数和方法

    • 相同点:都是用来实现某种功能的

    • 不同点:

      • 函数是单独声明,并且调用的(单独存在)
      • 方法是在对象里面的,调用的时候 对象.方法()
3.9.4 new 关键字执行过程
  • new 构造函数首先在内存中创建一个空的对象
  • this 就会指向刚才创建的空对象
  • 执行构造函数里面的代码,给空对象添加属性和方法
  • 返回这个对象(所以不需要return)
3.9.5 遍历对象

对象里的属性和方法是无序的,所以不能使用 for 循环遍历

for…in 语句用于对数组或者对象的属性进行循环操作。

  • 语法格式

    for (变量 in 对象) {
    
    }
    
    • 代码实操

    • 我们使用 for…in 里面的变量,一般写 k 或者 key

      let obj = {
          name : 'sheep',
          age : 18,
          sex : '女',
          fn : function(){}
      }
      
      //遍历对象
      for (let k in obj) {
          console.log(k);// k 变量 输出得到属性名
          console.log(obj[k]);// obj[k] 输出得到属性值
      }
      

3.10 内置对象

  • JS中对象分为三种:自定义对象、内置对象、浏览器对象
  • 内置对象就是指 JS 语言自带的一些对象,供开发者使用,并提供了一些常用的或者是最基本而必要的功能(属性和方法),帮助我们快速开发
  • JS 提供了多个内置对象:Math、Date、Array、String等
3.10.1 查阅文档
  • MDN

    https://developer.mozilla.org/zh-CN/

3.10.2 Math

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AS0h6wha-1668609019257)(https://gitee.com/colohh/image_bed/raw/master/img/Math%E5%AF%B9%E8%B1%A1.png)]

  • 不是构造函数,所以我们不需要 new 来调用,而是直接使用里面的属性和方法即可

    • 调用属性

      //圆周率
      console.log(Math.PI);
      
    • 调用方法

      //取最大值
      console.log(Math.max(1,99,3))
      
  • 随机数方法 Math.random

    • random() 返回一个[ 0,1 )之间随机的小数

    • 这个方法里面不跟参数

    • 我们想要得到这两个数之间的随机整数 并且 包含这两个整数

      function getRandom(min, max) {
        	min = Math.ceil(min);
        	max = Math.floor(max);
        	return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值
      }
      	console.log(getRandom(1,10));
      
3.10.3 Date 日期对象
  • Date 是一个构造函数,必须使用 new 来调用创建我们的日期对象(必须实例化)

    let date = new Date();
    console.log(date);
    
  • 如果没有参数,则返回当前系统的当前时间

参数常用的写法

  • 数字型 2019,10,1

    let date1 = new Date(2019,10,1);
    console.log(date1);
    
  • 字符串型 ‘2019-10-1 8:8:8’

    let date2 = new Date( '2019-10-1 8:8:8');
    console.log(date2);
    
  • 日期格式化

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NsJgqam7-1668609019257)(https://gitee.com/colohh/image_bed/raw/master/img/Date%E5%AF%B9%E8%B1%A1.png)]

  • 代码实操

    let date = new Date();//实例化
    console.log(date.getFullYear());//返回当前日期的年
    console.log(date.getMonth() + 1);//返回月份 month(0 - 11);
    console.log(date.getDay() + 1);//返回星期几 (周六返回6;周日返回0)
    
  • 获取Date的总的毫秒数(时间戳)(距离1970.01.01过了多少毫秒数)

    • 通过 valueOf()

      let date = new Date();
      console.log(date.valueOf());
      
    • 通过 getTime()

      let date = new Date();
      console.log(date.getTime());
      
    • 简单写法 ==+==new Date()

      let date1 = +new Date();
      
    • h5 新增写法

      console.log(Date.now());
      
3.10.4 数组对象
(1)检测是否为数组
  • instanceof 运算符,可以用来检测是否为数组

    let arr = [];
    let obj = {};
    console.log(arr instanceof Array);//true
    console.log(obj instanceof Array);//false
    
  • Array.isArray(参数); h5新增

    let arr = [];
    console.log(Array.isArray(arr));//true
    
(2)添加删除数组元素的方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MHfFKHS4-1668609019258)(https://gitee.com/colohh/image_bed/raw/master/img/%E6%B7%BB%E3%80%81%E5%88%A0%E6%95%B0%E7%BB%84%E5%85%83%E7%B4%A0%E7%9A%84%E6%96%B9%E6%B3%95.png)]

  • push() 在数组的末尾,添加一个或多个数组元素

    • push() 括号里参数直接写数组元素

    • push 完之后,返回的结果是新数组的长度

      let arr.push(4,'pink');
      console.log(arr.push(4,'pink'))// 5
      
  • unshift() 在数组的开头,添加一个或多个数组元素

    • unshift() 括号里参数直接写数组元素

    • unshift 完之后,返回的结果是新数组的长度

      let arr = [1,2,3];
      arr.unshift(4,'pink');
      console.log(arr.unshift(4,'pink'))// 5
      
  • pop() 删除数组的最后一个元素

    • pop() 里不写参数

    • 返回值是被删掉的数组元素

      let arr = [1,2,3];
      arr.pop();
      console.log(arr.pop());// 3
      
  • shift() 删除数组的第一个元素

    • shift() 里不写参数

    • 返回值是被删掉的数组元素

      let arr = [1,2,3];
      arr.shift();
      console.log(arr.shift());// 1
      
(3)数组排序
  • 翻转数组

    • reverse()

      let arr = ['pink','red','blue'];
      arr.reverse();
      console.log(arr);
      
  • 冒泡排序

    • sort()

      let arr = [8,3,6,4,5];
      arr.sort(function(a - b){
      	return a - b;//升序的顺序排列
      	return b - a;//降序的顺序排列
      });
      console.log(arr1);
      
(4)数组索引方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0iRPDmG0-1668609019258)(https://gitee.com/colohh/image_bed/raw/master/img/%E6%95%B0%E5%AD%97%E7%B4%A2%E5%BC%95%E6%96%B9%E6%B3%95.png)]

  • indexOf(数组元素,[起始位置])

    • 只返回第一个满足条件的数组元素的索引号

    • 如果在该数组里找不到元素,则返回 -1

      let arr = ['pink','red','blue','green','blue'];
      console.log(arr.indexOf('blue'));// 2 返回数组元素的索引号
      
  • lastIndexOf(数组元素)

    • 类似于 indexOf(),不过 lastIndexOf()是从后往前查找

    • 如果在该数组里找不到元素,则返回 -1

      let arr = ['pink','red','blue','green','blue'];
      console.log(arr.lastIndexOf('blue'));// 4
      
(5)数组转换为字符串
  • toString()

    • 直接转换为字符串

      let arr = [1,2,3];
      console.log(arr.toString());//1,2,3
      
  • join(‘分隔符’)

    • 更高级,join() 可以自定义分隔符

      let arr = [1,2,3];
      console.log(arr.join());// 1,2,3
      console.log(arr.join('-'));//1-2-3
      console.log(arr.join('&'));//1&2&3
      
3.10.5 字符串对象
(1)基本包装类型

复杂数据类型才有 属性和方法

简单数据类型为什么会有 length 属性呢

  • 基本包装类型:就是把简单数据类型(三个:String、Number、Boolean)包装成为了复杂数据类型,这样基本数据类型就有了属性和方法

    // 底层流程展示
    let str = 'sheep';
    console.log(str.length);
    //1. 把简单数据类型包装为复杂数据类型
    let temp = new String('andy');
    //2. 把临时变量的值给 str
    str = temp;
    //3. 销毁这个临时变量
    temp = null;
    
(2)字符串的不可变性
  • 值不可变:看上去是改变了内容,实际上是改变字符串变量名指向的地址(好像指针噢),内存中开辟了一个新的内存空间存了一个新值(因此不要大量的拼接字符串
(3)根据字符返回位置

字符串的所有方法,都不会修改字符串本身(字符串本身是不可变的),操作完成会返回一个新的字符串

  • indexOf(‘字符’,[起始位置])

    let str = '改革春风吹满地,春天来了';
    console.log(str.indexOf('春'));// 2
    console.log(str.indexOf('春',3));// 8 从索引号是 3 的位置开始往后查找
    
  • lastIndexOf(‘字符’,[起始位置])

(4)根据位置返回字符(重点)
  • charAt(index)

    • 获取指定位置处的字符

      let str = 'sheep';
      console.log(str.charAt(1));// h
      
    • 利用 charAt( ) 遍历字符串

      for (i = 0; i < str.lenghth ;i++) {
          console.log(str.charAt(i));
      }
      
  • charCodeAt(index)

    • 返回相应索引号的字符ASCII值 目的:判断用户按下了哪个键

      let str = 'sheep';
      console.log(charCodeAt(1));// 104
      
    • 附 ASCII 码表

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zPVPRo8a-1668609019259)(https://gitee.com/colohh/image_bed/raw/master/img/ASCII%E7%A0%81%E8%A1%A8.PNG)]

  • str[index]

    • 获取指定位置处的字符(HTML5)
    let str = 'sheep';
    console.log(str[1]);// h
    
(5)字符串的基本操作方法(重点)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aNL3cGAr-1668609019259)(https://gitee.com/colohh/image_bed/raw/master/img/%E5%AD%97%E7%AC%A6%E4%B8%B2%E7%9A%84%E6%93%8D%E4%BD%9C%E6%96%B9%E6%B3%95.png)]

(6)字符串的连接
  • concat(str1,str2…)

    • 用于连接两个或多个字符串,拼接字符串,等效于+ ,+更常用

      let str = 'andy';
      console.log(str.concat('red'));// andyred
      
(7)自定义位置索引
  • substr(start,length)

    • 从 start 位置开始索引,length 取的个数

      let str = '改革春风吹满地';
      console.log(str.substr(2,2));// 春风
      
  • slice(start,end)

    • 从 start 位置开始,截取到 end 位置(不包含end)
  • substring(start,end)

    • 从 start 位置开始,截取到 end 位置(不包含end),基本和 slice 相同,但不接受负值
(8)替换字符
  • replace(‘被替换的字符’,‘替换为的字符’)

    • 只替换第一个符合要求的字符

      let str = 'andy';
      console.log(str.replace('a','b'));
      
(9)字符串转换为数组
  • split(‘分隔符’)

    • 分隔符取决于字符串用什么符号来把它们分开的

      let str1 = 'red,pink,blue';
      console.log(str1.split(','));//[red,pink,blue]
      
      let str2 = 'red&pink&blue';
      console.log(str2.split('&'));//[red,pink,blue]
      
3.11 JS 简单数据类型和复杂数据类型
3.11.1 简单类型与复杂类型
  • 简单类型又叫做值类型,在存储时变量中存储的是值本身,因此叫做值类型

    string , number , boolean , undefined , null

    • 其中 null 比较特殊 typeof 它返回的是一个空的对象(object)

      所以如果有一个变量我们以后打算存储为对象,暂时没想好放什么,这个时候就给 null

      let timer = null;
      console.log(typeof timer);//object
      
  • 复杂类型又叫做引用类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用类型

    通过 new 关键字创建的对象(系统对象,自定义对象):如Object , Array , Date 等

3.11.2 堆和栈

JS 里没有堆和栈的概念,只是帮助我们方便理解代码的执行方式

  • 分配区别
    • 栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面
    • 2、堆(操作系统)∶存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂数据类型存放到堆里面
3.11.3 简单类型的内存分配
  • 简单数据类型存放到栈里面
  • 在栈里面直接存放的是值
3.11.4 复杂类型的内存分配
  • 复杂数据类型存放到堆里面
    • 首先在栈里面存放地址 用十六进制表示,然后这个地址指向堆里面存储的数据
3.11.5 简单类型传参
  • 函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量

    function fn(a) {
    	a++;
    	console.log(a);// 11
    }
    let x = 10;
    fn(x);
    console.log(x);// 10
    
3.11.5 复杂类型传参
  • 函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象

    function Person(name) {
        this.name = name;
    }
    function f1(x) {
        console.log(x.name);// 2.这个输出是:刘德华
        x.name = '张学友';
        console.log(x.name);// 3.这个输出是:张学友
    }
    let p = new Person('刘德华');
    console.log(p.name);// 1.这个输出是:刘德华
    f1(p);
    console.log(p.name);// 4.这个输出是:张学友
    
  • 图解上面代码:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FFgnVSXQ-1668609019259)(https://gitee.com/colohh/image_bed/raw/master/img/%E5%A4%8D%E6%9D%82%E7%B1%BB%E5%9E%8B.png)]
    .split(‘,’));//[red,pink,blue]

    let str2 = ‘red&pink&blue’;
    console.log(str2.split(‘&’));//[red,pink,blue]

    
    
    
3.11 JS 简单数据类型和复杂数据类型
3.11.1 简单类型与复杂类型
  • 简单类型又叫做值类型,在存储时变量中存储的是值本身,因此叫做值类型

    string , number , boolean , undefined , null

    • 其中 null 比较特殊 typeof 它返回的是一个空的对象(object)

      所以如果有一个变量我们以后打算存储为对象,暂时没想好放什么,这个时候就给 null

      let timer = null;
      console.log(typeof timer);//object
      
  • 复杂类型又叫做引用类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用类型

    通过 new 关键字创建的对象(系统对象,自定义对象):如Object , Array , Date 等

3.11.2 堆和栈

JS 里没有堆和栈的概念,只是帮助我们方便理解代码的执行方式

  • 分配区别
    • 栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面
    • 2、堆(操作系统)∶存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂数据类型存放到堆里面
3.11.3 简单类型的内存分配
  • 简单数据类型存放到栈里面
  • 在栈里面直接存放的是值
3.11.4 复杂类型的内存分配
  • 复杂数据类型存放到堆里面
    • 首先在栈里面存放地址 用十六进制表示,然后这个地址指向堆里面存储的数据
3.11.5 简单类型传参
  • 函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量

    function fn(a) {
    	a++;
    	console.log(a);// 11
    }
    let x = 10;
    fn(x);
    console.log(x);// 10
    
3.11.5 复杂类型传参
  • 函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象

    function Person(name) {
        this.name = name;
    }
    function f1(x) {
        console.log(x.name);// 2.这个输出是:刘德华
        x.name = '张学友';
        console.log(x.name);// 3.这个输出是:张学友
    }
    let p = new Person('刘德华');
    console.log(p.name);// 1.这个输出是:刘德华
    f1(p);
    console.log(p.name);// 4.这个输出是:张学友
    
  • 图解上面代码:

    [外链图片转存中…(img-FFgnVSXQ-1668609019259)]

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值