JS知识点总结(1)

98 阅读16分钟

1.JS的基本概念

JavaScript是运行在客户端浏览器的解释型、弱类型、面向对象的脚本语言

编程语言分类

  • 按翻译的方式:
  1. 编译型:程序运行前先检查语法是否正确,正确则运行,否则不允许运行,语法严格
  2. 解释型:程序运行前不需要检查语法是否正确,直接运行,遇到错误则停止后续代码,语法宽松
  • 按严格程度
  1. 强类型:变量保存的数据,是由定义的数据类型决定的
  2. 弱类型:变量保存的数据可以是任意类型,数据类型由数据本身决定
  • 按编程的核心分类
  1. 面向过程
  2. 面向对象:常使用的写法:对象名.属性名;对象名.方法名();

组成部分

  • BOM:Browser Object Model 浏览器对象模型,用来操作浏览器
  • DOM:Document Object Model 文档对象模型,可以用js来操作HTML和CSS
  • ECMAScript 核心语法(算法题/逻辑题)

DOM树概念:DOM将我们的HTML看做了是一个倒挂的树状结构,但是树根不是html标签,而是document对象
document对象:不需要我程序员创建的,由浏览器的js解释器自动创建,一个页面只有一个document
作用:可以通过树根找到我们想要的任何一个DOM元素/节点/对象(属性和方法)
DOM会将页面上每个元素、属性、文本、注释都会当作一个DOM元素/节点/对象

查找元素

  1. 通过ID查找元素 语法:var elem=document.getElementById("id值"); 特殊:
    1. 返回值,找到了返回的是一个当前找到的DOM元素;没找到,返回一个null,做了别的操作可能就会报错
    2. 找到了多个相同的id,那么只会返回第一个
    3. 一次只能获取一个元素,也只能操作一个元素
    4. 其实根本不需要使用此方法,直接写ID也可以找到元素
  2. 通过标签名查找元素 语法:var elems=document/已经找到了的父元素.getElementsByTagName("标签名"); 特殊:
    1. 返回值:找到了返回的一个是类数组DOM集合(很像数组,都能用下标,都能用length,都能遍历),没找到返回一个空集合
    2. JS不能直接操作DOM集合,只能直接操作DOM元素,解决:要么使用下标拿到某一个元素,要么使用遍历拿到每一个元素
    3. 不一定非要从document开始查找,如果document去找,会找到所有的元素,可以换成我们已经找到的某个父元素,就只会找到这个父元素下面的元素了
  3. 通过class名查找元素 语法:var elems=document/已经找到了的父元素.getElementsByClassName("标签名"); 等同于通过标签名查找元素
  4. 通过关系查找元素:
    前提条件:必须先找到一个元素才可以调用关系网
  • 父元素:elem.parentNode;
  • 子元素:elem.children; (找到的是一个子元素集合)
  • 第一个儿子:elem.firstElementChild;
  • 最后一个儿子:elem.lastElementChild;
  • 前一个兄弟:elem.previousElementSibling;
  • 后一个兄弟:elem.nextElementSibling;

操作元素

前提:找到元素才能操作元素: <标签 属性名="属性值" style="样式">内容</标签 >

1.内容:

  1. innerHTML:获取 和 设置 开始标签到结束标签之间的内容 - 支持识别标签 获取:elem.innerHTML; 设置:elem.innerHTML="新内容";
  2. innerText:获取 和 设置 开始标签到结束标签之间的文本 - 不支持识别标签 获取:elem.innerText; 设置:elem.innerText="新文本"; 以上两个属性都是为双标签准备的,但是操作不了单标签input的内容
  3. value:专门为input的value值准备的 获取:input.value; 设置:input.value="新值";

2.属性: 获取属性值:elem.getAttribute("属性名"); 设置属性值:elem.setAttribute("属性名","属性值");

简化版: 获取属性值:elem.属性名; 设置属性值:elem.属性名="新属性值"; 缺陷: 1.class必须写为className - 2015年过后,ES6诞生过后,class变成了一个关键字 2.不能操作自定义属性,只能操作标准属性

3.样式 使用样式的方式: 1.内联/行内样式 2.内部样式表 3.外部样式表 二阶段我们就是要用js来操作【内联样式】 1.不会牵一发动全身 2.优先级最高

