JavaScript基础

  • A+
所属分类:Web前端
摘要

  JavaScript是一种运行在客户端的脚本语言,现基于Node.js技术进行服务端编程;

 

JavaScript基础

1- 初识JavaScript

1.1 JavaScript 是什么

  • JavaScript是一种运行在客户端的脚本语言,现基于Node.js技术进行服务端编程;

    所谓脚本(Script)语言:是运行时不需要编译,运行过程中由 js 解释器( js 引擎)逐行来进行解释并执行。读到一行,执行一行;

  • 目的是实现逻辑业务与页面控制,相当于动作;

    所谓逻辑性:就是 实现这个要求的思路 先怎么做后怎么做;

1.2 JavaScript的作用

  • 表单动态校验(密码强度检测) ( JS 产生最初的目的 )

  • 网页特效

  • 服务端开发(Node.js)

  • 桌面程序(Electron)

  • App(Cordova)

  • 控制硬件-物联网(Ruff)

  • 游戏开发(cocos2d-js)

1.3 HTML/CSS/JS 的关系

HTML 和 CSS 属于描述类语言;JS 属于 编程类语言;

JavaScript基础

1.4 浏览器执行 JS 简介

浏览器分成两部分:渲染引擎和 JS 引擎

  • 渲染引擎:用来解析HTML和CSS,俗称内核,比如 chrome浏览器的 blink,老版webkit等;

  • JS 引擎:也称 JS 解释器。用来读取网页中的 JavaScript代码,处理后运行,如chrome的V8;

    浏览器本身并不会执行JS代码,而是通过内置 JavaScript 引擎(解释器) 来执行 JS 代码 。JS 引擎执行代码时逐行解释每一句源码(转换为机器语言),然后由计算机去执行,所以 JavaScript 语言归为脚本语言,会逐行解释执行。

1.5 JS 的组成

JavaScript基础

  1. ECMAScript

    ECMAScript:规定了JS的编程语法和基础核心知识,是所有浏览器厂商共同遵守的一套JS语法工业标准。

    更多参看MDN: MDN手册

  2. DOM——文档对象模型

    文档对象模型(DocumentObject Model,简称DOM),是W3C组织推荐的处理可扩展标记语言的标准编程接口。通过 DOM 提供的接口可以对页面上的各种元素进行操作(大小、位置、颜色等)——元素对象;

  3. BOM——浏览器对象模型

    浏览器对象模型(Browser Object Model,简称BOM) 是指浏览器对象模型,它提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。通过BOM可以操作浏览器窗口,比如弹出框、控制浏览器跳转、获取分辨率等——浏览器窗口;

 

1.6 JS 书写位置

JS 有3种书写位置,分别为行内、内嵌和外部。

1.行内式

<input type="button" value="点我" onclick="alert('Hello World')" />

 

  • 可以将单行或少量 JS 代码写在HTML标签的事件属性中(以 on 开头的属性),如:onclick

  • 注意单双引号的使用:在HTML中我们推荐使用双引号, JS 中我们推荐使用单引号

  • 可读性差, 在html中编写JS大量代码时,不方便阅读;

2.内嵌式

<script>     alert('Hello  World~!'); </script>

 

  • 可以将多行JS代码写到 script 标签中

  • 内嵌 JS 是学习时常用的方式

3.外部JS文件

<script src="my.js"></script>

 

  • 利于HTML页面代码结构化,把大段 JS代码独立到 HTML 页面之外,既美观,也方便文件级别的复用

  • 引用外部 JS文件的 script 标签中间不可以写代码

  • 适合于JS 代码量比较大的情况

    <head>         <meta charset="UTF-8">         <title>Document</title>         <!-- 2.内嵌式的js -->         <script>             alert('这是我的第一个js');         </script> // 3.外部js的写法,开始和结束标签间不能写字         <script src="script.js"> </script>     </head> <body>         <!-- 1.行内式的js 直接写到元素内部,以on开头的属性 外双内单引号 -->         <input type="button" value="提交" onclick="alert('提交成功')">     </body>

 

 

2 - JavaScript注释

JS中的注释主要有两种,分别是单行注释和多行注释。

1. 单行注释 // 用来注释单行文字(  快捷键   ctrl  +  /   ) 2. 多行注释 /* */  用来注释多行文字( 默认快捷键  alt +  shift  + a )

 


更改快捷键:vscode → 首选项按钮 → 键盘快捷方式 → 查找 原来的快捷键 → 修改为新的快捷键 → 回车确认

3 - JavaScript输入输出语句

为了方便信息的输入输出,JS中提供了一些输入输出语句,其常用的语句如下:

方法 说明 面向对象
alert(msg) 浏览器弹出警示框 用户
console.log(msg) 浏览器控制台打印输出信息 程序员
prompt(info) 浏览器弹出输入框,用户可以输入 用户
  <script>        // 1.弹出输入框 输入内容后默认弹出输入的内容         prompt('请输入你的年龄');        // 2.alert 弹出警示框 输出的 展示给用户的         alert('这是我的第一个js');       // 3.console 控制台输出打印信息 给程序员测试用的 浏览器f12控制台左手第二个         console.log('这是程序员能看到的');   </script>

 

 

程序设计基础

1 - 变量概述

1.1 什么是变量

  • 为什么需要变量?有些数据需要保存,所以需要变量;

  • 变量是什么?变量相当一个容器,用来存储数据;

  • 本质?变量的本质是程序在内存中的一块存储空间;

  • 通过变量名找到变量,访问内存;

  • 变量的命名规范:见名知意-驼峰命名法;

1.2 - 变量的使用

  • 变量的声明

  • 变量的赋值

  • 变量的初始化

    1.声明变量

var age; // 声明一个名称为 age 的变量;本质是 在内存中申请一块存储空间

 

  • var 是一个 JS关键字,用来声明变量( variable 变量的意思 )。使用该关键字声明变量后,计算机会自动为变量分配内存空间,不需要程序员管;

  • age 是程序员定义的变量名,我们要通过 变量名来访问内存中分配的空间;

    2.赋值

age = 10; // 给 age 这个变量赋值为 10    

 

      
  • = 表示赋值,用来把右边的值赋给左边的变量空间

  • 变量值是程序员保存到变量空间里的值

    3.变量的初始化

声明一个变量的同时并赋值, 我们称之为变量的初始化。

var age  = 18;  // 声明变量同时赋值为 18

 

案例:

  • 弹出一个输入框,提示用户输入姓名;

  • 弹出一个对话框,输入 用户刚才输入的姓名;

    <script>         // 1.用户输入姓名 存储到一个myname的变量里 变量是存储容器         var myname = prompt('请输入姓名');         // 2.输出这个用户名         alert(myname);         // alert('myname');加了单引号就显示不出变量名了     </script>

 

 

1.3 变量语法扩展

1.更新变量

变量被重新复赋值后,它原有的值就会被覆盖,变量值将以最后一次赋的值为准。

var age = 18; age = 81;   // 最后的结果就是81 因为18 被覆盖掉了 

 

         

2.同时声明多个变量

同时声明多个变量时,只需要写一个 var, 多个变量名之间使用英文逗号隔开。

var age = 10,  name = 'zs', sex = 2;     

 

3.声明变量特殊情况

情况 说明 结果
var age ; console.log (age); 只声明 不赋值 undefined
console.log(age) 不声明 不赋值 直接使用 报错
age = 10; console.log (age); 不声明 只赋值 10 可运行

案例:变量的语法扩展

    <script>         // 1.更新变量 变量被重新赋值后,以最新一次为准         var myname = '卡卡西';         console.log(myname);         myname = '火影';         console.log(myname);//最新一次显示 火影 但之前的因为也输出了,也会有历史显示          // 2.声明多个变量,可简写 只需写一个var,变量名间逗号隔开,分号表结束         // var age = 18;         // var address = '通辽';         // var sex = 'nv';         var age = 18,             address = '通辽',                 sex = 'nv';          // 3. 声明变量的特殊情况         // 3.1 只声明 不赋值 结果是?undefined         var sex;         console.log(sex); // undefined         // 3.2 不声明 不赋值 直接使用某个变量会报错         console.log('tel');         // 3.3 不声明直接赋值 js 可以使用         qq = 110;         console.log(qq); // 110     </script>

 

案例:交换两个变量的值

js 是编程语言有很强的逻辑性在里面: 实现这个要求的思路 先怎么做后怎么做

// 思路:引入一个临时变量temp     <script>         var temp;         var apple1 = '青苹果';         var apple2 = '红苹果';         temp = apple1;         apple1 = apple2;         apple2 = temp;         console.log(apple1);         console.log(apple2);     </script>

 

1.4 变量命名规范

  • 由字母(A-Za-z)、数字(0-9)、下划线(_)、美元符号( $ )组成,如:usrAge, num01, _name

  • 严格区分大小写。var app; 和 var App; 是两个变量

  • 不能 以数字开头。 18age 是错误的

  • 不能 是关键字、保留字。例如:var、for、while

  • 变量名必须有意义。 MMD BBD nl → age

  • 遵守驼峰命名法。首字母小写,后面单词的首字母需要大写。

 

2 - 数据类型

2.1 数据类型简介

1.为什么需要数据类型?

在计算机中,不同的数据所需占用的存储空间是不同的,为了便于把数据分成内存所需的大小,充分利用存储空间,于是定义了不同的数据类型。

2.变量的数据类型?

变量的数据类型决定了以什么样的类型存储到计算机的内存中。JavaScript 是一种弱类型或者说动态语言。这意味着不用提前声明变量的类型;在程序运行过程中,变量的数据类型是由 JS引擎根据 = 右边变量值的数据类型来判断的。

var age = 10;// 这是一个数字型 var areYouOk = '是的';// 这是一个字符串     

 

JavaScript 拥有动态类型,同时也意味着相同的变量可用作不同的类型:

var x = 6;// x 为数字 var x = "Bill";// x 为字符串   

 

3.数据类型的分类

  • 简单数据类型 (Number,String,Boolean,Undefined,Null)

  • 复杂数据类型 (object)

2.2 简单数据类型

简单数据类型(基本数据类型)

简单数据类型 说明 默认值
Number 数字型,包含整形和浮点型,如21和0.21 0
String 字符串型,加了引号的都是字符串 “ ”、‘ ’
Boolean 布尔值型,返回值true、false,等价于1和0 false
Undefined var a;声明变量确没给值,此时a = undefined undefined
Null var a = null;声明了变量a为空值 null

1、数字型 Number

  <script>             // 1.存储整形和浮点型         var age = 21; // 整数         var Age = 21.3747; // 小数            // 2.存储各进制数值         var num1 = 010; // 八进制         var num2 = 0xff; // 十六进制          // 3.数字型范围 三个特殊值         alert(Number.MAX_VALUE); // 最大值         alert(Number.MIN_VALUE); // 最小值         alert(Infinity); // 无穷大         alert(-Infinity); // 无穷小         alert(NaN); // not a number,代表一个非数值          console.log('Number.MAX_VALUE * 2'); // Infinity 无穷大         console.log('-Number.MAX_VALUE * 2'); // -Infinity 无穷小          console.log('pink老师' - 100);// NaN 非数值          // 4.isNaN() 判断 非数字类型 并且返回一个值          // 是数字返回 false 不是返回true         console.log(isNaN(12)); // false         console.log(isNaN(userName)); // true   </script>

 

2、字符串型 String

(1)字符串型是引号内的任意文本,内部换行需要用转义字符 如 n

    <script>         // 嵌套原则:外双内单 或 外单内双;         var str = '我是一个"高富帅"的程序员';         console.log(str);          // 字符串转义字符  都是用  开头 但是这些转义字符写到引号里面         var str1 = "我是一个'高富帅'的n程序员";         console.log(str1);     </script>

 

