javascript基础汇总~~~全

这篇博客详细介绍了JavaScript的基础知识,包括语言组成、应用场景、语法规范、数据类型、运算符、变量、控制流程、数组、函数、对象等内容。JavaScript可以应用于网页特效、游戏开发、服务端、桌面程序等多个领域。博客中特别强调了数据类型的区别,如undefined与null,以及NaN的检测,还涵盖了数组的声明、遍历、去重和操作,以及函数的声明、调用和作用域。此外,还讨论了循环结构、分支结构和逻辑运算符的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

javascript

  • 是一种编程语言
    在这里插入图片描述

javascript语言的组成

  • ECMAScript
    确定js语言的语法规范 一些特定的可以被计算机识别的代码)
  • DOM
    文档对象模型
    js动态操作网页内容 一套操作页面元素的API
    通过DOM提供的API对文档树(HTML)进行节点操作
  • BOM
    浏览器对象模型
    js动态操作浏览器窗口 一套操作浏览器功能的API
    通过BOM可以操作浏览器窗口
应用场景
  • 网页特效
  • 游戏开发(通过cocos2d.js)
  • 服务端开发(通过node.js)
  • 命令行工具(通过node.js)
  • 桌面程序(Electron)
  • App(Cordova)
  • 控制硬件(物联网Ruff)

凡是能用js实现的功能 最终都会用js来实现

js三种书写位置

  • 行内式
    写在标签内部
<div onclick="alert('我是行内写法')"></div>
  • 内嵌式
    写在script标签中
    script标签可以写在head标签中 也可以写在body标签中
<script>
    alert('我是内嵌写法')
</script>
  • 外联式
    写在js文件中
    要用script标签的src属性导入
<script src='1.js'></script>

注意
如果script标签没有写src属性 是内联写法 js代码要写在标签里面
如果script标签写了src属性 是外联写法 js代码写在js文件中 此时script标签里面的代码无效

js代码注释

  • 单行注释//
    注释内容只能是一行

  • 对行注释/**/
    注释内容可以使多行

单行注释快捷键 ctrl + /
多行注释快捷键 ctrl + shift + /

js常用五句话

  • 主要用于调试以及浏览器的简单交互
alert('弹出一个提示框');
console.log('在控制台输出');
prompt('弹出一个输入框');//得到的数据是字符串类型
confirm('弹出一个确认框');
document.write('动态给页面添加内容')

注意
console.log()是给程序员自己看的 不是给用户看的
document.write()可能会覆盖网页原本的内容

计算机工作原理

  • 计算机组成

  • 软件(安装在操作系统上 操作系统的底层又运行在硬件当中)
    应用软件: 浏览器 qq 微信 webstorm…
    系统软件: Windows Linux iOS…

  • 硬件
    三大件: CPU 内存 硬盘
    输入设备 鼠标 键盘 摄像头…
    输出设备 显示器 打印机 投影机…

  • 代码进行的原理
    计算机工作原理

  • 代码在运行时 计算机主要做两件事
    1.识别并实现语法
    2.处理数据(计算和存储)

数据类型与直接量

  • 直接量(字面量)
    js可以直接拿来使用的数据
    这里的数据是指符合数据类型的数据

  • 数据类型
    代码在运行的时候 会产生各种不同的数据 不同的数据 CPU处理与存储的方式是不一样的 所以 需要对数据进行数据类型的分类

字符串类型String

用于显示网页文本
一切以单引号或双引号引起来的内容 都是字符串类型

数值类型Number

用于数学计算
一切数学中的数字

  • 数字的极值(了解)
console.log ( Number.MAX_VALUE );//1.7976931348623157e+308 无限接近于正无穷的数
console.log ( Number.MIN_VALUE );//5e-324 无限接近于0的正数 
console.log (Infinity );//正无穷
console.log (- Infinity );//负无穷
布尔类型Boolean

表示事物的对立面
只有两个值 true真 false假

注意
谷歌控制台小技巧
字符串显示黑色 数字显示蓝色

typeof 检测数据所属的数据类型

  • 两种语法
    typeof(数据)
    typeof 数据

typeof结果会得到数据所对应类型的 字符串
可以检测除null和数组之外的数据类型

console.log ( typeof 123 );//'number'
console.log ( typeof( 123 ) );//'number'
console.log ( typeof "123" );//'string'
console.log ( typeof true );//'boolean'
function fn(){}
console.log(typeof fn);//function
var a ;
console.log(typeof a);//undefined
var nu = null;
console.log(typeof nu);//object
var arr = [1,2,3];
console.log(typeof arr);//object
数组数据类型检测
  • Array.isArray(数据)
  • 检测数据是否是数据 是数组返回true 不是数组返回false
var arr = [1,2,3];
console.log(Array.isArray(arr));//true
  • 数据 instanceof Array
  • 检测数据是否是数据 是数组返回true 不是数组返回false
var arr = [1,2,3];
console.log(arr instanceof Array);//true
万能的数据类型检测
  • Object.prototype.toString.call(数据)
  • 可以检测所有的数据类型
var arr = [1,2,3];
console.log(Object.prototype.toString.call(arr));//[Object Array]
var nu = null;
console.log(Object.prototype.toString.call(nu));//[Object Null]

变量

  • var (variable)关键字
    内存中用来保存数据的一块空间
  • 用于声明变量
    用于在内存中存储数据
var num;//声明变量
num = 10;//赋值
console.log(num);//取值

注意
=号在js中是赋值运算符
作用是将等号右边的数据存入左边的变量对应的空间中

注意 不要把变量与字符串搞混淆

console.log('num');//打印的是num字符串
console.log(num);//打印num变量中存储的数据
  • 变量的初始化
    var num = 10;

  • 变量的批量声明(同时声明多个变量)
    var a,b,c;

  • 变量的批量声明赋值
    var a=10,b=10,c=10;

  • 变量的重新声明(会覆盖已经存在的变量)
    var num = 20;

  • 变量的重新赋值(先销毁旧值 然后存入新值)
    num = 10;

  • 变量的值是另一个变量的值

  • 是将变量中的数据复制一份给另一个变量

var a = 10;
//将a变量中的值复制一份给变量b
var b = a;
  • 交换两个变量的值
var n1 = 10;
var n2 = 20;
var temp = n1;
n1 = n2;
n2 = temp;
console.log(n1);
console.log(n2);
  • 不适用临时变量 交换两个变量的值
		var a = 10;
        var b = 20;
        a = b - a;//b=20 a=10
        b = b - a;//b= 10 a=10
        a = a + b;//a = 20 b=10
        console.log(a);
        console.log(b);

变量的命名规则与规范

规则
必须遵守 不遵守程序会报错
变量名由字母 数字 下划线_ $符号组成 不能以数字开头
不能以js关键字和保留字作为变量名

规范
所有程序员需要遵守的代码习惯
命名要有意义 一般用英语名词
使用驼峰命名法 第一个英语单词首字母小写 后面每个单词首字母大写 如fontSize

js关键字和保留字

js中的+号的两个作用

字符串连接符
  • 把加号两边的数据连接成一个新的字符串
  • 加号两边只要有一边是字符串 会拼接成字符串
console.log(100+'100');//'100100'
数学加号
  • 两边都要是数字
console.log(1+1);//2

算术运算符与算术表达式

  • 算术运算符+ - * / %
  • 运算符只是一种运算符的符号 单独存在没有意义 通常与数字在一起组成式子 也就是表达式
  • 表达式一定有结果 要么直接打印出结果 要么存入变量中
console.log(1+1);//2
var a = 1+1;
console.log(a);//2

//%取模
console.log(10%3);//1

注意
除法中 0不能作为除数 如果一个数字除以0 会得到Infinity
如果一个除法的结果是无限循环小数 js只会保留小数点后的15-17位 对开发没有影响 可以忽略

  • 复合算术运算符
    +=
    -=
    *=
    /=
    %=