获取:elem.style.css属性名; 设置:elem.style.css属性名="css属性值"; 特殊: 1.css属性名,有横线的地方,去掉横线,变为小驼峰命名法 如:border-radius -> borderRadius 2.目前学习的,获取时,只能获取内联样式

4.绑定事件: elem.on事件名=function(){ 操作; ==this==关键字:目前只能用于事件内: 如果单个元素绑定事件:this->这个元素 如果多个元素绑定事件:this->当前触发事件的元素 }

总结: 获取 - 往往都是用与判断比较 设置 - 就是添加/修改

扩展:计算字符串 - 脱字符串的衣服: eval(str);

2.引用js的方法

  • 行内式:
    • a标签:书写在href属性上 如,<a href="javascript: alert('hellow world')">点我一下</a>
    • 非a标签:书写在行为属性上 如,<div onclick="alert('hello world')">点我一下</div>
  • 内嵌式: 在body中添加<script> </script> 在标签内直接书写JS代码 (直接执行,不需要依赖任何行为)
  • 外链式: 在body中输入<script src="XXX.js"></script> 另建XXX.js文件直接书写js代码 (直接执行,不需要依赖任何行为)

注意:script标签只要有了src属性,标签之间不能再写代码

3.js的输出方式

  1. 在控制台输出日志 console.log() 在F12控制台显示日志
  2. 在页面输出日志 ducument.write()/ducument.writeIn() 在页面上输出,而且支持识别标签; 但如果绑定了点击事件后输出,会把页面上原来的HTML和CSS都全部替换掉
  3. 在警告弹出框输出日志 alert()/window.alert() 在一个浏览器自带的弹出框中输出日志,但是弹出框会卡住页面,用户只能看到一个白板

4.变量

用来保存程序运行过程中的中间值,创建后可以再次修改 var nub=100; var是容器 nub是自定义的容器名字 在js中=的含义是赋值 一个变量只能储存一个值,当新写入值时,会清除原来的值 例:

<script>
   var num=100
   alert(num)
   var num=200
   alert(num)
   // 会先弹窗显示100,点击确定后显示200,此时变量num的值为200
</script>

变量命名规则:

  1. 由数字、字母、下划线、$组成
  2. 不能以数字开头
  3. 严格区分大小写
  4. 不能使用==关键字==或==保留字==(目前还不是关键字,以后可能是关键字的字),如 var for function等js中有特殊意义的单词
  5. 最好是使用一些有语义的单词,能直观展示变量的内容,建议下划线命名法或小驼峰命名法

注意: 如果变量名为name,自动转为字符串数据类型 可以在一条语句里面,声明多个变量,用逗号分隔

用户输入弹出框 var user=prompt("提示文字","默认值")

常量

常量,值不能改变 使用const关键字声明一个常量 习惯上,常量名使用纯大写形式

const PI = 3.1415926;
//常量的值是不能改变的。
PI = 3.1416 ;
console.log( PI);
//报错,无法改变常量的值

5.数据类型

  • 基本数据类型:
    • 数值类型Number
      var num=2e5 科学计数法 2 * 10的五次方
      var num=0x100 十六进制
      var num=0o100 八进制
      var num=0b100 二进制
      NaN:
    1. not a number 不是一个数值
    2. 表示存储数据是数值类型的数据,但不是一个数值
    3. NaN参与任何算数运算结果为NaN
    4. NaN参与任何比较运算结果为false
    5. 因此↑,判断是否为NaN不能用== 或 === ,而使用 isNaN(需要判断的对象)==true则为NaN
    • 字符串类型String
      包含在引号内的数据(不区分单引号双引号) var s='hello world' var s="好好学习,努力赚钱" 注意:页面上的一切东西,数据类型默认都是一个字符串
    • 布尔类型Boolean
      var b=true 真 var b=false 假
    • 空类型Null
      var k=null null表示有值,有一个空值,用于释放变量/内存,节约内存空间
    • 未定义型Undefined
      var k undefined表示没有值
  • 引用/对象数据类型:11个引用类型的对象 object 对象
    function 函数
    array 数组
    ...

数据类型检测
语法: typeof 要检测的变量
结果:该变量存储的数据的数据类型(这个结果的数据类型是字符串)
检测返回值
数值类型 返回 number
字符串类型 返回 string
布尔类型 返回 boolean
undefined 返回 undefined
null 返回 object