(2)字符串转义符

转义符 解释说明
n 换行符,n 是 newline 的意思
斜杠
' ' 单引号
" ”双引号
t tab 缩进
b 空格 ,b 是 blank 的意思

(3)字符串拼接:

  • 多个字符串之间可以使用 + 进行拼接, 字符串 + 任何类型 = 新字符串类型

  • + 号总结口诀:数值相加 ,字符相连

    <script>         // 1. 检测获取字符串的长度 length          var str = 'my name is andy';         console.log(str.length); // 15          // 2. 字符串的拼接 + 不同类型也可拼接 但最后是字符串型          // 数字型是结果 即:数值相加、字符相连         console.log('沙漠' + '骆驼'); // 字符串的 沙漠骆驼         console.log('pink老师' + 18); // 'pink老师18'         console.log('pink' + true); // pinktrue         console.log(12 + 12); // 24         console.log('12' + 12); // '1212'     </script>

 

(4)字符串拼接加强

  • 经常会将字符串和 变量 来拼接,变量可以很方便地修改里面的值

  • 变量是不能添加引号的,因为加引号的变量会变成字符串

  • 如果变量两侧都有字符串拼接,口诀“引引加加 ”,删掉数字,变量写加中间

    <script>         console.log('pink老师 18 岁');         //先写此句,然后删除18 引引加加 中间加变量                  var age = 18;         console.log('pink老师' + age + '岁');// 引引加加     </script>

 

案例:交互编程的三个基本要素

  • 用户输入:弹出一个输入框prompt,让用户输入年龄;

  • 程序内部处理:把用户输入的值作为变量保存起来,把刚才输入的年龄与所要输出的字符串拼接;

  • 输出结果:使用alert语句弹出警示框;

案例:显示年龄案例

    <script>         var age = prompt('请输入你的年龄');         var str = '你今年已经' + age + '岁了';         alert(str);     </script>

 

 

3、布尔型Boolean

  • 布尔类型有两个值:true 和 false ,其中 true 表示真,而 false 表示假;

  • 布尔型和数字型相加的时候, true 的值为 1 ,false 的值为 0;

console.log(true + 1);  // 2 console.log(false + 1); // 1

 

4、Undefined 和 Null

  • 一个声明后没有被赋值的变量会有一个默认值undefined ( 如果进行相连或者相加时,注意结果)

var variable; console.log(variable);           // 只声明未赋值 输出 undefined console.log('你好' + variable);  // 你好undefined console.log(11 + variable);    // undefined 和数字相加 输出 NaN  console.log(true + variable); //  NaN

 

  • 一个声明变量给 null 值,里面存的值为空(学习对象时,我们继续研究null)

var vari = null; console.log('你好' + vari);  // 你好null console.log(11 + vari);     // 11 console.log(true + vari);   //  1

 

2.3 获取变量数据类型

1.typeof 获取检测变量的数据类型

    <script>         var num = 18;         console.log(typeof num); // number         var str = 'pink';         console.log(typeof str); // string         var flag = true;         console.log(typeof flag); // boolean         var vari = undefined;         console.log(typeof vari); // undefined         var timer = null;         console.log(typeof timer); // object          // prompt 取过来的值是 字符型的         var age = prompt('请输入您的年龄');         console.log(age);         console.log(typeof age); // string     </script> 

 

也可以通过控制台的颜色判断数据类型;黑色是字符串;

2.字面量

字面量表示如何表达这个值,一眼看上去知道这个属于什么类型的值。

    <script>         console.log(18);// 数字字面量         console.log('18');// 字符串字面量         console.log(true);// 布尔字面量         console.log(undefined);         console.log(null);     </script>

 

 

2.4 数据类型转换

什么是数据类型转换?就是把一种数据类型的变量转换成另一种数据类型,通常会实现3种方式的转换:

  • 转换为字符串类型

  • 转换为数字型

  • 转换为布尔型

1.转换为字符串

方式 说明 案例
加号拼接字符串 和字符串拼接的结果都是字符串 var num = 1;alert(num + '我是字符串');也称隐式转换
toString( ) 转成字符串 var num = 1;alert(num.toString( ));
String( )强制转换 转成字符串 var num = 1;alert(String(num));
    <script>         // 1. 把数字型转换为字符串型变量 .toString()         var num = 10;         var str = num.toString();         console.log(str);         console.log(typeof str);         // 2. 我们利用 String(变量)            console.log(String(num));         // 3. 利用 + 拼接字符串的方法实现转换效果 隐式转换         console.log(num + '');     </script>

 

2.转换为数字型(重点)

方式 说明 案例
parseInt(string)函数 将string类型转换成整数数值型 parseInt('78')
parseFloat(string)函数 将string类型转换成浮点数值型 parseFloat('78.21')
Number()强制转换函数 将string类型转换成数值型 Number('12')
js隐式转换(- * /) 利用算数运算隐式转换为数值型 '12' - 0
    <script>         var age = prompt('请输入你的年龄');         // 1. parseInt(变量) 可以把字符型的转换成数字型 得到的是整数         console.log(parseInt(age));         console.log(parseInt('3.14')); // 整数 3         console.log(parseInt('120px')); // 整数 120 单位px被去掉         console.log(parseInt('rem120px')); // NaN 首字母检测不是数字          // 1. parseFloat(变量) 可以把字符型的转换成浮点型 得到的是浮点数         console.log(parseFloat('3.14')); // 3.14         console.log(parseFloat('120px')); // 单位也会去掉          // 3. Number(变量)         var str = '123';         console.log(Number(str));         console.log(Number('12'));          // 4. 利用了算术运算 - * / 隐式转换(不能 +)         console.log('12' - 0); // 数字型 12,先把数字转为数字型在-         console.log('123' - '120'); // 3          console.log('123' + '120'); // 123120 + 是字符串拼接,     </script>

 

 

案例:输出年龄

思路:

  • 弹出一个输入框(prompt),让用户输入出生年份(用户输入)

  • 把用户输入的值用变量保存起来,用今年年份减去变量值,就是现在的年龄(程序内部处理)

  • 弹出警示框(alert),把计算的结果输出(输出结果)

    <script>         var year = prompt('请输入你的出生年份');         var age = 2020 - year;// year是字符串 减法隐式转换 成数字型         alert('你今年已经 ' + age + ' 岁了');     </script>

 

案例:简单加法器

要求:计算两个数的值,用户输入第一个值后,继续弹出第二个输入框并输入第二个值,最后弹出窗口显示两次输入值相加的结果。

    <script>           var num1 = prompt('请输入第一个值:');         var num2 = prompt('请输入第二个值:');         var result = parseFloat(num1) + parseFloat(num2);         alert('结果是:' + result);     </script>

 

3.转换为布尔型

  • 代表空、否定的值会被转换为 false ,如 ''、0、NaN、null、undefined ;

  • 其余值都会被转换为 true;

console.log(Boolean('')); // false console.log(Boolean(0)); // false console.log(Boolean(NaN)); // false console.log(Boolean(null)); // false console.log(Boolean(undefined)); // false  console.log(Boolean('小白')); // true console.log(Boolean(12)); // true

 

 

3 - 标识符、关键字、保留字

3.1 标识符

标识(zhi)符:就是指开发人员 为变量、属性、函数、参数取的名字。 标识符不能是关键字或保留字。

3.2 关键字

关键字:是指 JS本身已经使用了的字,不能再用它们充当变量名、方法名。  包括:break、case、catch、continue、default、delete、do、else、finally、for、function、if、in、instanceof、new、return、switch、this、throw、try、typeof、var、void、while、with 等。

3.3 保留字

保留字:实际上就是预留的“关键字”,意思是现在虽然还不是关键字,但是未来可能会成为关键字,同样不能使用它们当变量名或方法名。  包括:boolean、byte、char、class、const、debugger、double、enum、export、extends、fimal、float、goto、implements、import、int、interface、long、mative、package、private、protected、public、short、static、super、synchronized、throws、transient、volatile 等。  注意:如果将保留字用作变量名或函数名,那么除非将来的浏览器实现了该保留字,否则很可能收不到任何错误消息。当浏览器将其实现后,该单词将被看做关键字,如此将出现关键字错误。

3.4 标识符命名规范

  • 变量、函数的命名必须要有意义

  • 变量的名称一般用名词

  • 函数的名称一般用动词

  • 操作符(=)、括号、左右各留一个空格;

    注释后面打一个空格;

     

4 - 运算符(操作符)

4.1 运算符的分类

运算符(operator)也被称为操作符,是用于实现赋值、比较和执行算数运算等功能的符号。

JavaScript中常用的运算符有:     - 算数运算符  + - * / %     - 递增和递减运算符  ++ --     - 比较运算符  > < >= <= != ==     - 逻辑运算符  && || !     - 赋值运算符  =

4.2 算数运算符

1.算术运算符概述

概念:算术运算使用的符号,用于执行两个变量或值的算术运算。

运算符 描述 实例
+ 10+20=30
- 10-20=-10
* 10*20=200
/ 10/20=0.5
% 取余数(取模) 返回除法的余数 9%2=1

2.浮点数的精度问题

浮点数值的最高精度是 17 位小数,但在进行算术计算时其精确度远远不如整数。

    var result = 0.1 + 0.2; // 结果是:0.30000000000000004     console.log(0.07 * 100); // 结果是:7.000000000000001     // 所以:不要直接判断两个浮点数是否相等 !

 

3.表达式和返回值

表达式:是由数字、运算符、变量等组成的式子

表达式最终都会有一个结果,返回给开发者,称为返回值

 

4.3 递增和递减运算符

如果需要反复给数字变量+1或-1可以使用递增(++)和递减(--)运算符来完成。 在 JavaScript 中,递增(++)和递减(--)既可放在变量前,也可以放变量后面 前置递增和后置递增。 注意:前置递增和后置递增在单独使用时,效果是一样的;在表达式里,有所不同;

递增运算符

  • 前置递增运算符 “++变量”:

    使用口诀:先自加,后返回值 ++num——num = num + 1;

    var  num = 10;     alert(++num + 10);   // num = 11  11+10=21

 

  • 后置递增运算符 “变量++”:

    使用口诀:先原值运算,后自加 num++ —— num = num + 1 ;

    var  num = 10;     alert(10 + num++);  // num = 11 10+10=20

 

案例:递增运算符:

    <script>         var a = 10;         ++a; // ++a  11    a = 11         var b = ++a + 2; // a = 12         console.log(b); // 14          var c = 10;         c++; // c++ 11          var d = c++ + 2; //  c++  = 11+2     c = 12         console.log(d); // 13          var e = 10;         var f = e++ + ++e; // 1. e++ =  10  e = 11  2. e = 12  ++e = 12         console.log(f); // 10 + 12 = 22         // 后置自增  先表达式返回原值 后面变量再自加1     </script>

 

 

4.4 比较运算符

  • 比较运算符概述

    概念:比较运算符(关系运算符)是两个数据进行比较时所使用的运算符,比较运算后,会返回一个布尔值(true / false)作为比较运算的结果。

    运算符名称 说明 案例 结果
    < 小于号 1<2 true
    > 大于号 1>2 false
    >= 大于等于号 2>=2 true
    <= 小于等于号 2<=3 false
    == 判断号(会转型) 37==37 true
    != 不等号 37!=37 false
    === !== 全等 要求值和数据类型都一致 37==='37' false

     

  • 等号比较

    符号 作用 用法
    = 赋值 等号右侧的值赋给左侧
    == 判断 判断两边的值是否相等(注意隐式转换)
    === 全等 判断两边的值和数据类型是否完全相同

    实例:比较运算符

            //1. 我们程序里面的 == 是判断两边值是否相等         console.log(3 == 5); // false         console.log('pink老师' == '刘德华'); // flase         console.log(18 == 18); // true         console.log(18 == '18'); // true         console.log(18 != 18); // false         // 2. 我们程序里面有全等 一模一样  要求 两侧的值 还有 数据类型完全一致才可以 true         console.log(18 === 18);         console.log(18 === '18'); // false

     