var num =10;
num = num % 3;
//等价于
var num = 10;
num %= 3

自增自减运算符

自增运算符++
  • 自增表达式 由自增运算符组成的式子 num++
  • 变量自身+1
自减运算符--
  • 自减表达式 由自减运算符组成的式子 num--

  • 变量自身-1

  • 前自增与后自增
    ++num
    num++
    相同点:无论是前自增还是后自增 对于变量自身而已没有区别 都是自身+1
    不同点 表达式结果不同

//后自增 
var num =10;
num++;
console.log(num);//11
//先赋值 后自增
//将变量的值赋值给表达式的结果 再变量自身+1
var res = num++;
console.log(res);//11
//前自增
var num =10;
++num;
console.log(num);//11
//先自增 后赋值
//将变量自身+1 在将变量的值赋值给表达式的结果
var res = ++num;
console.log(res);//12

  • 测试题1
var a = 1;
var b = a++ +a++;
//b=1+    a=2
//b=1+2=3   a=3
console.log(a);//3
console.log(b);//3

  • 测试题2
var c = 10;
var d = c++ + ++c -c--;
//d=10+  c=11
//d=10+12- c=12
//d=10+12-12 c=11
console.log(c);//11
console.log(d);//10

关系表达式与关系运算符

关系运算符
  • 比较两个数字之间的关系(判断某种条件是否成立)
  • > >= < <= == != === !==
关系表达式
  • 由关系运算符组成的式子
  • 结果一定是布尔类型 true关系成立 false关系不成立
console.log(10<2);//false
console.log(1=='1');//true
console.log(1==='1');//false

== 相等与=== 全等的区别
==相等运算符 只比较数据的值 不比较数据的类型
===全等运算符 先比较数据的值 后比较数据的类型
注意
区别于=号
=号是赋值运算符
将等号右边的数据存入左边的变量中

逻辑运算符与逻辑表达式

逻辑运算符
  • 计算多个条件之间的关系
    &&逻辑与 一假则假
    ||逻辑或 一真则真
    !逻辑非 取反 true变false false变true

逻辑运算符的短路运算

  • 如果左边的式子能够决定逻辑表达式的结果 那么右边的式子不会执行
  • 逻辑与 一假则假
    找假
    如果左边的式子能够转换为false 就无条件返回左边式子的值 反之无条件返回右边式子的值
  • 逻辑或 一真则真
    找真
    如果左边的式子能够转换为true 就无条件返回左边式子的值 反之无条件返回右边式子的值
  • 逻辑非
    没有短路运算
    因为逻辑非只有一个式子
var num = 10;
var res = 1>2 && num++;
console.log(res);//false 一假则假 &&后面的式子不会执行
console.log(num);//10
var res = 1 || null;
console.log(res);//1
var res = undefined || null;//一真则真
console.log(res);//null
  • 逻辑表达式的结果不一定是布尔类型 ! ! ! ! !
var num =10 && 20;
console.log(num);//20
逻辑表达式
  • 由逻辑运算符组成的式子
console.log(20>10 && 20<5);//false
console.log(20>10 || 20<5);//true
console.log(!true);//false

运算符的优先级(了解)

  • 不同的运算符运算的顺序不一样
  1. 小括号()
    作用 提升优先级
  2. 自增自减运算符
  3. 算数运算符
  4. 关系运算符
  5. 逻辑运算符
  6. 赋值运算符
    [运算符优先级]

Math高级数学函数

Math语法描述
Math.PI圆周率
Math.abs()绝对值(返回一个数字距离坐标原点的距离)
Math.ceil()天花板函数(向上取整)
Math.floor()地板函数(向下取整)
Math.max()取一组数字的最大值
Math.mix()取一组数字的最小值
Math.round()四舍五入
Math.pow(x,y)幂运算 (求x的y次方)
Math.random()随机数(生成0-1之间的小数)
console.log(Math.PI);//3.141592653589793
console.log(Math.abs(-2));//2
console.log(Math.ceil(1.2));//2
console.log(Math.floor(1.2));//1
console.log(Math.max(10,20,30));//30
console.log(Math.min(10,20,30));//10
console.log(Math.round(10.5));//11
console.log(Math.pow(2,3));//8
console.log(Math.random());//生成0-1之间的随机小数
console.log(Math.random()*100);//生成0-100之间的随机小数
console.log(Math.ceil(Math.random()*100));//生成1-100之间的随机整数 需要向上取整
console.log(Math.floor(Math.random()*100));//生成0-100之间的随机整数 需要向下取整

数据类型

  • 基本数据类型
    number
    string
    boolean
    null
    undefined

  • 复杂数据类型
    Array
    Object
    Function

  • undefined
    只有一个值 就是undefined
    未定义
    如果变量只声明 未赋值 默认值就是undefined

  • null
    只有一个值 就是null
    空值
    必须手动设置 变量在任何时候自己的值都不会是null
    如果使用typeof检测null 结果会得到object 无法用typeof检测null
    如果要检测 可以使用Object.prototype.toString.call(null);来检测 结果是[Object Null]

undefined与null的区别(重点)

undefined与null的数据类型不同 但是值的比较的时候是相同的

console.log(undefined==null);//true 它们的值都是空
console.log(undefined===null);//false 它们的值相等 但是数据类型不同

NaN与isNaN

NaN (not a number)

是number数值类型中的一个特殊的值
表示数学错误的计算结果
如果数学计算结果不是一个数字 就会得到NaN

注意
NaN与任何数字计算的结果都是NaN
NaN与任何数字都不等 包括它自身

console.log('字符串'-20);//NaN
console.log(NaN+1);//NaN
console.log(NaN==0);//false
console.log(NaN==NaN);//false
console.log(typeof NaN);//'number'
检测一个数据是不是NaN
  • 语法 isNaN(数据)
  • 如果结果是数字 返回false 结果不是数字 返回true
console.log(isNaN(NaN));//true
console.log(isNaN('字符串'-1));//true
console.log(isNaN(10-1));//false

显式类型转换

  • 程序员主动调用关键字来转换

其他数据类型转number

1.string字符串类型转number
  • .parentInt(数据) 转整数
    工作原理: 从左往右逐个解析字符 遇到非数字字符会结束解析 并返回已经解析好的整数 如果第一个字符串就是非数字字符 直接返回NaN
  • parentFloat(数据) 转浮点数
    工作原理: 从左往右逐个解析字符 可以识别第一个小数点 后面再遇到非数字字符会结束解析 并返回已经解析好的数字 如果第一个字符串就是非数字字符 直接返回NaN
2.其他数据类型转number
  • Number(数据)
    工作原理: 可以解析整数与小数 将整个数据进行解析 只要有一个非数字字符就会返回NaN
  • 常见的是布尔类型转数值类型 会得到0或1
    true转1 false转0
  • undefined转数值类型 会得到NaN
  • null转数值类型 会得到0
console.log(Number(true));//1
console.log(Number(false));//0
console.log(Number(undefined));//NaN
console.log(Number(null));//0
console.log(Number(''));//0

一般数字字符串转数字使用parseInt和parseFloat 其他数据类型转数字用Number()

其他数据类型转string

  • String(数据)
    可以识别undefined与null
  • 变量名.toString()
    不能识别undefined与null

其他数据类型转boolean

  • Boolean(数据)
    布尔类型只有两个值
    false: 八种情况会得到false
    0 -0 NaN '' undefined null false document.all()
    true: 除开得到false的八种情况之外的一切数据

隐式类型转换

  • 当运算符两边的数据类型不一样 编译器会偷偷帮我们转成一致在进行计算
转number的情况
  • 算数运算符(+ - * / %)
  • 关系运算符(> >= < <= == != === !==)
  • 自增自减(-- ++)
//编译器帮我们将'10'转成Number('10')再去运算
console.log('10'-2);//8