6.数据类型的转换

  • 转数值

    1. Number(需要转化的对象)
      所有数据类型都可以转换,完全等效于隐式转换
    2. parseInt(需要转化的对象)
      字符串和小数转为整数型数字,从左向右依次读取每个字符,碰到非数字字符,就停止转换,如果一来就碰到了不认识的,则为NaN
    3. parseFloat(需要转化的对象)
      执行原理同parseInt,可以识别第一个小数点
    4. 隐式转换(X-0 X*1 X/1 X%1)
      true->1 false->0 undefined->NaN null->0 ''->0
  • 转字符串

    1. String(需要转化的对象)
    2. 需要转化的对象.toString()
      注意:undefined或null不可用,因为两者都不能使用任何的.操作
    3. 隐式转换(X+'')
  • 转布尔

    1. Boolean(需要转化的对象)
      注意:除了0 NaN '' undefined null转化为false;其他都会转化为布尔数据true
    2. 隐式转换(!!X)

7.js运算符

算数运算符 进行数学运算的符号
赋值运算符 进行赋值操作的符号
比较运算符 进行比较运算的符号
逻辑运算符 进行逻辑运算的符号
自增自减运算符 单独对一个变量进行+1或-1操作的符号

  • 算数运算符:具有隐式的数值类型转换(当字符串为纯数字的情况下,转为数值类型,如果字符串包含了非数字字符,直接转为NaN)
    +正常为加法数学运算,当符号任意一边是字符串的时候,就会进行字符串的拼接
    -*/%分别是减法、乘法、除法、取余的数学运算
    取余运算的运用:
    1.判断奇偶性:num%2,结果为0说明是偶数,结果为1说明奇数
    2.获取一个数字的倒数n位
  • 赋值运算符:
    = 进行赋值操作
    += 加等于 例如n1+=3 相当于n1=n1+3
    -= 减等于
    *= 乘等于
    /= 除等于
    %= 取余等于
  • 比较/关系运算符:结果一定是布尔数据true或false
    • 常规比较:
      > 大于
      < 小于
      >= 大于等于
      <= 小于等于
    • 特殊比较:
      == 等于比较 只比较值是否相等,不考虑数据类型
      === 全等于比较 值和数据类型都相同
      != 不等于比较
      !== 不全等于比较
      想要判断多个条件,只能运用逻辑运算符
  • 逻辑运算符:符号两侧只能是布尔数据
    && 与运算 必须符号两边都为true,最终结果才是true
    || 或运算 只要符号任意一边是true,最终结果为true
    ! 非运算 本身是true结果为false,本身是false结果为true(取反运算)
  • 自增自减运算符:
    ++ 自增 在自身基础上+1
    前置++:先改变变量值,再参与运算
    后置++:先参与运算,再改变变量值
    -- 自增 在自身基础上-1
    前置--
    后置--

关于NaN的运算:
console.log ( '北京'-100=='北京'- 100 );//false;左侧'北京'-100结果是NaN;右侧'北京'-100 结果是NaN;NaN≠NaN
console.log ( '北京'+100=='北京'+ 100 );//true;执行字符串拼接,结果是true;

8.条件分支语句

程序的流程控制语句:3种
1、顺序执行 - 默认,从上向下的依次执行
2、分支结构 - 通过条件的判断,选择部分代码执行
3、循环结构 - 通过条件的判断,选择要不要重复执行某些代码

  • if语句
    if(){} 条件满足就执行if的{},不满足不执行
    if(){}else{} 条件满足就执行if的{},不满足就执行else的{}
    if(){}else if(){} 哪一个条件满足就执行哪一个if的{},前面条件满足了,就不考虑后面的条件
    if(){}else if(){}else{} 多个条件依次判断是否满足,满足则执行if的{},所有条件都不满足,执行else的{}
    在()中书写条件
    在{}中书写条件满足时执行的代码

9.循环结构语句

循环结构:反复执行【相同或相似】的操作时使用
循环三要素:
1.循环条件:开始 - 结束,循环的次数
2.循环体:做的操作是什么
3.循环变量:记录着我们当前在哪一次,而且他会不断的变化,往往都会向着不满足循环条件进行

  • while语句
    语法:
    var 循环变量=几;
    while(循环条件){
    循环体;
    循环变量变化;
    }
    执行原理:首先创建了循环变量,然后判断条件,如果条件满足,则做【一次】循环体操作,并不会退出循环,回过头继续判断条件是否满足,如果满足,则再做【一次】循环体操作.直到循环条件不满足,才会退出循环
    宏观上感受循环一瞬间就结束了,但是微观上来说其实是【一次一次】执行的