4.5 逻辑运算符

  • 逻辑运算符概述

    逻辑运算符是用来进行布尔值运算的运算符,其返回值也是布尔值。

    逻辑运算符 说明 案例
    && "逻辑与" ’与‘ and true && false
    || "逻辑或" ’或‘ or true || false
    "逻辑非" ’非‘ not ! true

    案例:逻辑运算符

            <script>         // 1. 逻辑与 &&  and 两侧都为true  结果才是 true  只要有一侧为false  结果就为false          console.log(3 > 5 && 3 > 2); // false         console.log(3 < 5 && 3 > 2); // true         // 2. 逻辑或 || or  两侧都为false  结果才是假 false  只要有一侧为true  结果就是true         console.log(3 > 5 || 3 > 2); // true          console.log(3 > 5 || 3 < 2); // false         // 3. 逻辑非  not  !          console.log(!true); // false     </script>

     

     

  • 短路运算(逻辑中断)

    逻辑运算符左边的表达式值可以确定结果时,就不再继续运算右边的表达式的值;

    // 1.逻辑与 短路运算     //如果第一个表达式为真,则返回表达式2;如果第一个为假,则返回表达式1;     console.log(123 && 456);//456     console.log(0 && 456 + 1 && 2);// 0     console.log('' && 1 + 2 && 456 * 56789); // ''     // 空或者否定的为假 其余是真  0 ‘’ null undefined NaN 为假;      // 2.逻辑或 短路运算     //如果表达式1 结果为真 则返回表达式1 如果结果为假,则返回表达式2     console.log(123 || 456);//123     console.log(0 && 456 + 1 && 2);//456 继续向后运行

 

4.6 赋值运算符

概念:用来把数据赋值给变量的运算符。

赋值运算符 说明 案例
= 直接赋值 var name = '值';
+=、-= 加、减一个数后在赋值 var age = 10; age+=5; // 15
*=、/=、%= 乘、除、取模后再赋值 var age = 2; age*=5; // 10

案例:赋值运算符

    var age = 10;     age += 5;  // 相当于 age = age + 5;     age -= 5;  // 相当于 age = age - 5;     age *= 10; // 相当于 age = age * 10;

 

 

4.7 运算符优先级

优先级 运算符 顺序
1 小括号 ( )
2 一元运算符 ++ -- !
3 算术运算符 先 * / % 后 + -
4 关系运算符 > >= < <=
5 相等运算符 == != === !==
6 逻辑运算符 先 && 后 ||
7 赋值运算符 =
8 逗号运算符 ,
  • 一元运算符里面的逻辑非优先级很高

  • 逻辑与比逻辑或优先级高

 

5 - 流程控制

5.1 流程控制概念

流程控制就是来控制代码按照一定结构顺序来执行 流程控制主要有三种结构:顺序结构、分支结构、循环结构

5.2 顺序流程控制

特点:从上到下,依次执行

5.3 分支流程控制

特点:根据不同的条件,执行不同的路径代码(多选一的过程)得到不同的结果;

JS 语言提供了两种分支结构语句:if 语句、switch 语句

5.4 if 语句

       // 1. if语句          // 条件表达式成立 则执行代码,否则什么也不做         if (条件表达式) {             // 条件成立执行的代码语句         }         // 2. if else 双分支语句         // 分支语句 2选1过程 最终只有一条语句执行         if (条件表达式) {             语句1;//如果条件成立则执行语句1             }         else { 语句2 };//条件不成立执行语句2           // 3. 多分支语句          // 最后也是只有一个语句执行 else if任意多,都不成立执行 else         if (条件表达式1) {             语句1;         } else if (条件表达式2) {              语句2;               } else {             最后的语句;         }          // 4. 三元表达式 条件表达式 ?表达式1 :表达式2        // 如果条件表达式为真,则返回表达式1,否则返回表达式2,表达式有返回值         var num = 10;         var result = num > 5 ? '是的' : '不是的'; // 我们知道表达式是有返回值的         console.log(result);          // if (num > 5) {         //     result = '是的';         // } else {         //     result = '不是的';         // }

 

案例:判断是否闰年 (if ...else...)

// 算法:能被4整除且不能整除100的为闰年,或者能够被400整除的就是闰年     <script>         var year = prompt('请您输入年份:');         if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {             alert('您输入的年份是闰年');         } else {             alert('您输入的年份是平年');         }     </script>

 

案例:判断成绩级别 (if ...else if ...else...)

// 思路:从大到小的顺序,否则 就都输出了     <script>         var score = prompt('请您输入分数:');         if (score >= 90) {         alert('宝贝,你是我的骄傲');         } else if (score >= 80) {         alert('宝贝,你已经很出色了');         } else if (score >= 70) {         alert('你要继续加油喽');         } else if (score >= 60) {         alert('孩子,你很危险');         } else {         alert('熊孩子,我不想和你说话,我只想用鞭子和你说话');     </script>

 

案例:数字补0案例 (条件表达式 ? 表达式1 : 表达式2)

// 思路:用户输入一个0-59之间的数字,如果小于10,在这个数字前面补0(加0 拼接)      <script>         var time = prompt('请您输入一个 0 ~ 59 之间的一个数字');         // 三元表达式 表达式 ? 表达式1 :表达式2          var result = time < 10 ? '0' + time : time;          alert(result);     </script>

 

 

5.5 switch分支流程控制

  • switch :开关 转换 , case :小例子 选项

  • 关键字 switch 后面括号内可以是表达式或值, 通常是一个变量,不用数值;

  • 如果表达式与case后面得值 存在匹配全等(===) ,则与该 case 关联的代码块会被执行,并在遇到 break 时停止,整个 switch 语句代码执行结束

  • 如果所有的 case 的值都和表达式的值不匹配,则执行 default 里的代码

  • 注意: 执行case 里面的语句时,如果没有break,则继续执行下一个case,不会退出switch

特点:switch后面的表达式是 固定值,通常是变量,优点是可以直接跳转到特定的case语句;

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

 

案例:查询水果价格 switch()

        // 弹出 prompt 输入框,让用户输入水果名称,把这个值取过来保存到变量中。         // 将这个变量作为 switch 括号里面的表达式。         // case 后面的值写几个不同的水果名称,注意一定要加引号 ,因为必须是全等匹配。         // 弹出不同价格即可。          var fruit = prompt('请您输入查询的水果:');         switch (fruit) {         case '苹果':         alert('苹果的价格是 3.5/斤');         break;         case '榴莲':         alert('榴莲的价格是 35/斤');         break;         default:         alert('没有此水果');     }    

 

5.5 switch 语句和 if else if 语句的区别

  • 一般情况下,它们两个语句可以相互替换

  • switch用于处理case比较确定的情况,如固定值的;进行条件判断后直接执行到程序的条件语句,效率更高;

  • if else更加灵活,常用于范围判断(大于 小于);但if else有几种条件就判断多少次;分支较少时效率较高;

 

6 - 循环

循环的目的:可以重复执行某些代码

JS三种循环结构:

  • for循环:常用于 计数

  • while循环:复杂一点的条件判断,比for灵活

  • do...while循环:比while严谨

三个循环很多情况可以相互转换;

6.1 for循环

重复执行某些代码,通常和计数有关系

    // 1. 语法结构     for (初始化变量; 条件表达式; 操作表达式) {         //循环体     }      //1.初始化变量 就是用 var声明一个普通变量,常用于作为计数器     //2.条件表达式 用来决定每一次循环是否继续执行 终止的条件     //3.操作表达式 每次循环最后执行的代码 常用于计数器变量递增减      for (var i = 1; i <= 100; i++) {         console.log('你好吗');     }     //1.先赋初值 var i = 1 整个循环只执行一次     //2.在执行 i <= 100 条件成立执行循环语句 不成立跳出循环     //3.条件成立的话 接下来执行console.log('')     //4.最后执行i++ i++是单独写的代码 递增  第一轮结束     //5.接着执行 i <= 100 如果满足条件 就去执行循环体 不满足条件退出循环 第二轮

 

for循环执行方式

    <script>         // 1.for循环 重复执行相同代码         // 让用户 控制 输入的次数         var num = prompt('请输入次数');         for (var i = 1; i <= num; i++) {             alert('hello world');             // console.log('hello world');         }          // 2.for循环 重复执行不同的代码 因为我们有计数器变量 i 的存在 i每次循环值都会变化         // 计数器 输出一个人 1~100岁         for (var i = 1; i <= 100; i++) {             console.log('这个人今年' + i + '岁了');         }     </script>

 

案例:有关for循环的算法

    <script>     // 1. 求 1~100 之间的整数累加和 算法:sum = sum + i  5050;            var sum = 0;// 求和变量 初始值为0         for (var i = 1; i <= 100; i++) {             // sum = sum + i;             sum += i;         }         console.log(sum);      // 2. 求1~100间的所有数的平均值 需要一个 sum 和的变量 还需要一个平均值 average 的变量  50.5         var sum = 0;         var average = 0;         for (var i = 1; i <= 100; i++) {             sum = sum + i;             // sum += i;         }         average = sum / 100;         console.log(average);     // 3. 求1~100间所有偶数和奇数的和 需要一个偶数和even 和一个奇数和odd         var even = 0;         var odd = 0;         for (var i = 1; i <= 100; i++) {             if (i % 2 == 0) {                 even = even + i;             } else {                 odd = odd + i;             }         }         console.log('1~100之间的所有偶数和是' + even);         console.log('1~100之间的所有奇数和是' + odd);     </script>

 

案例:求学生成绩案例

    <script>         // 思路:         // 1. 弹出输入框输入总得班级人数(num)         // 2. 依次输入学生成绩并保存(score)         // 3. for循环 弹出的次数与班级总人数之间的关系 i <= num         // 4. 先求总成绩 sum ,之后求平均成绩 average 弹出结果         var num = prompt('请输入班级的总人数');// num 总的班级人数         var sum = 0;         var average = 0;         for (var i = 1; i <= num; i++) {             var score = prompt('请输入第' + i + '个学生成绩');             sum = sum + parseFloat(score);         }         average = sum / num;         alert('班级总成绩是' + sum);         alert('班级的平均分是' + average);     </script>

 

案例:打印五角星

  <script>         //     一行打印五个星星          // console.log('★★★★★');         //     循环打印5次         // for (var i = 1; i <= 5; i++) {         //     console.log('★');         // }          // 1.一行打印五颗星星 追加字符串的方法-是一行打印多少个,不是循环多少次一行一个         // var str = '';          // for (i = 1; i <= 5; i++) {         //     str = str + '★';         // }          // 2.取决于用户输入         var num = prompt('请输入星星的个数');         var str = '';         for (i = 1; i <= num; i++) {             str = str + '★';         }         console.log(str);     </script>

 

 

双重for循环

双重for循环:

    <script>         // 1.语法结构          for (外层的初始化变量; 外层的条件表达式; 外层的操作表达式) {             for (里层的初始化变量; 里层的条件表达式; 里层的操作表达式) {                 执行语句;             }         }         //  内层循环可以看做外层循环的循环体语句         //  外层循环执行一次,内层循环 执行全部         //  总共执行了 i*j 次          for (var i = 1; i <= 3; i++) {             console.log('这是外层循环第' + i + '次');             for (var j = 1; j <= 3; j++) {                 console.log('这是内层循环第' + j + '次');             }         }     </script>

 