//编译器帮我们将'字符串'转成Number('字符串')再去运算
//Number('字符串')是整个数据解析 遇到非数字字符直接返回NaN
//NaN与任何数字的运算结果都是NaN
console.log('字符串'-2);//NaN
转string的情况
  • +字符串连接符

注意
+号有两个作用 一个是算术运算符 一个是字符串连接符
只要+号两边有一边是字符串 那么+号就是字符串连接符
否则+号就是算术运算符

//只要加号有一边是字符串 那么加号就是字符串连接符
//编译器会将10转成String(10) 再去拼接
console.log(10+'10');//'1010'

//+号两边没有字符串 就是算术运算符 那么编译器会将true转成Number(true) true转数值类型是1 false转数值类型是0
console.log(1+true);//2
console.log('1'+true);//'1true'
转boolean的情况
  • 逻辑非!
    取反 true变false false变true
//编译器遇到逻辑非 会将数据转成Boolean(0) 结果是false !取反 结果是true
console.log(!0);//true
//编译器遇到逻辑非 会讲数据转成Boolean(1) 结果是true !取反结果是false !再取反 结果是true
console.log(!!1);//true

程序流程控制

顺序结构(默认)

  • 代码从上往下顺序依次执行

分支结构

if分支结构
适用于一种条件判断
代码根据条件执行
  • 语法:
    if(条件){ 条件成立时执行大括号里面的代码 }

注意
if小括号的结果一定是布尔类型
if中小括号里面的代码
1.常用的是关系表达式
2.直接写布尔类型的值
3.写其他的值 编译器会帮我们转布尔类型Boolean(数据)再来判断是否成立

if-else分支结构
  • 适用于两种互斥条件

  • 互斥条件 两个条件一定会满足一个 (不会同时满足 也不会同时不满足)

  • 大括号中的代码 一定会执行一个( 不会同时执行 也不会同时不执行)

  • 语法:

if(条件){
  条件成立时执行的代码
}else{
   条件不成立时执行的代码
}
  • if-else优点
    两个互斥条件 只需要判断一次
if-else if-else结构
  • 适用于多种条件判断
  • 必须要以if开头 中间else if可以是多个 结尾else可以省略 一般不会省略 会导致逻辑漏洞
  • 所有大括号中的代码最多只会执行一个
  • 语法:
if(条件1){
   条件1成立时执行的代码
}else if(条件2){
   条件2成立时执行的代码
}else{
    以上条件都不成立时执行else里面的代码
}
switch-case分支结构
  • 适用于固定值匹配
    匹配: 全等===

  • 语法:

switch(匹配值){
    case1:
        匹配值===1时需要执行的代码;
        break;
    case2:
        匹配值===2时需要执行的代码;
        break;
    default:
    
        匹配值与case后面的值都不全等 需要执行的代码;
        break;
}
  • break关键字作用
    结束switch-case语句
    防止穿透

注意
匹配值与case后面的值一定要是全等的关系
default代码块可以写在任何位置 但是一般写在最后面
如果不写break 则会发生穿透现象(代码无条件从上一个case执行到下一个case)
写break的作用 阻止穿透现象
如果多个值需要执行的代码相同 可以合理使用穿透现象


三元运算符与三元表达式

三元运算符
  • 运算符根据操作的数的多少分为一元运算符 二元运算符 三元运算符
    一元运算符 ++ --只能操作一个数
    二元运算符 算数运算符 关系运算符 操作两个数
    三元运算符 可以操作三个数
三元表达式
  • 由三个运算符组成的式子
  • 语法: 表达式?代码1:代码2
  • 如果表达式成立 则执行代码1 否则执行代码2
  • 如果代码1和代码2有结果 那么三元表达式的结果就是代码1和代码2的值

注意
三元表达式做的事与if-else一样 只是代码更简洁

//如果代码1和代码2有结果 那么三元表达式的结果就是代码1和代码2的值
var res = 1>10?10:20;
console.log(res);//20
循环结构
  • 循环中人为结束循环使用break
while循环结构
  • 适用于循环次数不固定的场景
  • 代码重复执行
  • 先判断条件 后执行循环体
  • 特点 如果循环条件不成立 循环体可能一次都不会执行
  • 语法
while(条件){
    循环体 条件成立需要重复执行的代码
}
  • 示例
var num = 0;
while(num<5){
    console.log('条件成立执行')
    num++;
}

注意
if小括号的结果一定是布尔类型
if中小括号里面的代码
1.常用的是关系表达式
2.直接写布尔类型的值
3.写其他的值 编译器会帮我们转布尔类型Boolean(数据)再来判断是否成立
避免写一个死循环

  • 穷举
    猜谜游戏
    生成以1-100之间的随机整数 让用户猜
    如果用户猜大了或猜小了 提示用户 直到用户猜对为止
        var num = Math.ceil(Math.random() * 100);
        console.log(num);
        //搞个死循环 直到猜对为止
        while (true) {
            var guess = +prompt('请输入数字');
            if (guess == num) {
                alert('猜对了');
                //结束循环用break
                break;
            } else if (guess > num) {
                alert('猜大了');
            } else {
                alert('猜小了');
            }
        }

do-while循环结构
  • 适用于循环次数不固定 循环体无条件执行一次
  • 特点 循环体无条件执行一次循环体
  • 先斩后奏
  • 先执行一次循环体 后判断条件

do{ 循环体 无条件执行一次循环体 再判断条件是否成立 }while(条件)