特殊:
1.死循环:永远不会停下来的循环
何时使用:不确定循环次数的时候
while(true){
循环体;
}
2.退出循环语句:break - 只能在循环中使用,多半都是搭配死循环使用的

  • for语句
    语法:
    for(var 循环变量=几;循环条件;变量的变化){
    循环体;
    }
    死循环:
    for(;;){
    循环体;
    }

面试题:while 和 for 的区别?
语法上有区别,但两者都能做到相同的操作
一般来说我们不确定循环次数的时候,会使用while循环 - 死循环
一般来说我们确定循环次数的时候,就用for循环 - 更漂亮更简洁,大部分情况都会使用它

10.函数

Function:函数,称之为方法:需要提前【预定义好】的,以后就可以【反复使用】的【代码段】

定义/声明/创建函数: function 函数名(){ 函数体; } 调用/使用函数:

  1. 要么在js中程序员直接写死,要执行几次:函数名();
  2. 交给用户绑定在某个元素上,写上点击事件,让用户来触发

何时使用:

  1. 不希望打开页面立刻执行,而需要时再使用或由用户触发
  2. 希望能够反复执行,不用刷新页面
  3. 以后任何一个独立的功能体,都要单独封装为一个函数(你的每一个作业)
  4. 函数的地位非常高,函数是第一等公民地位,随时随地考虑能不能封装为一个函数,尤其是重复的代码
  5. 函数内的一切内存,函数调用完毕后都会自动释放

带参数的函数 定义:function 函数名(形参1,形参2,...){ 函数体; } 调用:函数名(实参1,实参2,...)
形参:形式参数,其实就是一个变量,但是不需要写var,而且默认也没有保存任何值,默认值为undefined
实参:实际参数,真正的值,需要再你调用时再传入
注意:

  1. 传实参的顺序一定要和形参的顺序一一对应,并且数量也要对应
  2. 不是一定要带参数的函数才是好函数,具体情况,需要具体分析:
    如果函数体就是固定的,则使用普通函数
    如果函数体希望根据传入的实参不同,做的略微不同,则使用带有参数的函数

11.数组

场景: 当需要保存多个数据时,不推荐使用变量,因为变量其实就是我们所谓的内存,变量创建的越多,那么我们内存空间消耗就越大,那么网站的性能就会越差.这种情况就使用数组.

定义:创建一个变量可以保存【多个数据】的集合 数组都是线性排列,除了第一个元素,每个元素都有唯一的前驱元素 除了最后一个元素,每个元素都有唯一的后继元素 每个元素都有一个自己的位置,称之为叫做下标(索引),下标是从0开始的,到最大长度-1 与对象不同点:不需要键名,自带顺序

创建一个数组 1.直接量方式:
var arr=[];//空数组
var arr=[数据1,数据2,...];
2.构造函数方式:
var arr=new Array();//空数组
var arr=new Array(数据1,....);//注意:此方法只写一个值的时候为数组长度,即一个定义了数组长度的空数组

数组具有三大不限制

  1. 不限制元素的个数
  2. 不限制元素的类型
  3. 不限制元素的下标越界 如果获取元素,下标越界,返回的一个undefined 如果添加元素,下标越界,会得到一个稀疏数组,导致下标不再连续,如果搭配上循环去遍历每一个元素的话,我们会得到很多很多的undefined

数组的操作

  • 长度的操作
    • 获取长度 arr.length 其值为最大下标+1
    • 设置长度 arr.length=数值 长度小于原数组长度时,会按照顺序删除靠后的数据
    • 三个固定套路: 1. 获取倒数第n个元素:arr[arr.length-n] 2. 始终向末尾添加元素:arr[arr.length]=新值; 3. 缩容:删除倒数n个元素:arr.length-=n
  • 数据的操作
    • 获取数据 arr[索引值]
    • 设置数据 arr[索引值]=数值 下标处没有元素为添加,有则替换

数组的遍历 从头到尾依次访问数组的每一个数据即遍历 利用循环进行遍历,开始为0,结束为小于数组长度,步长为1,使用循环控制变量当做数组的索引来访问数组中的每一个数据

for(var i=0;i < arr.length;i++){
   console.log(arr[i])
}