案例:打印n行n列五角星

    <script>         var rows = prompt('请你输入行数:');         var cols = prompt('请你输入列数:');         var str = '';         for (var i = 1; i <= rows; i++) { // 外层循环负责 打印i行              for (var j = 1; j <= cols; j++) { // 内层循环负责 一行打印j个                 str = str + '★';             }             // 如果一行打印完毕j个星星就要另起一行 加 n             str = str + 'n'; // 字符串拼接 追加字符串         }         console.log(str);     </script>

 

案例:打印 倒三角

JavaScript基础

    <script>         var str = '';         for (var i = 1; i <= 10; i++) { //外层循环控制行数             for (var j = i; j <= 10; j++) {                  //内层循环打印个数不一样 j=i=1,从1~10打印10个                 str = str + '★';             }             // 如果一行打印完毕j个星星就要另起一行 加 n             str = str + 'n';         }         console.log(str);     </script>

 

案例:打印九九乘法表(正三角)

       // 一共有9行,但是每行的个数不一样,因此需要用到双重 for 循环        // 外层的 for 循环控制行数 i ,循环9次 ,可以打印 9 行          // 内层的 for 循环控制每行公式  j   	  // 核心算法:每一行 公式的个数正好和行数一致, j <= i;       // 每行打印完毕,都需要重新换一行
    <script>         str = '';         for (i = 1; i <= 9; i++) {             for (j = 1; j <= i; j++) {                 // str = str + '★';                 // str += i + 'x' + j + '=' + i * j;                 str += j + 'x' + i + '=' + i * j + 't';                 //为了符合列匹配关系             }             str = str + 'n';         }         console.log(str);    </script>

 

for 循环小结

  • for 循环可以重复执行某些相同代码

  • for 循环可以重复执行些许不同的代码,因为我们有计数器

  • for 循环可以重复执行某些操作,比如算术运算符加法操作

  • 双重 for 循环,外层循环一次,内层 for 循环全部执行

  • for 循环是循环条件和数字直接相关的循环

断点调试:

  • 浏览器中f12打开调试器窗口

  • 单击某条语句设置断点,并刷新浏览器

  • 右上角 步进 进行一步步调试,看程序怎样运行的

 

6.2 while循环

while语句的语法结构如下:

使用 while 循环时一定要注意,它必须要有退出条件,否则会成为死循环

    <script>         // 1. while 循环语法结构 while 当...的时候         // 2.执行思路 当条件表达式为true时 执行循环体 否则 退出循环          while (条件表达式) {              循环体          }                 // 3.代码验证         var num = 1;// 初始化变量 计数器         while (num <= 100) {             console.log('hello');             num++; // 操作表达式 完成计数器的更新 防止死循环 不加限制会变成死循环 一定要有退出条件         }          // 转换写法         for (num = 1; num <= 100; num++) {             console.log('hello');         }     </script>

 

案例:while循环 输出人的年龄

    <script>         // while循环案例         // 1.打印人的一生,从1岁到100岁         var i = 1;         while (i <= 100) {             console.log('这个人今年' + i + '岁了');             i++;         }          // 2.计算1~100之间所有的整数和         var sum = 0;         var j = 1;         while (j <= 100) {             sum = sum + j;             j++;         }         console.log(sum);          // 3.弹出一个提示框,你喜欢我么? 如果输入喜欢,就提示结束,否则 一直询问         var message = prompt('你喜欢我么?');         while (message !== '喜欢') {             message = prompt('你喜欢我么');         }         alert('我也喜欢你啊');     </script>

 

 

6.3 do-while循环

比while更简单一些;

while是先判断后循环;do...while是先执行,后判断,至少执行一次;

    <script>         // 1.语法结构  先循环,在判断,至少执行一次         do {             //循环体         } while (条件判断);          // 2.代码         var i = 1;         do {             console.log('how are you');             i++;         } while (i <= 100)                      do {             var message = prompt('你喜欢我么?');         } while (message !== '喜欢')          alert('我也喜欢你啊');     </script>

 

 

6.4 continue、break

1.continue 关键字用于立即跳出本次循环

继续下一次循环(本次循环体中 continue 之后代码会少执行一次)

案例:吃5个包子,第3个有虫子,就扔掉第3个,继续吃第4个第5个包子,代码实现如下

     for (var i = 1; i <= 5; i++) {          if (i == 3) {              console.log('这个包子有虫子,扔掉');              continue; // 跳出本次循环,跳出的是第3次循环            }           console.log('我正在吃第' + i + '个包子呢');      }      //1. 求 1~100 之间,除了能被7整除之外的 整数和         var sum = 0;         for (var i = 1; i <= 100; i++) {             if (i % 7 == 0) {                 continue;// 退出本次循环 直接跳到 i++             }             sum += i;             console.log(sum);         }     </script>

 

2.break 关键字用于立即跳出整个循环(循环结束)

案例:吃5个包子,吃到第3个发现里面有半个虫子,其余的不吃了,其代码实现如下

  for (var i = 1; i <= 5; i++) {      if (i == 3) {          break; // 直接退出整个for 循环,跳到整个for下面的语句      }      console.log('我正在吃第' + i + '个包子呢');    }

 

 

7 - 数组

为什么需要数组?

普通变量一次只能存一个值;数组(Array)是一组数据的集合,一次可以存多个值;

7.1 数组的概念

数组是指一组数据的集合,其中的每个数据被称作元素,在数组中可以存放任意类型的元素。

7.2 创建数组

JS 中创建数组有两种方式:

  • 利用new 关键字 创建数组(对象)

var 数组名 = new Array() ; var arr = new Array();   // 创建一个新的空数组

 

  • 利用数组字面量创建数组

var  数组名 = []; // 使用数组字面量方式创建带初始值的数组 数组类型不限 var  数组名 = [1,'pink',true];// 数组的初始化

 

7.3 获取数组中的元素

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

数组可以通过索引来访问、设置、修改对应的数组元素,可以通过“数组名[索引]”的形式来获取数组中的元素。

        // 4. 我们数组里面的数据一定用逗号分隔         // 5. 数组里面的数据 比如1,2, 我们称为数组元素         // 6. 获取数组元素  格式 数组名[索引号]  索引号从 0开始          console.log(arr1);         console.log(arr1[1]); // pink老师         console.log(arr1[2]); // true   

 

注意:如果访问时数组没有和索引值对应的元素,则得到的值是undefined

7.4 遍历数组

把数组中的每个元素 从头到尾 都访问一次(类似学生的点名)称为遍历数组;

for循环中的 i 是计数器,当索引号使用,arr[i] 是数组元素 第i个数组元素,索引号从0开始

    <script>         // 1.数组索引 访问数组中某个元素         var arr = ['red', 'green', 'blue'];         console.log(arr[0]);// red          // 2.遍历数组 通过for循环访问数组所有元素         //   因为数组索引号从0开始,所以i必须从0开始 i < 3         //   输出的时候 arr[i] i 计数器 当索引号来用         var arr = ['red', 'green', 'blue'];         for (var i = 0; i < arr.length; i++) {             console.log(arr[i]);         }         // 数组名.length 可以直接获取数组长度 动态监测数组元素的个数         console.log(arr.length);// 此处数组的长度是数组元素的个数,并非索引     </script>

 

案例:求数组里面所有元素的和及平均值

    <script>         // 1.声明一个求和变量 sum         // 2.遍历这个数组,把里面每个数组元素 加到sum 里         // 3.用求和变量 sum 除以数组的长度得到数组的平均值         var arr = [2, 4, 1, 7, 4];         var sum = 0;         var average = 0;         for (i = 0; i < arr.length; i++) {             // sum+=i;// 加的不是计数器,是数组里的元素             sum += arr[i];         }         average = sum / arr.length;         console.log('这组数的和是:' + sum);         console.log('这组数的平均值是:' + average);         console.log(sum, average); // 想要输出多个变量,用逗号分隔即可     </script>

 

案例:求数组 [2,6,1,77,52,25,7] 中的最大值

    <script>         // 1.声明一个求和变量 max 默认最大值可以取数组中的第一个元素         // 2.遍历这个数组,把里面每个数组元素和 max 相比较         // 3.如果这个数组元素大于max 就把这个数组元素存到 max 里面,否则继续下一轮比较。         var arr = [2, 6, 1, 77, 52, 25, 7];         var max = arr[0];// 将数组第一个值赋值给max         for (i = 1; i < arr.length; i++) {             if (arr[i] > max) {                 max = arr[i];             }         }         console.log('该数组里最大的是:' + max);     </script>

 

案例:将数组元素转换为字符串,中间用任意字符相连

        // 将数组 ['red', 'green', 'blue', 'pink'] 转换为字符串,并且用 | 或其他符号分割         // 1.需要一个新变量用于存放转换完的字符串 str。         // 2.遍历原来的数组,分别把里面数据取出来,加到字符串里面。         // 3.同时在后面多加一个分隔符         <script>          var arr = ['red', 'green', 'blue', 'pink'];         var str = '';         var sep = '|';         for (i = 1; i < arr.length; i++) {             str += arr[i] + sep;         }         console.log(str);     </script>

 

注意

  • 此处数组的长度是数组元素的个数 ,不是数组的索引号(下标号)。

  • 当我们数组里面的元素个数发生了变化,这个 length 属性跟着一起变化;数组的length属性可以被修改:

  • 如果设置的length属性值大于数组的元素个数,则会在数组末尾出现空白元素;

  • 如果设置的length属性值小于数组的元素个数,则会把超过该值的数组元素删除

7.5 数组中新增元素

1、通过修改length长度新增数组元素,通过length长度实现数组的扩容

2、通过修改数组索引新增数组元素,追加数组元素

    <script>         // 1.新增数组元素 修改length长度         var arr = ['red', 'green', 'blue'];         console.log(arr.length);         arr.length = 5;// 数组长度修改为5 里面应该有5个元素         console.log(arr);// 后面两个是空的 undefined          // 2.新增数组元素 修改索引号 追加数组元素         var arr1 = ['red', 'green', 'blue'];         arr1[3] = 'pink';         console.log(arr1);         arr1[4] = 'hotpink';         console.log(arr1);         arr1[0] = 'yellow';// 替换原来的数组元素         console.log(arr1);          arr1 = '有点意思';// 不要直接给 数组名赋值 否则里面的数组元素都没有了         console.log(arr1);     </script>

 

 

案例:数组存放0~10个值,循环追加的方式输出

    <script>         var arr = [];// 定义一个空数组         for (var i = 0; i < 10; i++) {// 遍历数组             // arr=i;// 不要直接给数组名赋值 否则以前的元素都没了             arr[i] = i + 1;// i是数组下标 下标为0的数组对应着 第一个数组元素         }         console.log(arr);     </script>

 

案例:筛选数组 筛选数组中大于10的数存入新数组

    <script>         // 方法一         var arr = [1, 2, 3, 4, 5, 6, 7, 8, 19, 10];         var newArr = [];// 声明一个新的数组存放新数据         var j = 0;// 方法1 声明一个新变量         for (var i = 0; i < arr.length; i++) {             if (arr[i] >= 10) {                 // 新数组索引号应该从0开始 依次递增                 newArr[j] = arr[i];                 // 在旧数组里找出大于等于10的元素 依次追加给新数组                 j++;             }         }         console.log(newArr);          // 方法二         var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];         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);     </script>

 

案例:删除数组指定元素,数组去重 删除数组中的0

    // 1、需要一个新数组用于存放筛选之后的数据。     // 2、遍历原来的数组, 把不是 0 的数据添加到新数组里面(此时要注意采用数组名 + 索引的格式接收数据)。     // 3、新数组里面的个数, 用 length 不断累加。     <script>         var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];         var newArray = [];         for (var i = 0; i < arr.length; i++) {             if (arr[i] != 0) {                 newArray[newArray.length] = arr[i];             }         }         console.log(newArray);     </script>

 

案例:翻转数组 将数组中的内容反过来存放

    // 1、声明一个新数组 newArr     // 2、把旧数组索引号第4个取过来(arr.length - 1),给新数组索引号第0个元素 (newArr.length)     // 3、我们采取 递减的方式  i--   // 思路:把 旧数组 的 最后一个元素 取出来给 新数组 作为第一个  (递减)       <script>         var arr = ['red', 'green', 'blue', 'pink', 'purple'];         var newArr = [];         for (var i = arr.length - 1; i >= 0; i--) {             newArr[newArr.length] = arr[i];         }         console.log(newArr);     </script>

 

案例:数组排序 交换相邻两个变量(冒泡排序)

冒泡排序:一种算法,把一系列数据按照一定的顺序排列,依次比较相邻两个元素;

JavaScript基础

    <script>         var arr = [5, 4, 3, 2, 1];         for (var i = 0; i <= arr.length - 1; i++) { // 外层交换趟数 5个元素交换4趟             for (var j = 0; j <= arr.length - i - 1; j++)                  //里层循环 负责每一趟的交换次数             {                 // 内部交换2个变量的值 前一个和后面一个数组元素相比较                 if (arr[j] > arr[j + 1]) {                     var temp = arr[j];                     arr[j] = arr[j + 1];                     arr[j + 1] = temp;                 }             }         }         console.log(arr);     </script>

 

 

8 - 函数

8.1 函数的概念

函数:就是封装了一段可被重复调用执行的代码块

通过此代码块可以实现大量代码的重复使用

8.2 函数的使用

函数使用分为两步: 声明函数 和 调用函数;

     // 1.声明函数  函数名 命名为动词     // (1) function 声明函数的关键字 全部小写      // (2) 函数是做某件事情,函数名一般是动词 sayHi       // (3) 函数不调用自己不执行     function 函数名() {         //函数体代码     }
// 2.调用函数 函数名(); // 通过调用函数名来执行函数体代码 函数不调用 自己不执行 function sayHi() { console.log('hi~~'); } sayHi();

 

注意:声明函数本身并不会执行代码,只有调用函数时才会执行函数体代码。

案例:利用函数封装计算1-100累加和

        // 1.声明函数         function getSum(num1,num2) {             var sum = 0;// 准备一个变量,保存数字和             for (var i = num1; i <= num2; i++) {                 sum += i;// 把每个数值 都累加 到变量中             }             alert(sum);         }         // 2.调用函数         getSum(1,100);

 

8.3 函数的参数

  • 形参:形式上的参数 声明函数时定义 可看做不用声明的变量

  • 实参:实际上的参数 函数调用时传递的 最终实参传递给形参

函数参数的运用:

        // 1.函数声明 声明形参         function 函数名(形参1, 形参2, 形参3...) {             // 函数体         }         // 2.函数调用 调用实参         函数名(实参1, 实参2, 实参3...);           // 声明函数         function getSum(num1, num2) {             console.log(num1 + num2);         }         // 调用函数         getSum(1, 3); // 4 先将实参传递给形参 在执行函数体         getSum(6, 5); // 11

 

函数形参和实参数量不匹配时

参数个数 说明
实参个数等于形参个数 输出正确结果
实参个数多于形参个数 值取到形参个数
实参个数小于形参个数 多的形参定义为undefined,结果NaN
注意:在JavaScript中,形参的默认值是undefined。

案例:函数的执行

// 1.函数可以重复相同的代码     function cook() {         console.log('hello');     }     cook();  // 2.也可以利用函数的参数 实现函数重复不同的代码     function 函数名(形参1,形参2...) { // 声明的小括号里是形参 形式上的              }     函数名(实参1,实参2...);// 函数调用的小括号里是实参 实际的      function cook(aru) { // 形参是接收实参的 aru='hello' 相当于一个不用声明的变量         console.log(aru);     }     cook('hello');// 形参和实参个数尽量相匹配 // 1.利用函数求任意两个数之间的和     function getSum(num1,num2) {         console.log(num1 + num2);     }     getSum(1, 3);     getSum(2, 6);
// 2.利用函数求任意两个数之间的累加和 function getSum(start, end) { var sum = 0; for (var i = start; i <= end; i++) { sum += i; } console.log(sum); } getSum(1, 100);

 

8.4 函数的返回值return

return 语句

函数只是用来做某件事或实现某种功能,最终的结果需要返回给函数的调用者; 只要函数遇到return 就把后面的结果 返回给函数的调用者  函数名()= return + 后面
   // 声明函数     function 函数名(){         ...         return  需要返回的值;     }     // 调用函数     函数名();// 此时调用函数就可以得到函数体内return 后面的值      // 声明函数     function sum(){      ...      return 666;     }     // 调用函数     sum(); // 此时sum = 666,return 语句会把自身后面的值返回给调用者

 

  • 在使用 return 语句时,函数会停止执行,并返回指定的值

  • 如果函数没有 return ,返回的值是 undefined

    // 1.利用函数求任意两个数之和         function getResult(num1,num2) {             return num1 + num2;         }         //getResult();// getResult = num1+num2         console.log(getResult(1,2));      // 2.利用函数求两个数中最大值         function getMax(num1,num2) {             // if (num1 > num2) {             //     return num1;             // } else {             //     return num2;             return num1 > num2 ? num1 : num2;         }         console.log(getMax(1, 3));      // 3.利用函数求数组中的最大值         function getArrMax(arr) { // arr接收一个数组             var max = arr[0];             for (var i = 1; i<=arr.length; i++) {                 if (arr[i] > max) {                     max = arr[i];                 }             }             return max;         }         // getArrMax([1,2,3,4,5]);// 实参是一个数组         // 实际开发中,常用一个变量 来接收 函数的返回结果         var re = getArrMax([1,2,3,4,5]);         console.log(re);

 

return函数注意事项:

// 1.return 终止函数         function getSum(num1, num2) {             return num1 + num2;             alert('这条语句不被执行');//return结束,后面的代码不被执行         }          // 2.return 只能返回一个值         function fn(num1, num2) {             return num1, num2;// return返回的结果是最后一个值 num2         }         console.log(fn(1, 2));          // 3.求任意两个数的 加减乘除结果         function getResult(num1, num2) { // 想要输出多个值return 可以返回数组             return [num1 + num2, num1 - num2, num1 * num2, num1 / num2];         }         var re = getResult(1, 2);         console.log(re);          // 4. 我们的函数如果有return 则返回的是 return 后面的值,如果函数么有 return 则返回 undefined            console.log(fun1()); // 返回 666         function fun2() {          }         console.log(fun2()); // 函数返回的结果是 undefined

 

退出循环

break ,continue ,return 的区别

  • break :结束当前的循环体(如 for、while)

  • continue :跳出本次循环,继续执行下次循环(如 for、while)

  • return :不仅可以退出循环,还能够返回 return 语句中的值,同时还可以结束当前的函数体内的代码

 

8.5 arguments的使用

当不确定有多少个参数传递的时候,可以用 arguments 来获取。

arguments对象中存储了传递的所有实参,是当前函数的一个内置对象,函数独有的;

  <script>         // arguments 的使用  只有函数才有 arguments对象  而且是每个函数都内置好了这个arguments         function fn() {             // console.log(arguments); // 里面存储了所有传递过来的实参  arguments = [1,2,3]             // console.log(arguments.length);             // console.log(arguments[2]);             // 我们可以按照数组的方式遍历arguments             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() 等等     </script>

 

注意:在函数内部使用该对象,用此对象获取函数调用时传的实参。

案例:利用函数求任意个数的最大值

 <script>         // 利用函数求任意个数的最大值         function getMax() { // arguments = [1,2,3]             var max = arguments[0];             for (var i = 1; i < arguments.length; i++) {                 if (arguments[i] > max) {                     max = arguments[i];                 }             }             return max;         }         console.log(getMax(1, 2, 3));         console.log(getMax(1, 2, 3, 4, 5));         console.log(getMax(11, 2, 34, 444, 5, 100));     </script>

 

案例:

<script>         // 1.利用函数封装方法 翻转任意数组 reverse 翻转         function reverse(arr) {             var newArr = [];             for (var i = arr.length - 1; i >= 0; i--) {                 newArr[newArr.length] = arr[i];             }             return newArr;         }         var arr1 = reverse([1, 2, 3, 4, 5]);         console.log(arr1);          // 2.利用函数封装的方法,对数组排序--冒泡排序         function sort(arr) {             for (var i = 0; i < arr.length - 1; i++) {                 for (var j = 0; j < arr.length - i - j; j++) {                     if (arr[j] > arr[j + 1]) {                         var temp = arr[j];                         arr[j] = arr[j + 1];                         arr[j + 1] = temp;                     }                 }             }             return arr;         }         var arr2 = sort([1, 2, 3, 4, 5]);         console.log(arr2);          // 3.判断闰年         function isRunYear(year) {             // 如果是闰年返回 true 否则返回false             var flag = flase;             if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {                 flag = true;             }             return flag;         }         console.log(isRunYear(2000));         console.log(isRunYear(1999));     </script>

 

函数之间可以相互调用:

函数内部可以调用另一个函数;

    <script>         // 函数是可以相互调用的         // function fn1() {         //     console.log(11);         //     fn2(); // 在fn1 函数里面调用了 fn2 函数         // }         // fn1();          // function fn2() {         //     console.log(22);          // }         </script>

 

在同一作用域代码中,函数名即代表封装的操作,使用函数名加括号即可以将封装的操作执行。

案例:输出当年年的2月份天数

<script>         // 用户输入年份,输出当年年的2月份天数         function backDay() {             var year = prompt('请您输入年份');             if (isRunYear(year)) {                 alert('当前年份是闰年 2月份有29天');             } else {                 alert('当前年份是平年 2月份有28天');             }         }         backDay();         // 判断是否为闰年的函数         function isRunYear(year) {             var flag = false;             if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {                 flag = true;             }             return flag;         }     </script>

 

 

8.6 函数的两种声明方式

1、自定义函数方式(命名函数)

利用函数关键字 function 自定义函数方式

    // 声明定义方式     function fn() {...}     // 调用 调用函数的代码既可以放到声明函数的前面,也可以放在声明函数的后面     fn();

 

2、函数表达式方式(匿名函数)

        // var 变量名 = function () { }         var fun = function () {             console.log('我是函数表达式');         }         fun();

 

  • fun是变量名 不是函数名

  • 函数表达式 声明方式和 声明变量差不多,只不过变量里存的是值 而 函数表达式里存的是函数

  • 函数调用的代码必须写到函数体后面

  • 函数表达式也可以进行传递参数

 

9 - 作用域

9.1 作用域概述

作用域:变量能够起作用和效果的 某个范围 目的:为了提高程序的可靠性 更重要的作用是减少命名冲突 全局作用域和局部作用域命名不冲突

9.2 作用域的分类

JavaScript(es6前)中的作用域有两种:

  • 全局作用域

  • 局部作用域(函数作用域)

1.全局作用域

	作用于所有代码执行的环境(整个script标签内部)或独立的js文件,或者var声明的。 	如果在函数内部没有声明,直接赋值的变量也属于全局变量,一般不用console.log(); 	全局变量只有浏览器关闭时才会结束,占资源;

2.局部作用域

	作用于函数内的代码环境,就是局部作用域(函数作用域)  	在函数内部的作用域,这个代码名字只在函数内部起作用  	function fn { 局部作用域 }; 	函数的形参也可以看做局部变量;局部变量在代码执行完毕后就结束;

3.es6新增块级作用域

js在es6中新增块级作用域,块作用域由 { } 包括 如if{} for{}等 在其他编程语言中(如 java、c#等),在 if 语句、循环语句中创建的变量,仅仅只能在当前 if 语句、当前循环语句中使用
  • java有块级作用域:

if(true){   int num = 123;   system.out.print(num);  // 123 } system.out.print(num);    // 报错

 

以上java代码会报错,是因为代码中 { } 即一块作用域,其中声明的变量 num,在 “{ }” 之外不能使用;

而与之类似的JavaScript代码,则不会报错。

  • js中没有块级作用域(在ES6之前)

if(true){   var num = 123;   console.log(123); //123 } console.log(123);   //123

 

 

9.3 - 变量的作用域

在JavaScript中,根据作用域的不同,变量可以分为两种:

  • 全局变量

  • 局部变量

1.全局变量

在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。 注意 如果在函数内部 没有声明直接赋值的变量也属于全局变量
  • 全局变量在代码的任何位置都可以使用

  • 在全局作用域下 var 声明的变量 是全局变量

  • 特殊情况下,在函数内不使用 var 声明的变量也是全局变量(不建议使用)

2.局部变量

在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量) 注意: 函数的形参也可以看做是局部变量
  • 局部变量只能在该函数内部使用

  • 在函数内部 var 声明的变量是局部变量

  • 函数的形参实际上就是局部变量

3.全局变量和局部变量的区别

  • 全局变量:在任何一个地方都可以使用,只有在浏览器关闭时才会被销毁,因此比较占内存;

  • 局部变量:只在函数内部使用,当其所在的代码块被执行时,会被初始化;当代码块运行结束后,就会被销毁,因此更节省内存空间;

 

9.4 - 作用域链

根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称作作用域链。

案例分析1:
function f1() { // 外部函数     var num = 123;     function f2() {         console.log( num );// 站在目标出发,一层一层的往外查找     }     f2(); // 内部函数 } var num = 456; f1();

 

案例:

作用域链:采取就近原则的方式来查找变量最终的值 var a = 1; function fn1() {     var a = 2;     var b = '22';     fn2();     function fn2() {         var a = 3;         fn3();         function fn3() {             var a = 4;             console.log(a); //a的值 ?             console.log(b); //b的值 ?         }     } } fn1();            // 作用域链         var num = 10;         function fn() {             var num = 20;// 根据作用域链机制 先调用上一级的             function fun() {                 console.log(num);// 内部函数可以调用外部函数 属于子集             }         }          function f1() {             var num = 123;             function f2() {                 console.log(num);// 站在目标出发一层层往外查找 num=123 近             }             f2();         }         var num = 456;         f1();

 

 

预解析

1.1 预解析的相关概念

JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的。  JavaScript 解析器在运行 JavaScript 代码的时候分为两步:预解析和代码执行。  预解析:  js引擎会把js里所有的 var 还有 function 提升到当前作用域的最前面,预解析也叫做变量、函数提升。 代码执行: 按照代码抒写的顺序从上到下执行

注意:预解析会把变量和函数的声明在代码执行之前执行完成。

 

1.2 预解析分类

预解析分为变量预解析(变量提升) 和 函数预解析(函数提升)  变量提升:变量的声明会被提升到当前作用域的最上面,变量的 赋值 不会提升。 函数提升:函数的声明会被提升到当前作用域的最上面,但是不会调用函数。

预解析分为变量预解析(变量提升) 和 函数预解析(函数提升)

 // 1.未声明 直接调用  报错         console.log(num);          // 2.先调用 后声明  undefined 坑1         // 变量预解析(变量提升)声明提升,赋值不提         console.log(num);         var num = 10;         // 预解析后相当于:         var num; // 只声明 未赋值 undefine         console.log(num);         num = 10;          // 3.利用关键字定义函数 函数先调用后声明 或 先声明后调用 无影响         // 函数预解析(函数提升)         fn();         function fn() {             console.log(11);         }         // 预解析后相当于:把函数提升到最前面          // 4.利用函数表达式定义函数 只能先声明后调用 否则会报错         // 解决函数表达式声明调用问题         var fun = function () {             console.log(22);         }         // 预解析后相当于:         var fun;         fun();         fun = function() {             console.log(22);         } 

 

案例:

// 1.         var num = 10;         fun();         function fun() {             console.log(num);             var num = 20;         }     // 函数提升后 相当于以下代码   输出undefined         var num;         function fun() {             var num; // 只声明 未赋值 undefined             console.log(num);             num = 20;         }         num = 10;         fun();      // 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 = b = c = 9;             // 相当于 var a = 9;b = 9;c = 9;//b c 直接赋值 没有var声明 相当于全局变量             // 集体声明应该是 var a  =9,b = 9,c = 9;             var a;             a = b = c = 9;             console.log(c);// 9             console.log(b);// 9             console.log(a);// 报错 a当局部变量看 只声明         }

 

 

对象

1.1 对象的相关概念

1、什么是对象?

对象是指具体的事物,如字符串、数值、数组函数等;万物皆对象;

对象是由属性和方法组成的:

  • 属性:事物的特征,在对象中用属性来表示(常用名词)

  • 方法:事物的行为,在对象中用方法来表示(常用动词)

2、为什么需要对象?

保存一个值用变量;保存多个值,可以使用数组;保存一个人的完整信息可以用对象(相当于C语言结构体);

  • 对象可以让代码结构更清晰

  • 对象属于复杂数据类型object。

  • 本质:对象就是一组无序的相关属性和方法的集合。

  • 构造函数泛指某一大类,比如苹果,不管是红色苹果还是绿色苹果,都统称为苹果。

  • 对象实例特指一个事物,比如这个苹果、正在给你们讲课的pink老师等。

  • for...in 语句用于对对象的属性进行循环操作。

 

变量、属性、函数、方法的区别

相同点 他们都是用来存储数据的;

  • 变量:单独声明赋值,使用的时候直接写变量名 单独存在

  • 属性:对象里面的变量称为属性,不需要声明,用来描述对象特征 对象.属性;

    属性是对象的一部分,而变量不是对象的一部分,变量是单独存储数据的容器

  • 函数:单独存在的,通过“函数名()”的方式就可以调用

  • 方法:对象里面的函数称为方法,方法不需要声明,使用“对象.方法名()”的方式就可以调用;

    方法是对象的一部分,函数是单独封装操作的容器

    函数和方法的相同点 都是实现某种功能 做某件事

// 变量和属性的相同点 都是用来存储数据的         // 1.变量 单独声明并赋值 使用的时候直接写变量名 单独存在         var name = 10;         // 2.属性 在对象里不需要声明 调用的时候必须是 对象.属性         var obj = {             age: 18         }         console.log(obj.age);          // 函数和方法的相同点 都是实现某种功能 做某件事         // 3.函数是单独声明 并且调用的 函数名() 单独存在的         function fn() {          }         // 4.方法 在对象里面 调用的时候 对象.方法()         var obj = {             age: 18             fn: function () {              }         }

 

小括号()优先级;中括号[ ]数组;花括号{ }对象

1.2 创建对象的三种方式

  • 利用字面量创建对象;

  • 利用new object创建对象;

  • 利用构造函数创建对象;

1、利用字面量创建对象

    <script>         // 1.利用 字面量 创建对象 利用键值对形式 属性名 :属性值 ,中间 逗号 隔开                      var obj = {};         var obj = {             uname: '张三疯', // 里面的属性或方法采取键值对的形式 键 属性名 :值 属性值             age: '18',       // 多个属性或者方法中间用逗号隔开             sex: '男',             sayHi: function () {    // 方法冒号后面跟的是一个匿名函数 function                 console.log('hi~');             }         }          // 2.调用对象                  console.log(obj.name); // 调用对象的属性 采用 对象名.属性名 理解为 的         console.log(obj['age']); // 调用属性还有一种方法 对象名['属性名']             obj.sayHi(); // 调用对象的方法 sayHi  对象名.方法名()     </script>

 

2、利用 new Object 创建对象

        // 利用 new Object 创建对象 利用 等号 = 赋值的方法 添加对象的属性和方法         var obj = new Object();// 创建一个空的对象         obj.uname = '张三疯'; // 利用 等号 = 赋值的方法 添加对象的属性和方法         obj.age = 18;        // 每个属性和方法之间用分号结束         obj.sayHi = function () {             console.log('hi~');         }         console.log(obj.uname);         console.log(obj['sex']);         obj.sayHi();   

 

3、利用构造函数创建对象

因为前面两种方式一次只能创建一个对象;

  • 构造函数就是把 我们对象里一些相同的属性和方法抽象出来封装到函数中;

  • 构造函数用于创建某一类函数,首字母要大写;与关键字 new 一起使用;

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

    <script>         // 利用构造函数创建对象         // 需要创建四大天王的对象 相同的属性: 名字 年龄 性别 相同的方法:唱歌         function 构造函数名() {             this.属性 = 值;             this.方法 = function () { }         }         new 构造函数名(); // 1.构造函数 泛指一大类         function Star(uname, age, sex) { // 构造函数首字母大写             this.name = uname;             this.age = age;             this.sex = sex;             this.sing = function (sang) {                 console.log(sang);             }         } // 2.对象 特指某一个 对象的实例化         var ldh = new Star('刘德华', 18, '男');         // 多了个 this 和new 不需要 return 就可以返回结果         // console.log(typeof ldf); // object         console.log(ldh.name);         console.log(ldh['sex']);         ldh.sing('冰雨');     </script>         // 1. 构造函数名字首字母要大写         // 2. 我们构造函数不需要return 就可以返回结果         // 3. 我们调用构造函数 必须使用 new         // 4. 我们只要new Star() 调用函数就创建一个对象 ldh  {}         // 5. 我们的属性和方法前面必须添加 this

 

 

构造函数和对象的区别:

  • 构造函数 如明星 泛指一大类 类似于java语言中的类

  • 对象 特指 是一个具体的事物

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

 

new关键字:

  • new 构造函数可以 在内存中创建了一个空的新对象;

  • 让this就会指向刚才的空对象

  • 执行构造函数里面的代码 给这个空对象添加属性和方法

  • 返回这个新对象(所以不需return)

var ldh = new Star('刘德华', 18, '男');

 

1.3 遍历对象

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

for (变量 in 对象名字) {     // 在此执行代码 }

 

变量通常用 k 或者 key

         // for (变量 in 对象) { }         for (var k in obj) {             console.log(k);// k变量输出 得到的是 属性名             console.log( obj[k] );// 得到的是 属性值         }

 

 

1.4 内置对象

1.41内置对象的概念

  • JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象

  • 前面两种对象是JS 基础 内容,属于 ECMAScript; 第三个浏览器对象属于我们 JS 独有的, 我们JS API 讲解

  • 内置对象就是指 JS 语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)

  • 内置对象最大的优点就是帮助我们快速开发

  • JavaScript 提供了多个内置对象:Math、 Date 、Array、String等

 

1.42 MDN文档查阅!

查找文档:学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过MDN/W3C来查询。 Mozilla 开发者网络(MDN)提供了有关开放网络技术(Open Web)的信息,包括 HTML、CSS 和万维网及 HTML5 应用的 API。 MDN:https://developer.mozilla.org/zh-CN/

 

Math对象

1.Math 概述

Math 对象不是构造函数,所以我们不需要new 来调用 而是直接使用里面的属性和方法即可,它具有数学常数和函数的属性和方法。跟数学相关的运算(求绝对值,取整、最大值等)可以使用 Math 中的成员。

属性、方法名 功能
Math.PI 圆周率
Math.floor() 向下取整
Math.ceil() 向上取整
Math.round() 四舍五入版 就近取整 注意 -3.5 结果是 -3
Math.abs() 绝对值
Math.max()/Math.min() 求最大和最小值
Math.random() 获取范围在[0,1)内的随机值

注意:上面的方法使用时必须带括号

        // Math 三个取整的方式         // (1) Math.floor() 地板 向下取整 往小了取值         console.log(Math.floor(1.9));// 1         // (2) Math.ceil()  天花板 向上取整 往大了取值         console.log(Math.ceil(1.1));// 2         // (3) Math.round() 四舍五入 其他数字都是四舍五入 5往大了取         console.log(Math.round(1.1));// 1         console.log(Math.round(1.5));// 2         console.log(Math.round(-1.1));// -1         console.log(Math.round(-1.5));// -1                    // Math 数学对象 不是一个构造函数,不需要 new 调用 直接使用里面的属性和方法         console.log(Math.PI);// 一个属性 圆周率         console.log(Math.abs(-1));// 1 绝对值         console.log(Math.max(1, 33, 99));// 99         console.log(Math.max('pink'));// NaN         console.log(Math.max());//          // 利用对象封装自己的数学对象 里面有PI最大值和最小值         var myMath = {             PI: 3.1415926,             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(1, 5, 9));         console.log(myMath.min(1, 5, 9));

 

2. 随机数方法 random()

random() 方法可以随机返回一个小数,其取值范围是 [0,1),左闭右开 0 <= x < 1 ;

得到一个两数之间的随机整数,包括两个数在内。

获取指定范围内的随机整数算法

function getRandom(min, max) {   return Math.floor(Math.random() * (max - min + 1)) + min;  }

 

案例:Math对象随机数方法

        // 想要得到两个数之间的随机整数 并且包括这2个数         // 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));         // 随机点名         var arr = ['张三', '张三疯', '张三疯子', '李四', '李思思'];         // console.log(arr[0]);         console.log(arr[getRandom(0, arr.length - 1)]);

 

案例:猜数字游戏

程序随机生成一个 1~ 10 之间的数字,并让用户输入一个数字,

案例分析

① 随机生成一个1~10 的整数 我们需要用到 Math.random() 方法。

② 需要一直猜到正确为止,所以一直循环。

③ 用while 循环合适更简单。

④ 核心算法:使用 if else if 多分支语句来判断大于、小于、等于。

    <script>         function getRandom(min, max) {             return Math.floor(Math.random() * (max - min + 1)) + min;         }          var random = getRandom(1, 10);         while (true) { // 死循环             var num = prompt('你来猜?输入1~10之间的一个数字');             if (num > random) {                 alert('你猜大了');             } else if (num < random) {                 alert('你猜小了');             } else {                 alert('你猜对了');                 break;// 退出整个循环 一定要写结束循环条件             }         }     </script>

 

如果限定猜的次数,可以在条件判断改为for

日期对象

Date 对象和 Math 对象不一样,  Date是一个构造函数,使用时需要实例化后(new)才能使用其中具体方法和属性 Date 实例用来处理日期和时间

1.使用Date实例化日期对象

  • 获取当前时间必须实例化:

var now = new Date(); console.log(now);

 

  • 获取指定时间的日期对象

var future = new Date('2019/5/1'); 如果Date()不写参数,就返回当前时间 如果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-1 8:8:8'         var date1 = new Date(2019, 10, 1);         console.log(date1);// 返回的是 11月 不是 10月         var date1 = new Date('2019-10-1 8:8:8');         console.log(date2);

 

2.使用Date实例的方法和属性 日期格式化

方法名 说明 代码
getFullYear() 获取当年 getFullYear()
getMonth() 获取当月(0-11) getMonth()
getDate() 获取当前日期 getDate()
getDay() 获取星期几(周日为0) getDay()
getHours() 获取当前小时 getHours()
getMinutes() 获取当前分钟 getMinutes()
getSeconds() 获取当前秒钟 getSeconds()

 

案例: 输出当前日期

请写出这个格式的日期:2019年5月1日 星期三

    <script>         // 格式化日期 年月日 手动更改显示         var date = new Date();         console.log(date.getFullYear());// 返回当前日期的年 2019         console.log(date.getMonth() + 1); // 月份 返回的月份小1个月 月份写时加1         console.log(date.getDate()); // 返回的是 几号         console.log(date.getDay()); // 3 周日返回的是0         // 写一个 2019年 5月 1日 星期三         var year = date.getFullYear();         var month = date.getMonth();         var dates = date.getDate();         var arr = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];         var day = date.getDay();         console.log('今天是:' + year + '年' + month + '月' + dates + '日' + arr[day]);     </script>

 

案例: 输出当前时间

写一个函数,格式化日期对象,成为 HH:mm:ss 的形式 比如 00:10:45

    <script>         // 格式化日期 时分秒         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());     </script>

 

 

3.通过Date实例获取总毫米数

总毫秒数的含义:基于1970年1月1日(世界标准时间)起的毫秒数

毫秒数也叫时间戳,永远不会重复;

案例:获取总毫秒数

    <script>         // 获得 Date总的毫秒数 不是当前时间的毫秒数 而是距离1970年1月1日                var date = new Date();// 实例化Date对象         // 1. 通过 valueOf()  getTime() 用于获取对象的原始值         console.log(date.valueOf());// 距离 1970 过了多少毫秒         console.log(date.getTime());          // 2. 简单的写法(常用)         var date1 = +new Date();// +new Date() 返回的是总毫秒数         console.log(date1);          // 3. HTML5新增的的方法,有兼容性问题         console.log(Date.now());     </script>

 

案例:倒计时效果

案例分析

① 核心算法:输入的时间减去现在的时间就是剩余的时间,即倒计时 ,但是不能拿着时分秒相减,比如 05 分减去25分,结果会是负数的。

② 用时间戳(毫秒)来做。用户输入时间总的毫秒数减去现在时间的总的毫秒数,得到的就是剩余时间的毫秒数。

③ 把剩余时间总的毫秒数转换为天、时、分、秒 (时间戳转换为时分秒)

转换公式如下:

 d = parseInt(总秒数/ 60/60 /24); // 计算天数

 h = parseInt(总秒数/ 60/60 %24) // 计算小时

 m = parseInt(总秒数 /60 %60 ); // 计算分数

 s = parseInt(总秒数%60); // 计算当前秒数

    <script>         function countDown(time) {             var nowTime = +new Date();// 返回的是当前时间的总毫秒数             var inputTime = +new Date(time);// 返回的是用户输入事件的总毫秒数             var times = (inputTime - nowTime) / 1000; // times是剩余时间总的秒数 1s=1000ms             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('2019-5-1 18:00:00'));         var date = new Date();         console.log(date);     </script>

 

 

数组对象

1.创建数组的两种方式

  • 字面量方式

       var arr = [1, 2, 3];         console.log(arr[0]);

     

  • 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       console.log(arr1);

     

    注意:上面代码中arr创建出的是一个空数组,如果需要使用构造函数Array创建非空数组,可以在创建数组时传入参数

    参数传递规则如下:

    • 如果只传入一个参数,则参数规定了数组的长度

    • 如果传入了多个参数,则参数称为数组的元素

2.检测是否为数组

  • instanceof 运算符

    instanceof 可以判断一个对象是否是某个构造函数的实例

    var arr = [1, 23]; var obj = {}; console.log(arr instanceof Array); // true arr是数组 console.log(obj instanceof Array); // false obj是对象

     

  • Array.isArray()

    Array.isArray()用于判断一个对象是否为数组,isArray() 是 HTML5 中新增的方法 ie9以上不支持

    var arr = [1, 23]; var obj = {}; console.log(Array.isArray(arr));   // true console.log(Array.isArray(obj));   // false

     

翻转数组:

  // 翻转数组         function reverse(arr) {             // if (arr instanceof Array) {             if (Array.isArray(arr)) {                 var newArr = [];                 for (var i = arr.length - 1; i >= 0; i--) {                     newArr[newArr.length] = arr[i];                  }                 return newArr;             } else {                 return 'error 这个参数要求必须是数组格式 [1,2,3]'             }         }         console.log(reverse([1, 2, 3]));         console.log(reverse(1, 2, 3));

 

3.添加删除数组元素的方法

数组中有进行增加、删除元素的方法,部分方法如下表

方法名 说明 返回值
push(参数1...) 末尾添加一个或多个元素,注意修改原数组 并返回新的长度
pop() 删除数组最后一个元素,把数组长度减1 无参数、修改原数组 返回他删除的元素的值
unshift(参数1...) 向数组的开头添加一个或多个元素,注意修改原数组 并返回新的长度
shift() 删除数组的第一个元素,数组长度减1无参数,修改原数组 并返回第一个元素得值

注意:push、unshift为增加元素方法;pop、shift为删除元素的方法

案例:添加删除数组元素

   <script>         // 添加删除数组元素方法         // 1. push() 在我们数组的末尾 添加一个或者多个数组元素   push  推         var arr = [1, 2, 3];         // arr.push(4, 'pink');         console.log(arr.push(4, 'pink'));          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() 它可以删除数组的最后一个元素           console.log(arr.pop());         console.log(arr);         // (1) pop是可以删除数组的最后一个元素 记住一次只能删除一个元素         // (2) pop() 没有参数         // (3) pop完毕之后,返回的结果是 删除的那个元素          // (4) 原数组也会发生变化         // 4. shift() 它可以删除数组的第一个元素           console.log(arr.shift());         console.log(arr);         // (1) shift是可以删除数组的第一个元素 记住一次只能删除一个元素         // (2) shift() 没有参数         // (3) shift完毕之后,返回的结果是 删除的那个元素          // (4) 原数组也会发生变化     </script> </head>

 

案例: 筛选数组

有一个包含工资的数组[1500, 1200, 2000, 2100, 1800],要求把数组中工资超过2000的删除,剩余的放到新数组里面

    var arr = [1500, 1200, 2000, 2100, 1800];     var newArr = [];     for (var i = 0; i < arr.length; i++) {         if (arr[i] < 2000) {         // newArr[newArr.length] = arr[i];          newArr.push(arr[i]);          }      }     console.log(newArr);

 

 

4.数组排序

数组中有对数组本身排序的方法,部分方法如下表

方法名 说明 是否修改原数组
reverse() 颠倒数组中元素的熟悉怒,无参数 改变原来数组 返回新数组
sort() 对数组的元素进行排序 改变原数组 返回新数组

 

注意:sort方法需要传入参数来设置升序、降序排序

  • 如果传入“function(a,b){ return a-b;}”,则为升序

  • 如果传入“function(a,b){ return b-a;}”,则为降序

        // 数组排序         // 1. 翻转数组         var arr = ['pink', 'red', 'blue'];         arr.reverse();         console.log(arr);          // 2. 数组排序(冒泡排序)         var arr1 = [17, 4, 71, 6, 9];         // arr1.sort();// 只能对单位数字排序         arr1.sort(function (a, b) {             return a - b;// 按照升序排列             return b - a;// 按照降序排序         });         console.log(arr1);

 

 

5.数组索引方法

数组中有获取数组指定元素索引值的方法,部分方法如下表

方法名 说明 返回值
indexOf() 数组中查找给定元素的第一个索引 存在返回索引,不存在,返回-1
lastIndexOf() 在数组中的最后一个索引 存在返回索引,不存在,返回-1

获取数组指定元素索引值

    <script>         // 返回数组元素索引号方法  indexOf(数组元素)  作用就是返回该数组元素的索引号 从前面开始查找         // 它只返回第一个满足条件的索引号          // 它如果在该数组里面找不到元素,则返回的是 -1           // var arr = ['red', 'green', 'blue', 'pink', 'blue'];         var arr = ['red', 'green', 'pink'];         console.log(arr.indexOf('blue'));         // 返回数组元素索引号方法  lastIndexOf(数组元素)  作用就是返回该数组元素的索引号 从后面开始查找         var arr = ['red', 'green', 'blue', 'pink', 'blue'];          console.log(arr.lastIndexOf('blue')); // 4     </script>

 

案例: 数组去重(重点案例)

有一个数组[‘c’, ‘a’, ‘z’, ‘a’, ‘x’, ‘a’, ‘x’, ‘c’, ‘b’],要求去除数组中重复的元素

案例分析

① 目标:把旧数组里面不重复的元素选取出来放到新数组中,重复的元素只保留一个,放到新数组中去重。

② 核心算法:我们遍历旧数组,然后拿着旧数组元素去查询新数组,如果该元素在新数组里面没有出现过,我们就添加,否则不添加。

③ 我们怎么知道该元素没有存在? 利用 新数组.indexOf(数组元素) 如果返回时 -1 就说明 新数组里面没有该元素

旧数组['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b']

新数组 [ ]

    <script>         // 数组去重 ['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'] 要求去除数组中重复的元素。         // 1.目标: 把旧数组里面不重复的元素选取出来放到新数组中, 重复的元素只保留一个, 放到新数组中去重。         // 2.核心算法: 我们遍历旧数组, 然后拿着旧数组元素去查询新数组, 如果该元素在新数组里面没有出现过, 我们就添加, 否则不添加。         // 3.我们怎么知道该元素没有存在? 利用 新数组.indexOf(数组元素) 如果返回时 - 1 就说明 新数组里面没有改元素         // 封装一个 去重的函数 unique 独一无二的
        function unique(arr) {             var newArr = [];             for (var i = 0; i < arr.length; i++) {                 if (newArr.indexOf(arr[i]) === -1) {                     newArr.push(arr[i]);                 }             }             return newArr;         }         // var demo = unique(['c', 'a', 'z', 'a', 'x', 'a', 'x', 'c', 'b'])         var demo = unique(['blue', 'green', 'blue'])         console.log(demo);     </script>

 

 

6.数组转换为字符串

数组中有把数组转化为字符串的方法,部分方法如下表

方法名 说明 返回值
toString() 把数组转换成字符串 逗号分割每一项 返回一个字符串
join('分隔符') 方法用于把数组中的所有元素转换为一个字符串 返回一个字符串

注意:join方法如果不传入参数,则按照 “ , ”拼接元素

        // 数组转换成字符串         // 1. toString()          var arr = [1, 2, 3];         console.log(arr.toString());// 1,2,3         // 2. join(分隔符)         var arrr1 = ['green', 'blue', 'pink'];         console.log(arr1.join());// green,blue,pink         console.log(arr1.join('-'));// green-blue-pink         console.log(arr1.join('&'));// green&blue&pink

 

 

其他方法

  • 数组中还有其他操作方法,同学们可以在课下自行查阅学习

  • slice() 和 splice() 目的基本相同,建议同学们重点看下 splice()

方法名 说明 返回值
concat() 连接两个或多个数组 不影响原数组 返回一个新的数组
slice() 数组截取 slice(begin,end) 返回被截取项目的新数组
splice() 数组删除splice(第几个开始,要删除个数) 返回被删除项目的新数组 影响原数组

 

字符串对象

1.基本包装类型

为了方便操作基本数据类型,JavaScript 还提供了三个特殊的引用类型:String、Number和 Boolean。

基本包装类型就是把 简单数据类型 包装成为 复杂数据类型,这样基本数据类型就有了属性和方法。

// 下面代码有什么问题? var str = 'andy'; console.log(str.length);

 

按道理简单数据类型是没有属性和方法的,而对象才有属性和方法,但上面代码却可以执行,这是因为js 会把基本数据类型包装为复杂数据类型,其执行过程如下 :

    // 对象 才有 属性和方法   复杂数据类型才有 属性和方法      // 简单数据类型为什么会有length 属性呢?      // 基本包装类型:  就是把简单数据类型 包装成为了 复杂数据类型  // 1. 生成临时变量,把简单类型包装为复杂数据类型 var temp = new String('andy'); // 2. 赋值给我们声明的字符变量 str = temp; // 3. 销毁临时变量 temp = null;

 

2.字符串的不可变

	指的是里面的值不可变,虽然看上去可以改变内容,但只是地址变了,在内存中新开辟了一个内存空间。 原来的值还是有的; 	当重新给字符串变量赋值的时候,变量之前保存的字符串不会被修改,依然在内存中重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变。 	

由于字符串的不可变,在大量拼接字符串的时候会有效率问题

var str = 'abc'; str = 'hello'; // 当重新给 str 赋值的时候,常量'abc'不会被修改,依然在内存中 // 重新给字符串赋值,会重新在内存中开辟空间,这个特点就是字符串的不可变 // 由于字符串的不可变,在大量拼接字符串的时候会有效率问题 var str = ''; for (var i = 0; i < 100000; i++) {  str += i; } console.log(str); // 这个结果需要花费大量时间来显示,因为需要不断的开辟新的空间

3.根据字符返回位置

字符串的所有方法,都不会修改字符本身(字符串是可变的),操作完成后会发挥成以个新的字符串;

字符串通过基本包装类型可以调用部分方法来操作字符串,以下是返回指定字符的位置的方法:

方法名 说明
indexOf('要查找的字符',开始的位置) 返回指定内容在元字符串中的位置,如果找不到返回-1,开始的位置是index索引号
lastIndexOf() 从后往前找,值找第一个匹配的

 

 // 字符串对象 根据字符返回位置 str.indexOf('要查找的字符',[起始位置])         var str = '改革春风吹满地,春天来了';         console.log(str.indexOf('春'));// 2         console.log(str.indexOf('春', 3));// 从索引号是 3的位置开始往后查找 8

 

案例:返回字符位置

查找字符串"abcoefoxyozzopp"中所有o出现的位置以及次数

① 核心算法:先查找第一个o出现的位置

② 然后 只要indexOf 返回的结果不是 -1 就继续往后查找

③ 因为indexOf 只能查找到第一个,所以后面的查找,利用第二个参数,当前索引加1,从而继续查找

    <script>         var str = "abcoefoxyozzopp";         var index = str.indexOf('o'); // 从第一个o开始查找,返回 索引号 3         var num = 0;         // console.log(idnex);         while (index !== -1) {             console.log(index);             num++; // 开始寻找第二个 o             index = str.indexOf('o', index + 1);         }         console.log('o出现的次数是:' + num);     </script>

 

 

4.根据位置返回字符

字符串通过基本包装类型可以调用部分方法来操作字符串,以下是根据位置返回指定位置上的字符:

方法名 说明 使用
charAt(index) 返回指定位置的字符(index字符串的索引号) str.charAt(0)
charCodeAt(index) 获取指定位置处字符的ASII码(index索引号) str.charCodeAt(0)
str[index] 获取指定位置处字符 html/ie8+支持

 

在上述方法中,charCodeAt方法返回的是指定位置上字符对应的ASCII码,ASCII码对照表如下:

        // 根据位置返回字符         // 1. charAt(index) 根据位置返回字符         var str = 'andy';         console.log(str.charAt(3));// y         // 遍历所有字符         for (var i = 0; i < str.length; i++) {             console.log(str.charAt(i));         }         // 2. charCodeAt(index) 反应相应索引号的字符ASII值 目的:判断用户按下了哪个键         console.log(str.charCodeAt(0));//97         // 2. str[index] H5 新增的         console.log(str[0]); // a

 

案例:返回字符位

统计出现最多的字符和次数

判断一个字符串 'abcoefoxyozzopp' 中出现次数最多的字符,并统计其次数

1.核心算法:利用 charAt() 遍历这个字符串

2.把每个字符都存储给对象, 如果对象没有该属性,就为1,如果存在了就 +1

3.遍历对象,得到最大值和该字符

注意:在遍历的过程中,把字符串中的每个字符作为对象的属性存储在对象总,对应的属性值是该字符出现的次数

    <script>         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>     <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>

 

5.字符串操作方法

字符串通过基本包装类型可以调用部分方法来操作字符串,以下是部分操作方法:

方法名 说明
concat(str1,str2,str3...) 用于连接两个或多个字符串,拼接字符串,等效于+(+常用)
substr(start,length) 从start位置开始(索引号),length取个数
slice(start,end) 从start位置开始,截取到end位置,end取不到(都是索引号)
substring(start,end) 从start位置开始,截取到end,end取不到,基本和slice相同,但不接收负值

 

        // 字符串操作方法         // 1.concat('字符串1','字符串2'...)         var str  ='andy';         console.log(str.concat('red'));// andyred          // 2. substr('截取的起始位置','截取几个字符');         var str1 = '改革春风吹满地';         console.log(str1.substr(2,2));// 春风 // 第一个2 是索引号的2 从第几个开始  第二个2 是取几个字符

 

 

replace()方法

replace() 方法用于在字符串中用一些字符替换另一些字符,其使用格式如下:

字符串.replace(被替换的字符串, 要替换为的字符串); var str = 'andyandy'; console.log(str.replace('a')); //只替换第一个a

 

split()方法

split()方法用于切分字符串,它可以将字符串切分为数组。在切分完毕之后,返回的是一个新数组。

字符串.split("分割字符") var str = 'a,b,c,d'; console.log(str.split(',')); // 返回的是一个数组 [a, b, c, d]     <script>         // 1. 替换字符 replace('被替换的字符','替换为的字符') 只替换第一个         var str = 'andyandy';         console.log(str.replace('a', 'b'));// bndyandy         // 替换里面所有选中的字符串         var str1 = 'andyandy';         while (str1.indexOf('a') !== -1) {             str1 = str1.replace('a', '*');         }         console.log(str1);         // 2. 字符串转换为数组 split('分隔符') join 把数组转为字符串         var str2 = 'red,pink,blue';         console.log(str2, split(','));// ['red','pink','blue']         console.log(str2, split('&'));// ['red'&'pink'&'blue']     </script>

 

课下查阅

 toUpperCase() //转换大写

 toLowerCase() //转换小写

 

数据类型

1.1 简单数据类型

简单类型基本数据类型值类型):

在存储时变量中存储的是值本身,包括string ,number,boolean,undefined,null

null返回的是object,如果有个变量,以后打算存储为对象,可以用;

  <script>         // 简单数据类型 null  返回的是一个空的对象  object          var timer = null;         console.log(typeof timer);         // 如果有个变量我们以后打算存储为对象,暂时没想好放啥, 这个时候就给 null          // 1. 简单数据类型 是存放在栈里面 里面直接开辟一个空间存放的是值         // 2. 复杂数据类型 首先在栈里面存放地址 十六进制表示  然后这个地址指向堆里面的数据     </script>

 

 

1.2 复杂数据类型

复杂数据类型(引用类型):在存储时变量中存储的仅仅是地址(引用),通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等;

1.3 堆栈

  • 堆栈空间分配区别:

  1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面;

  2、堆(操作系统):存储 复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收

 

js中没有堆栈概念

  • 简单数据类型的存储方式

    值类型变量的数据直接存放在变量(栈空间)中,存储的是值

  • 复杂数据类型的存储方式

    引用类型变量(栈空间)里存放的是地址,地址指向堆里面的数据,真正的对象实例存放在堆空间中

    JavaScript基础

1.4 简单类型传参

函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。

    function fn(a) {         a++;         console.log(a);      }     var x = 10;     fn(x);     console.log(x);

 

运行结果如下:

 

1.5 复杂数据类型传参

函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。

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. 这个输出什么 ?  张学友

 

 

JavaScript基础