var num = 0;
do{
    console.log('无条件执行一次再做判断');
    num++;
}while(num<4)
  • 测试题

      登录案例
      弹出一个登录框让用户输入码用户名和密码 只要输入正确提示正确 输入错误就重复输入 直到输入正确为止
      账号admin 密码123456
    
	do{
		var usrname = prompt('请输入用户名');
		var pwd = prompt('请输入密码');
	}while(usrname !='admin'|| pwd != '123456);

for循环

  • 适用于循环次数固定的场景
    for(声明循环变量;循环条件;循环变量自增){循环条件成立执行代码}
  • for循环执行步骤
    1.执行 声明循环变量
    2.执行 判断循环条件
    3.条件成立 执行大括号代码 条件不成立 循环结束
    4.执行 循环变量自增 重复步骤2

注意
小括号里面是以分号隔开
小括号里面的语句可以省略 但是分号不能省略
if(;;){}

  • 箩筐思想
	//声明一个空箩筐
        var sum = 0;
        for (var i = 1; i <= 100; i++) {
            sum += i;
        }
        console.log(sum);
  • 打擂台思想
	//声明一个擂主 -Infinity
	var max = -Infinity;
        for (var i = 1; i <= 5; i++) {
            var num = +prompt('请输入第' + i + '个数');
            if (num > max) {
                max = num;
            }
        }
        console.log(max);
循环中的关键字
  • break
    结束循环语句 立即执行大括号后面的代码
  • continue
    结束本次循环体 立即进入下一次循环判断
    循环中break和continue关键字

注意
break关键字可以用于三种循环结构以及switch-case分支结构
continue关键字只能用于三种循环结构


  • 测试

      穷举: 从1遍历到无穷大寻找符合条件的数字
      有一群人 如果3个人站一排多出1个人 如果4个人站一排对出2个人 如果5个人站一排多出3个人 请问这群人有多少人
    
       for (var i = 1; i < Infinity; i++) {
            if (i % 3 == 1 && i % 4 == 2 && i % 5 == 3) {
                console.log(i);
                break;
            }
        }

循环嵌套
  • 打印正方形
  • 外层循环决定多少行 内层循环决定多少列
	 for (var j = 1; j <= 5; j++) {
	 //让里面的5个*循环5次 并回车
            for (var i = 1; i <= 5; i++) {
            //打印* 和一个空格&nbsp;;
            //一行打印出5个*
                document.write('*&nbsp;');
            }
            document.write('<br>')
        }
  • 打印三角形
	for (var j = 1; j <= 5; j++) {
            for (var i = 1; i <= j; i++) {
                document.write('*&nbsp;');
            }
            document.write('<br>')
        }
  • 打印倒三角形
	for (var j = 1; j <= 5; j++) {
           for (var i = 1; i <= (6-j); i++) {
               document.write('*&nbsp;');
           }
           document.write('<br>')
       }
  • 打印九九乘法表
 	for (var i = 1; i <= 9; i++) {
            for (var j = 1; j <= i; j++) {   					
            document.write(j+'*'+i+'='+j*i+'&nbsp;&nbsp;');
            }
            document.write('<br>')
        }

  • 循环练习

      老师问学生 这道题你会了吗(y/n)? 如果学生会就回去,不会,
      老师再问一遍 这道题你会了吗(y/n)?  在六遍以内不会都可以回家.
    
//法1 用do-while
	var count = 1;
        do {
            var isHui = prompt('第' + count + '次会了吗?y/n');
            count++;
        } while (isHui == 'n' && count <= 6);
        alert('不管会不会都会回家吧')
     
     
//法2 用for循环
	var count = 1;
        for (var i = 1; i <= 5; i++) {
            var isHui = prompt('第' + count + '次会了吗?y/n');
            count++;
            if (isHui == 'y') {
                break;
                //会了退出循环
            }
        }
        i == 6 ? alert('五次都不会') : alert('会了')
录入5个人的年龄并计算平均年龄,重复输入五次.
如果有人搞鬼输入负数或大于100的数,立即停止输入并报错,
还算出之前输入的个数和平均值打印出来
       var sum = 0;
        for (var i = 1; i <= 5; i++) {
            var age = +prompt('请输入第' + i + '个人的年龄');
            if (age < 0 || age > 100) {
                alert('出错');
                break;
            }
            sum += age;
        }
        console.log('之前输入的个数' + (i - 1) + '平均值是' + sum / (i - 1));
2006年培养学员80000人.年数2006年开始,人数80000起步 每年呈25%的增长速度.问需要几年到20万人
//法1 用do-while
        var num = 80000;
        var year = 2006;
        do {
            num *= 1.25;
            year++;
        } while (num < 200000)
        console.log(year);
       
//法2 用for循环
	var num = 80000;
        for (var i = 2006; i < Infinity; i++) {
            if (num < 200000) {
                num *= 1.25;
            }else{
                break;
            }
        }   
        alert(i);
用户输入正确,提示登录成功 输入错误,提示继续输入 输错3次,提示账号被冻结,不能再输入,跳出循环,结束
 //法1 用do-while
        var count = 1;
        do {
            var usr = prompt('请输入用户名');
            var pwd = prompt('请输入密码');
            count++;
        } while ((usr != 'admin' || pwd != '123456') && count <= 3);
        count == 4 ? alert('账号被冻结') : alert('登录成功');
        
        //法2 用for循环
        for (var i = 1; i <= 3; i++) {
            var usr = prompt('请输入用户名');
            var pwd = prompt('请输入密码');
            if (usr == 'admin' && pwd == '123456') {
                break;
            }
        }
        i == 4 ? alert('账号被冻结') : alert('登录成功');
	1000~ 5000之间有多少整数,其各位数字之和为5,分别是哪些数(例如整数2003的各位数字之和为 2+0+0+3 ,等于5)),并统计满足条件的整数有多少个。
 var count = 0;
       for (var i = 1000; i <= 5000; i++) {
           var q = parseInt(i / 1000);
           var b = parseInt(i % 1000 / 100);
           var s = parseInt(i % 100 / 10);
           var g = parseInt(i % 10);
           if (q + b + s + g == 5) {
               count++;
               console.log(i);
           }
       }
       console.log(count + '个');

数组

数组三要素
  • 元素
    数组中存储的数据
  • 下标
    元素的位置(从0开始)
    最大下标 = 数组名.length - 1
    数组名.length = 最大下标 + 1
  • 长度
    元素的数量
//数组的声明
var arr = [10,20,30];
//数组的取值:  数组名[下标]
console.log(arr[0];
//数组的长度: 数组名.length
console.log(arr.length);

注意
在数组取值中
如果没有超过最大下标 则取出对应下标的值
如果超过最大下标 获得的是undefined
在数组赋值中
如果没有超过最大下标 则修改原有的数据
如果超过最大下标 则动态添加数据

  • 不连续数组
    没有赋值的都是undefined
var arr = [10,20,30];
arr[4] = 50;
//下标为3没有赋值 则结果为undefined
console.log(arr[3]);//undefined
  • 获取数组的最后一个元素
    arr[arr.length-1]
  • 在数组最后添加一个元素
    arr[arr.length] = 值
  • 删除数组最后一个元素
    arr.length--
遍历数组
  • 获取数组中每一个元素
var arr = [10,20,30];
for(var i = 0; i < arr.length; i++){
	console.log(arr[i]);
}
  • 翻转数组
		//法1 倒序遍历 存入新数组
		var arr = [10, 30, 9, 20, -5, 6, 8];
		//声明一个空数组 保存翻转的元素
        var newArr = [];
        for (var i = arr.length - 1; i >= 0; i--) {
            newArr[newArr.length] = arr[i]
        };
        console.log(newArr);
        //法2 同法1
        var arr = [10, 30, 9, 20, -5, 6, 8];
		//声明一个空数组 保存翻转的元素
        for(var i=arr.length-1;i>=0;i--){
            newArr.push(arr[i])
        };
        console.log(newArr);
// 交换法 遍历一半 让下标为i的元素与下标为arr.length-1-i元素交互位置
        /* 
        0 与 arr.length-1 交换位置
        1 与 arr.length-1-1 交换位置
        ...
        i 与 arr.length-1-i 交换位置
         */
        for (var i = 0; i < arr.length / 2; i++) {
            var temp = arr[i];
            arr[i] = arr[arr.length - 1 - i];
            arr[arr.length - 1 - i] = temp;
        }
        console.log(arr);
  • 斐波那契数列
//1 1 2 3 5 8 13 21 44 ... 求第10列(下标9)
        var arr = [1, 1];
        for (var i = 2; i < 10; i++) {
            arr[i] = arr[i - 2] + arr[i - 1];
        }
        console.log(arr[arr.length - 1]);
  • 冒泡法排序
  • 核心原理
    数组中相邻两个元素比较大小 然后交换位置
//冒泡排序
        var arr = [10, 2, 9, -6, 66, 99, 5];
        /* 
        外层比较轮数
        第一轮找第一大 第二轮找第二大 第三轮找第三大... 所以7个元素只需比较6轮
        所以arr.length 需要比较 arr.length-1轮
         */
        for (var i = 0; i < arr.length - 1; i++) {
            /* 内层比较每一轮比较的次数 数组中两两比较 
            最后一次没意义 7个元素比6次即可
            (i=0)第一轮比较arr.length-1次 
            (i=1)第二轮比较arr.length-2次
            ...
            每一轮比较次数+i = arr.length-1
            所以每一轮比较次数 需要比较arr.length-1-i
            */
            for (var j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    var temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        console.log(arr);
二维数组(了解)
  • 数组中每一个元素都是数组
 var arr = [[10, 20, 30], [40, 50, 60], [70, 80, 90]];
        for (var i = 0; i < arr.length; i++) {
            //   取出数组中的数组
            console.log(arr[i]);
            for (var j = 0; j < arr[i].length; j++) {
                // 取出二维数组中的值
                console.log(arr[i][j]);
            }
        }
数组的声明方式
  • 简洁语法
    var arr = [10,20,30];

  • 标准语法
    var arr = new Array();
    var arr = new Array(10);
    var arr = new Array(10,20,30);

  • 两种声明方式的区别
    相同点: 当数组中有多个元素的时候 含义相同 只是语法不同
    不同点: 当数组中只有一个元素的时候 含义不同
    var arr = [10];代表数组中只有一个元素 值为10
    var arr = new Array(10);代表数组长度为10的空数组

数组去重
  1. 冒泡法
 //数组去重
        //法1 冒泡法
        var arr = [20, 25, 88, 66, 90, 25, 88, 66];
        for (var i = 0; i < arr.length - 1; i++) {
            for (var j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    var temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        // 得到从小到大的冒泡排序
        console.log(arr);
        //在判断相邻两个元素之间是否相等 如果不等 就添加到新数组中
        var newArr = [];
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] != arr[i + 1]) {
                // 追加到新数组中 两种方式都可以
                // newArr[newArr.length] = arr[i];
                newArr.push(arr[i]);
            }
        }
        console.log(newArr);
  1. 开关思想
 //数组去重
        //法2 开关思想
        var arr = [20, 25, 88, 66, 90, 25, 88, 66];
        //声明一个新数组 存放去重后的元素
        var newArr = [];
        for (var i = 0; i < arr.length; i++) {
            // 判断新数组中是否存在一样的元素 通过开关思想
            //提出假设 假设不在
            var buZai = true;
            for (var j = 0; j < newArr.length; j++) {
                // 推翻假设
                if (arr[i] == newArr[j]) {
                    buZai = false;
                    //存在一样的元素 结束循环
                    break;
                }
            }
            if (buZai) {
                // 追加到新数组的两种方式都可以
                // newArr[newArr.length] = arr[i];
                newArr.push(arr[i]);
            }
        }
        console.log(newArr);
  1. indexOf检测
 //数组去重
        //法3 indexOf检测
        var arr = [20, 25, 88, 66, 90, 25, 88, 66];
        //声明一个新数组 存放去重后的元素
        var newArr = [];
        //遍历arr
        for (var i = 0; i < arr.length; i++) {
            // indexOf(元素) 如果存在会返回下标 如果不存在会返回-1
            if (newArr.indexOf(arr[i]) == -1) {
             // 追加到新数组的两种方式都可以
            // newArr[newArr.length] = arr[i];
                newArr.push(arr[i])
            }
        }
        console.log(newArr);
  1. 对象法
 //数组去重
        //法3 indexOf检测
        var arr = [20, 25, 88, 66, 90, 25, 88, 66];
        //声明一个新数组 存放去重后的元素
        var newArr = [];
        //声明一个空对象 用来检测元素是否重复
        var obj = {};
        //遍历arr
        for (var i = 0; i < arr.length; i++) {
            if (obj[arr[i]] == undefined) {
             // 追加到新数组的两种方式都可以
             // newArr[newArr.length] = arr[i];
                newArr.push(arr[i]);
                obj[arr[i]] = 1;
            }
        }
        console.log(newArr);

  • 测试题

      将字符串数组用`|`分割成字符串
    
		//原生操作
		var arr = ['中国', '我', '爱', '你'];
        // 声明一个空字符串 存放数组中的值
        var str = '';
        for (var i = 0; i < arr.length; i++) {
            str += arr[i];
            // 最后一个字后面不需要|分割 所以判断只要不是最后一个 就添加|
            if (i != arr.length - 1) {
                str += '|'
            }
        }
        console.log(str);
		//通过数组的API操作
		//arr.join("自定义分隔符");
		//自动将数组转为字符串 
     	var arr = ['中国', '我', '爱', '你'];
        console.log(arr.join('|'));
将数组中为0的那些值去掉

        var arr = [10, 20, 0, 0, 30, 0, 0, 50];
        var newArr = [];
        for (var i = 0; i < arr.length; i++) {
            if (arr[i] != 0) {
                newArr[newArr.length] = arr[i]
            }
        }
        console.log(newArr);

函数

  • 将代码存入函数中 实现代码复用
语法
  • 声明函数
    function 函数名(形参){函数体}
  • 调用函数: 执行函数体代码
    函数名(实参)
  • 函数传参的本质 是一个变量赋值的过程
    实参给形参赋值
    形参与实参不需要一一对应 如果没有传 默认值就是undefined

循环与函数有着本质的区别
从数据层面上
函数是一种数据类型 存储的是代码
循环是一种语法 让代码重复执行
从作用上
函数是一段代码在多个地方执行一次
循环是一段代码在一个地方执行多次

  • 在函数外部无法访问函数内部声明的变量
  • 要想拿到函数内部的结果 可以在函数中return这个结果 然后用一个变量接收这个返回值后打印
函数的三要素
  1. 函数体(功能)
  2. 参数
  3. 返回值
函数中的关键字return
  • 只能写在函数体中
  • 作用
    结束函数调用 后面的所有代码都不执行
  • 返回值 : 函数传递数据给调用者
    return 值
函数的执行方式
  • 调用者传递数据给函数
  • 函数通过返回值将结果传递给调用者
  • 调用者用变量接收返回值或直接调用打印
函数的工作流程
  1. 声明函数
  2. 调用者传参
  3. 执行函数体代码
  4. 函数将结果返回给调用者
    函数的工作流程

  • 求任意n到m之间的和
  	   function getSum(n, m) {
            var sum = 0;
            for (var i = n; i <= m; i++) {
                sum += i;
            }
           return sum;
        }
        //假设求1到100之间的和
        //调用后用变量接收返回值
        var res = getSum(1, 100);
        console.log(res);
        //直接调用打印
        //console.log(getSum(1, 100));

  • 求任意半径圆的面积
 	   function getArea(r) {
           var area = Math.PI * Math.pow(r, 2);
           return area;
       }
       //假设需要求半径为10 直接调用传入值
        var res = getArea(10);
        console.log(res);
返回值的注意点
  1. 如果一个函数没有return 返回值是undefined
  2. 如果一个函数有return 但是后面没有值 返回值是undefined
  3. 只有函数写了return且return后面有值 返回值就是return后面的值
  4. return后 后面的代码不会执行

  • 求数组的最大值 用函数封装
   //求数组的最大值
        function getMax(arr) {
            var max = arr[0];
            for (var i = 0; i < arr.length; i++) {
                if (arr[i] > max) {
                    max = arr[i]
                }
            }
            return max;
        }
        var newArr = [10, 20, 6, 30, 99];
        var res = getMax(newArr);
        console.log(res);
变量的作用域
  • 变量作用域: 变量起作用的范围
  • 全局作用域: 全局变量 函数外面声明的变量 在页面任何位置起作用
//全局变量
var num = 10;
console.log(num);//10
  • 局部作用域: 局部变量 函数里面声明的变量 在函数内部起作用
function fn(){
	//局部变量
	var num = 10;
	console.log(num);//10
}
//局部变量在函数外部访问会报错
console.log(num);//报错
作用域链
默认情况下 js代码处于全局作用域(0级链)
声明一个函数 就会开辟一个新的局部作用域(1级链)
在函数内部又可以声明函数 形成局部作用域(2级链)
在函数内部又可以声明函数 形成局部作用域(3级链)
以此类推 就形成作用域链
  • 变量在作用域链的访问规则
    • 就近原则
    • 当在一个作用域访问变量时 会先从当前作用域寻找变量的声明
    • 如果有就访问 如果没有则从父级链中寻找声明
    • 有则访问 没有则继续从父级链中寻找 以此类推
    • 直到顶级链 如果顶级链还找不到 程序则报错
var num = 10;//0级链
function fn1(){//0级链
	var num = 20;//1级链
	console.log(num);
	function fn2(){//1级链
		var num = 30;//2级链
		console.log(num);//30
	}
	fn2();
}
fn1();
console.log(num);//10
  • js中只有函数可以开辟局部作用域
 		//分支结构中声明的变量是全局变量
        if (1 > 0) {
            //全局变量
            var num = 10;
        }
        console.log(num);//10

        console.log('------------------');

        //循环结构中声明的变量也是全局变量
        for (var i = 0; i <= 5; i++) {
        }
        console.log(i);//6

        console.log('------------------');

        var name = '张三'
        function fn() {
            //没有var关键字声明的变量是全局变量
            //将全局变量中的值重新赋值
            name = '李四';
            console.log(name);//李四
        }
        fn();
        console.log(name);//李四
js预解析
  1. js代码在执行代码之前 有一个预解析过程
  2. 预解析: js代码从上往下执行之前 编译器会将代码进行变量提升
  3. 变量提升:
    1. var关键字声明会提升到当前作用域最顶端 赋值语句在原地
    2. function关键字函数声明也会提前 调用语句在原地
      在这里插入图片描述
  4. 预解析的意义(作用): 可以让函数在任何地方调用
  5. 如果一个变量没有用var关键字声明 不管写在任何位置 都是全局变量 不参与预解析
  • js预解析面试题
  • 题1
    var num = 10;
        fun();
        function fun() {
            console.log(num);//undefined
            var num = 20;
        }
        console.log(num);//10
	//预解析过程
    //  var num ;
    //  function fun(){
    //     var num;
    //      console.log(num);//undefined
    //      num = 20;
    //  }
    //  num = 10;
    //  fun();
    // console.log(num);//10
  • 题2
 		console.log(a);//打印a整個函數
        a();//我是函数
        var a = '我是变量';
        function a() {
            console.log('我是函数');
        }
        a();//报错
        console.log(a);

        //预解析过程
        // var a;
        //变量重新声明
        // function a() {
        //     console.log('我是函数');
        // }
        // console.log(a);
        // a();//调用后打印函数里的代码-->我是函数
        // a = '我是变量'; 
        // a();//此时a中存储的是字符串 没有调用的语法 报错 程序报错 后面的代码不会执行
        // console.log(a);
  • 题3
 		console.log(a);
        var a = '我是变量';
        function a() {
            console.log('我是函数');
        }
        console.log(a);//'我是变量'

       //预解析过程
       //function和var都是声明作用 变量名相同 就是重新声明
    //    var a;
    //    function a(){
    //        console.log('我是函数');  
    //    }
    //    console.log(a);//打印出整个a函数
    //     // 没有var关键字声明 就是变量重新赋值
    //    a = '我是变量';
    //    console.log(a);//'我是变量'
函数声明
  • 函数声明(具名函数)
    function fn(){}
  • 表达式声明(匿名函数)
    var fn = function(){}

两种声明方式唯一的区别
函数声明可以在任何地方调用
表达式声明只能在声明之后调用

值类型与引用类型
  • 变量的声明是在栈中开辟空间
  • 值类型(string number boolean undefined null)
    基本数据类型栈中存储的是数据 赋值拷贝的也是数据 修改后的数据对原数据没有影响
  • 引用类型(Array Object)
    复杂数据类型栈中存储的是地址 数据存储在堆中 赋值拷贝的是地址 修改拷贝后的数据对原数据有影响
var a = 10;
var b = a;
b = 20;
console.log(a);
console.log(b);
var arr1 = [10,20,30];
var arr2 = arr1;
arr2[0] = 100;
console.log(arr[1]);
console.log(arr[2]);

值类型与引用类型

函数中关键字arguments
  • 函数实参与形参可以不一一对应 但是赋值是按顺序赋值的
  • 函数中arguments关键字 存储所有的实参 只能在函数中使用
  • 函数中arguments关键字 是一个伪数组 拥有数组的三要素(元素 下标 长度) 没有数组的API
  • 函数中arguments关键字与形参一一对应
    • 修改了arguments 形参也会改
    • 修改了形参 arguments也会修改
		function fn(a) {
            //存储所有的实参
            console.log(arguments);
            //arguments与形参一一对应
            // arguments修改了 形参也跟着修改
            arguments[0] = 10;
            console.log(a);
            // 形参修改了 arguments也跟着修改
            a = 20;
            console.log(arguments);
        }
        //函数中实参与形参不需要一一对应
        fn(1, 2, 3);
  • 函数中arguments关键字的应用场景
    让函数根据参数的数量实现不同的功能
 //需求
        //一个参数 打印参数
        //两个参数 求和
        //三个参数 其他功能
        function fn() {
            if (arguments.length == 1) {
                console.log(arguments[0]);
            } else if (arguments.length == 2) {
                console.log(arguments[0] + arguments[1]);
            } else {
                console.log('其他功能');
            }
        }
        fn(10);
        fn(10, 20);
        fn(10, 20, 30);
  • 函数练习

      写一个函数,实现翻转数组
    
 //写一个函数,实现翻转数组
 //方法1 通过倒序遍历 存入新数组中
        function fn(arr) {
            var newArr = [];
            for (var i = arr.length - 1; i >= 0; i--) {
                newArr[newArr.length] = arr[i];
            }
            return newArr;
        }
        var myArr = [10, 20, 30, 40, 50];
        var res = fn(myArr);
        console.log(res);
        
 //方法2 通过交换法 遍历一半 
 function fn(arr) {
            for (var i = 0; i < arr.length / 2; i++) {
                var temp = arr[i];
                arr[i] = arr[arr.length - i - 1];
                arr[arr.length - 1 - i] = temp;
            }
            return arr;
        }
        var myArr = [10, 20, 30, 40, 50];
        var res = fn(myArr);
        console.log(res);
写一个函数,既可以实现对数组排序从小到大,也可以从大到小
    function getSort(arr, flag) {
            for (var i = 0; i < arr.length - 1; i++) {
                for (var j = 0; j < arr.length - 1 - i; j++) {
                    if (flag ? arr[j] > arr[j + 1] : arr[j] < arr[j + 1]) {
                        var temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
            return arr;
        }
        var myArr = [10, 2, 30, 6, 9, -5, 0];
        //true 从小到大排序
        // var res1 = getSort(myArr,true);
        //false  从大到小排序
        var res2 = getSort(myArr, false);
        // console.log(res1);
        console.log(res2);

写一个判断平年闰年的函数
//输入一个年份,判断是否是闰年[闰年:能被4整数并且不能被100整数,或者能被400整数]
	//方法1
        function getYear(year) {
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                // true闰年
                return true;
            } else {
                //false平年
                return false;
            }
        }
        var myYear = +prompt('请输入一个年份');
        var res = getYear(myYear);
        console.log(res);
      //方法2 
       function getYear(year) {
            return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
        }
        var myYear = +prompt('请输入一个年份');
        var res = getYear(myYear);
        console.log(res);

写一个函数输入某年某月某日,判断这一天是这一年的第几天
        function getDay(year, month, day) {
            var arr = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
            if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
                arr[1] = 29;
            };
            //存储总天数
            var days = 0;
            for (var i = 0; i < month - 1; i++) {
                days += arr[i]
            }
            days += day;
            return days;
        }
        var usrYear = +prompt('请输入年')
        var usrMonth = +prompt('请输入月')
        var usrDay = +prompt('请输入日')
        var res = getDay(usrYear, usrMonth, usrDay);
        console.log(res);
写一个函数,可以随机生成十六进制颜色   ( #abcdef  );
        function getColor() {
            var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f'];
            var str = '#';
            for (var i = 0; i <= 6; i++) {
                var index = Math.floor(Math.random() * 16);
                str += arr[index];
            }
            return str;
        }
        console.log(getColor());
回调函数

如果一个函数的参数是一个函数 这个函数称之为回调函数

 	function a() {
            console.log('a中的函数');
        }
        function fn(c) {
            console.log('fn中的函数');
            c();
        }
        fn(a)
     //fn()调用后 会先执行函数里面的代码 实参a传入形参c中 实参a是个函数 函数中调用了c()也就是调用了a() 会执行a函数中的代码
自调用函数

一个函数自己调用自己

  • 常用于 匿名函数自调用
  • 语法 (匿名函数(){})();
  • 作用 开辟了局部作用域 防止全局变量污染

对象

  • 一个对象存储多个数据
  • 多个属性之间用逗号隔开
对象的声明
  • 简洁方式
    对象的初始化语法(声明的时候赋值)
    var 对象名 = {'属性名':'属性值','属性名':'属性值'}
  • 标准方式 (构造函数方式)
    var 对象名 = new Object({'属性名':'属性值','属性名':'属性值'});
对象的取值
  • 语法
    • 点语法: 对象名.属性名
    • 字符串语法 : 对象名['属性名']
  • 如果有这个属性 则获取这个属性值
  • 如果没有这个属性 会动态添加这个属性名 但是这个属性没有属性值 所以获取属性值结果是undefined
对象的赋值
  • 如果有这个属性 则是修改对应的属性值
  • 如果没有这个属性 则是动态添加属性
	var p = {
            name: 'jack',
            age: 18
        }
        var name = 'age';
        console.log(p.name);//jack
        console.log(p.age);//18
        console.log(p['name']);//jack
        console.log(p['age']);//18
        //字符串语法 取name变量中存储的字符串对应的属性值
        console.log(p[name]);//18
        var a = 'name';
        //点语法取a属性名的值 a不存在 结果是undefined
        console.log(p.a);//undefined
        console.log(p[a]);//jack

对象与数组的异同点
相同点 : 一个变量存储多个数据
不同点 :
数组 有序存储 下标与数据一一对应 下标从0开始递增
对象 无序存储 属性名与数据一一对应 (键值对)

遍历对象
  • 获取对象中所有的属性值
  • for-in循环
    for(var key in obj){}
  • key变量中存储的是对象的属性名字符串
  • 不能用点语法obj.key 获取的是key这个属性的值
  • 只能用字符串语法obj[key] (key中存储的是字符串数据)
方法中的this关键字

谁调用这个方法 this指向谁

	 var p = {
            name: 'jack',
            age: 18,
            sayHi: function () {
                console.log('我是' + this.name);
            }
        }
        //p调用 this指向p
        p.sayHi();
使用普通函数声明多个对象
 //使用函数声明多个对象
        function createPerson(name, age) {
        //声明一个空对象
            var person = {};
            //赋值 对象中不存在的属性会动态添加
            person.name = name;
            person.age = age;
            //返回对象
            return person;
        }
        var p1 = createPerson('张三', 18);
        console.log(p1);//{name: "张三", age: 18}
        var p2 = createPerson('李四', 18);
        console.log(p2);//{name: "李四", age: 18}
使用自定义构造函数声明多个对象
  • 调用函数时 前面加了new关键字
  • 优点 代码简洁
  • new关键字的作用
  1. 创建空对象
  2. 将this指向这个对象 this={}
  3. 完成对象的赋值(执行构造函数中的代码)
  4. 自动帮我们返回这个对象 return this
  		function CreatePerson(name, age) {
            //赋值 对象中不存在的属性会动态添加
            this.name = name;
            this.age = age;
        }
        var p1 = new CreatePerson('张三', 18);
        console.log(p1);//{name: "张三", age: 18}
        var p2 = new CreatePerson('李四', 18);
        console.log(p2);//{name: "李四", age: 18}

在这里插入图片描述

注意
自定义构造函数必须要用new关键字来调用
自定义构造函数的函数名一般首字母大写
如果在自定义构造函数中手动添加了return关键字
在基本数据类型中无效 在复杂数据类型中会覆盖new创建的那个对象

js对象
  • 自定义对象
    程序员自己声明的对象
  • 内置对象
    js作者提前写好的对象 里面存储了一些写好的属性和方法 方便开发者使用
    js内置对象
  • json对象
    解决跨平台兼容性问题
    所有编程语言都支持的一种对象类型 主要解决不同平台之间的数据传输
json对象

json对象与js对象的区别
json对象的属性名和属性值都要是字符串 用双引号括起来
使用上没有区别 只是数据处理方式不一样

内置对象

API(application programming interface): 对象的方法

Date对象
  • 创建时间对象
    var date = new Date()
  • 转换格式
	//根据本地时间格式,把 Date 对象转换为字符串。
        console.log(date.toLocaleString());
        console.log(date.toLocaleDateString());
        console.log(date.toLocaleTimeString());
  • 获取年月日时分秒
		console.log(date.getFullYear());//年
        console.log(date.getMonth());//月 月份范围0-11
        console.log(date.getDate());//日
        console.log(date.getDay());//星期 星期范围0-6 星期天到星期六
        console.log(date.getHours());//时 
        console.log(date.getMinutes());//分
        console.log(date.getSeconds());//秒
        console.log(date.getMilliseconds());//毫秒
Date日期对象方法描述
Date()返回当前的日期和时间
toLocaleString()根据本地时间格式,把 Date 对象转换为字符串返回当前的日期和时间。
toLocaleDateString()根据本地时间格式,把 Date 对象转换为字符串。返回当前的日期
toLocaleTimeString()根据本地时间格式,把 Date 对象转换为字符串。返回当前的时间
getFullYear()从 Date 对象以四位数字返回年份。
getMonth()从 Date 对象返回月份 (0 ~ 11)。
getDate()从 Date 对象返回一个月中的某一天 (1 ~ 31)。
getDay()从 Date 对象返回一周中的某一天 (0 ~ 6)。
getHours()返回 Date 对象的小时 (0 ~ 23)。
getMinutes()返回 Date 对象的分钟 (0 ~ 59)。
getSeconds()返回 Date 对象的秒数 (0 ~ 59)。
getMilliseconds()返回 Date 对象的毫秒(0 ~ 999)。

注意
日期对象获取的月份是从0-11
当前为7月 获取的是下标6
日期对象获取的星期是从0-6
星期天到星期六 星期天获取的是下标0

  • 创建自定义日期
    参数可以使自定义的 也可以是固定格式的时间字符串
		//自定义的参数 月份要对应日期对象的下标
		//如果当前是11月 那么要写下标10
  		var date1 = new Date(2017, 10, 3, 09, 30, 20);
        console.log(date1);
        //固定格式的时间字符串 'YYYY-MM-DD HH:mm:ss'
        var date2 = new Date('2017-11-03 09:30:20')
        console.log(date2);
Array对象
  • concat()
    拼接两个数据
    返回值: 拼接后的数组
		var arr = [63, 9, 9, 10];
        var arr1 = [10, 20];
        //concat() 拼接数组
        console.log(arr.concat(arr1));//[63, 9, 9, 10, 10, 20]
  • join()
    将数组元素拼接成字符串
    参数: 指定分隔符 默认是以逗号隔开
    返回值: 拼接之后的字符串
		var arr2 = ['我', '爱', '你', '中国']
        //join()以指定分隔符将数组拼接成字符串 默认以逗号隔开
        console.log(arr2.join());//'我,爱,你,中国'
        console.log(arr2.join('|'));//'我|爱|你|中国'
  • pop()
    删除数组的最后一个元素
    arr.length--
    返回值: 删除的那个元素
		//pop() 删除数组的最后一个元素 
        //返回值是删除的那个元素
        var arr = [63, 9, 2, 10];
        arr.pop();
        console.log(arr);// [63, 9, 2]
        var last = arr.pop();
        console.log(last);//2
  • push()
    往数组后面添加元素
    arr[arr,length]=值
    返回值: 新数组的长度
		//push() 往数组后面添加元素
        //返回值是新数组的长度
        var arr = [63, 9, 2, 10];
        arr.push(1, 2, 3);
        console.log(arr);//[63, 9, 2, 10, 1, 2, 3]
        var length = arr.push();
        console.log(length);//7
  • reverse
    翻转数组
 		//reverse() 翻转数组
        var arr = [63, 9, 2, 10];
        arr.reverse();
        console.log(arr);//[10, 2, 9, 63]
  • shift()
    删除数组的第一个元素
    返回值是删除的那个元素
//shift() 删除数组的第一个元素
        //返回值是删除的那个元素
        var arr = [63, 9, 2, 10];
        arr.shift();
        console.log(arr);//[9, 2, 10]
        var first = arr.shift();
        console.log(first);//9
        console.log(arr);//[2, 10]
  • slice(start,end)
    查找数组元素
    [开始下标,结束下标)
//slice(开始下标,结束下标) 查找数组元素 [开始下标,结束下标)
        var arr = [63, 9, 2, 10];
        console.log(arr.slice(0, 2));//[63, 9]
  • sort()
    排序 参数是一个函数
    从小到大排序 function(a,b){return a-b}
    从大到小排序 function(a,b){return b-a}
		/*sort() 排序
        参数是一个函数 
        从小到大排序 function(a,b){return a-b}
        从大到小排序 function(a,b){return b-a}
        */
        var arr = [63, 9, 2, 10];
        console.log(arr.sort(function (a, b) {
            return a - b;
        }));//[2, 9, 10, 63]
        console.log(arr.sort(function (a, b) {
            return b - a;
        }));//[63, 10, 9, 2]
  • splice()
    删除元素 并向数组添加新元素
    参数有三个
    第一个参数是删除的元素下标
    第二个参数是删除多少个元素
    第三个参数可选 要添加的新元素
    返回值是删除的元素
 		//splice(从哪里删,删几个,替换的元素)
        //返回值是删除的那个元素
        var arr = [63, 9, 2, 10];
        arr.splice(1, 1);
        console.log(arr);// [63, 2, 10]
        console.log(arr.splice(1, 1));//[2]
        arr.splice(0, 1, '替换的');
        console.log(arr);// ["替换的", 10]
数组对象的方法描述
concat()连接两个或更多的数组,并返回结果。
join()把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔
pop()删除并返回数组的最后一个元素
push()向数组的末尾添加一个或更多元素,并返回新的长度。
shift()删除并返回数组的第一个元素
unshift()向数组的开头添加一个或更多元素,并返回新的长度。
reverse()颠倒数组中元素的顺序。
sort()对数组的元素进行排序 参数是一个函数
slice()从某个已有的数组返回选定的元素 [开始下标,结束下标)
splice()删除元素,并向数组添加新元素。第一个参数是删除的元素下标 第二个参数是删除多少个元素 第三个参数可选 要添加的新元素 返回值是删除的元素
String对象
  • length属性
    字符串的长度
		//length属性 字符串的长度
        var str = '我是Denisedan';
        console.log(str.length);//11
  • charAt()
    根据下标获取对应的字符
 		//charAt() 根据下标获取对应的字符
        var str = '我是Denisedan';
        console.log(str.charAt(0));//'我'
        //也可以通过下标获取
        console.log(str[0]);//'我'
  • concat()
    拼接多个字符串
		//concat() 拼接多个字符串
        var str = '我是Denisedan';
        var str2 = '大家好';
        var res = str2.concat(str);
        console.log(res);//大家好我是Denisedan
        //也可以+号拼接
        var res2 = str2 + '我是Denisedan';
        console.log(res2);//大家好我是Denisedan
  • indexOf()
    indexOf(‘字符’) 判断字符串是否包含某个字符
    存在 返回首字符下标
    不存在 返回固定值-1
 		/*indexOf('字符') 判断字符串是否包含某个字符
        存在 返回首字符下标
        不存在 返回固定值-1
        */
        var str = '我是Denisedan';
        console.log(str.indexOf('d'));//8
        console.log(str.indexOf('6'));//-1
  • substr()
    截取字符串
    第一个参数是从哪个下标开始截取
    第二个参数是截取几个字符
		/*substr() 截取字符串 
        第一个参数是从哪个下标开始截取
        第二个参数是截取几个字符
        */
        var str = '我是Denisedan';
        console.log(str.substr(0,8));
  • replace()
    替换字符串
    第一个参数是要替换的字符串
    第二个参数是替换后的字符串
		/*replace() 替换字符串
        第一个参数是要替换的字符串 
        第二个参数是替换后的字符串
        */
        var str2 = '大家好';
        console.log(str2.replace('大家','你们'));//你们好
        //将第二个参数设置成空字符串 就是删除字符串
        var str2 = '大家好';
        console.log(str2.replace('大家',''));//好
  • toLocaleUpperCase()
  • toLocaleLowerCase()
    大小写转换
 		//大小写转换
        var str = '我是Denisedan';
        console.log(str.toLocaleUpperCase());//我是DENISEDAN
        console.log(str.toLocaleLowerCase());//我是denisedan
  • split()
    分割字符串
    将字符串中字符以固定的分隔符分割成多个字符串 并且放入数组中
    参数是指定分隔符 默认没有指定 则返回数组
 		/*split()分割字符串 
        将字符串中字符以固定的分隔符分割成多个字符串 
        并且放入数组中
        参数是指定分隔符 默认没有指定 则返回数组
        返回值一定是数组
        */
        var str = '我&是&Denise&dan';
        console.log(str.split());//["我&是&Denise&dan"]
        console.log(str.split('&'));// ["我", "是", "Denise", "dan"]
字符串对象的方法描述
charAt()返回在指定位置的字符。根据下标获取对应的字符
concat()连接字符串 拼接多个字符串
indexOf()检索字符串 判断字符串是否包含某个字符
lastIndexOf()从后向前搜索字符串。
substr()从起始索引号提取字符串中指定数目的字符。截取字符串 第一个参数是从哪个下标开始截取 第二个参数是截取几个字符
substring()提取字符串中两个指定的索引号之间的字符。不包括最后一个索引号
replace()替换与正则表达式匹配的子串。修改字符串 第一个参数是要修改的字符串 第二个参数是修改后的字符串
split()把字符串分割为字符串数组。
toLocaleLowerCase()把字符串转换为小写。
toLocaleUpperCase()把字符串转换为大写。
字符串的恒定性
  • 字符串无法被修改
  • 字符串创建后 会缓存在字符串常量区 每次创建字符串 会先去字符串常量区查找是否有相同的字符串 有则直接使用 没有则创建
		var str = '大家好';
        str[0] = '小';
        console.log(str);//大家好
  • 所有api都不会改变原先的字符串 而是生成一个新的字符串
 		var res = str.replace('大', '小');
        //字符串的api只是将字符串生成了一个新的字符串 原先的字符串没有发生改变
        console.log(res);//小家好
        // 字符串具有恒定性不会被修改
        console.log(str);//大家好
基本包装类型
  • 基本包装类型
    基本数据类型包装成引用类型

  • js为了让基本数据类型可以像对象一样调用方法 会将基本数据类型转成特殊的对象类型

       new String()
       new Number()
       new Boolean()
    

    思考 此时num是一个基本数据类型 怎么可以通过点语法调用.toString() 呢?
    var num = 10;
    num.toString();

      答: 
      编译器会将num转成new Number(10) 再去进行调用.toString()
    

字符串与字符串对象的区别
都是字符串 字符串具有恒定性
字符串是基本类型
字符串对象是基本包装

js中的转义符
转义符含义
\'单引号
\"双引号
\\反斜杠
\&&
\r回车符
\t制表符
\n换行符
\f换页符
\b退格符
逗号表达式与逗号运算符(了解)
  • 逗号运算符,
  • 逗号表达式
    (表达式1,表达式2,表达式3....)
  • 运算规则
  1. 逗号运算符的每一个式子都会执行
  2. 逗号运算式的结果是最终一个式子的结果
 		var n1 = 10;
        var n2 = 20;
        var res = (n1++ , n1 + n2)
        console.log(n1);//11
        console.log(n2);//20
        console.log(res);//31
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值