青训营笔记创作活动——js | 青训营

84 阅读7分钟

Javascript

1、javascript的组成部分。

BOM:Browser Object Model 操作浏览器的内容
DOM:Document Object Model 操作文档流的内容
EMCAscript:javascript书写的规则和语法

2、三种javascript。

// 行内样式
    // a标签书写在href属性上
    <a href="javascript:在冒号分号之间书写js代码;"></a>
    <a href="javascript:alert('hello world');">点我一下</a>
    // 非a标签书写在行为属性上
    <div onclick="alert('hello world')">点我一下</div>
// 内嵌样式(练习推荐)
    // 在script标签对内书写js代码
    <script>
       // js代码 
    </script>
    <script>
        alert('hello world')
    </script>
// 外联样式(项目推荐)
    // 在.js文件中书写js代码
    alert('hello world') 
    // html中引入js文件
    <script src="js文件路径"></script>

3、三种输出变量方式。

js代码可以不使用分号间隔喔!单行注释是//;多行注释是**\。

// 三种输出变量方式(可用于测试)
alert(num)           // 输出在弹出层上
console.log(num)     // 输出在控制台上
document.write(num)  // 输出在页面上

注意,console.log可以打印多个变量,使用console.log(num1,num2)即可。

4、空类型。

// 空类型
var num=null (null)  // 变量有值 有一个空值
var num              // 变量没有值
// 检查数据类型
var res=typeof num   // null -> object

5、数据类型转换。

// 转换为数值
var n1=Number(s1)      // 如果整体可以转换为一个合法数字则可反之则NaN
var n2=parseInt(s1)    // 如果整体可以转换为一个合法数字则可反之则截取合法片段
var n3=parseFloat(s1)  // parseFloat可以转换浮点数 而parseInt只能转换整数
// 转换为字符串
var s=String(n)
var ss=n.toString()   // 注意语法
// 转换为布尔
 var b=Boolean(nn)  // 0 NaN '' null undefined 均会被转换为false 其余均会被转换为true

6、运算符。

// == : 只比较值是不是相等 而不考虑数据类型
// ===: 既比较值是不是相等 又比较数据类型是不是相等
// 可以将上述与下述按相反理解即可
// != : 只比较值是不是不相等 而不考虑数据类型
// !==: 只要值和数据类型任何一个不相等就为true

7、控制结构。

// 选择结构
if ... else if ...
switch(...){case: ... break default: ...}
​
// 循环结构
for(...;...;...)
while(...)
do...while(...)
// 当条件在循环里面时两者一样 当条件在循环外面时当条件不满足 while一次也不执行 do...while会执行一次

8、函数。

// 函数定义
function 函数名 (形参列表)
{
    函数体
    return ...
}
// 函数调用
var res = 函数名 (实参列表)

9、作用域。

全局作用域:一个页面打开就是一个全局作用域
私有作用域:只有函数生成私有作用域 且一个函数对应一个私有作用域
定义:定义在哪一个作用域内则属于哪一个作用域
访问:该作用域内有则使用该作用域内的该变量 反之则使用父级作用域内的该变量 以此类推 全局没有则报错
赋值:该作用域内有则给该作用域内的该变量赋值 反之则给父级作用域内的该变量赋值 以此类推 全局没有定义为全局

10、对象数据类型。

// 增      对象名.键=值         对象名['键']=值   原先没有为增
// 删      delete 对象名.键     delete 对象名['键']
// 改      对象名.键=值         对象名['键']=值   原先存在为改
// 查      对象名.键            对象名['键']

11、数组数据类型。

// 数组长度  arr.length
// 获取数据  arr[index]
// 设置数据  arr[index]=value
// 遍历数组  for(var i=0;i<arr.length;i++) arr[i]

12、数组常用方法。

// 常用数组操作方法
​
数组.push(数据)      // 将数据追加到数组的末尾 返回数组的新长度
数组.pop()          // 删除数组的最后一个数据 返回被删除的数据
​
数组.unshift(数据)   // 将数据追加到数组的开头 返回数组的新长度
数组.shift()        // 删除数组的第一个数据 返回被删除的数据
​
数组.reverse()      // 反转数组 返回反转后的数组
​
数组.splice(起始索引index,长度len,要插入的数据) // 默认0 0 没有 
// 删除从index开始长度为len的数据并选择是否插入新数据 以新数组形式返回被删除的数据 原数组也会被更改
​
数组.sort()  // 排序数组 返回排序后的数组
数组.sort(function(a,b){return a-b})  // 升序
数组.sort(function(a,b){return b-a})  // 降序// 以上函数会改变原始数组
​
数组.join(连接符) //将数组用连接符连接成一个字符串 返回拼接后的字符串
​
数组.concat(其他数组) //将其他数组和数组拼接在一起 返回拼接好的新数组
​
数组.slice(开始索引,结束索引)  // 默认0 数组长度 
// 截取数组中的某些数据 以新数组的形式返回截取出来的数据 [开始索引,结束索引)
​
数组.indexOf(数据) // 查找该数据在数组中第一次出现的索引位置 没出现则为-1
​
数组.forEach(function(item,index,arr){}) // 遍历数组 元素 下标
​
数组.map(function(item,index,arr){}) // 映射数组 返回映射后的数组 按照条件统一处理数组可用
​
数组.filter(function(item,index,arr){}) // 过滤数组 返回过滤后的数组 按照要求选择数组元素可用
​
数组.every(function(item,index,arr){}) // 判断数组是不是每一项都满足条件 返回一个布尔值
​
数组.some(function(item,index,arr){}) // 判断数组是不是某一项满足条件 返回一个布尔值// 以上函数不会改变原始数组

13、字符串常用方法。

// 常用字符串操作方法
​
字符串.charAt(索引) // 获取对应索引位置的字符并返回
​
字符串.toLowerCase() // 将字符串的字母全部转换为小写 并返回转换后的字符串
字符串.toUpperCase() // 将字符串的字母全部转换为大写 并返回转换后的字符串
​
字符串.replace(换下内容,换上内容)  // 将字符串中第一个换下内容变为换上内容 并返回转换后的字符串
​
字符串.trim() // 去除首尾空格 并返回转换后的字符串
​
字符串.split(分隔符) // 按照分隔符将字符串切割为一个数组 并返回切割后的数组// 截取字符串 并返回截取后的字符串  [开始索引,结束索引)
字符串.substr(开始索引,多少个)  
字符串.substring(开始索引,结束索引)
字符串.slice(开始索引,结束索引)
​
// 以上函数均不会改变原始字符串

14、数字常用方法。

// 常用数字操作方法
​
Math.random()               // 获取[0,1)之间的随机小数
Math.round(n)               // 对数字n四舍五入
Math.ceil(n)                // 对数字n向上取整
Math.floor(n)               // 对数字n向下取整
Math.pow(底数,指数)          // 对数字进行幂运算
Math.sqrt(n)                // 对数字n求二次方根
Math.abs(n)                 // 求数字n的绝对值
Math.max(n1,n2,n3...nm)     // 求n1,n2,n3...nm最大值
Math.min(n1,n2,n3...nm)     // 求n1,n2,n3...nm最小值
Math.PI                     // 求π的近似值
获取a~b随机整数:Math.floor(Math.random()*(b-a+1))+a

15、时间常用方法。

// 常用时间操作方法var time = new Date()  // 当前电脑时间var time = new Date(年,月,日,时,分,秒)  // 月份从0开始
var time = new Date(2022,1,23,11,22,18)
// 获取信息
var year = 时间对象.getFullYear()
var month = 时间对象.getMonth()
var day = 时间对象.getDate()
var hour = 时间对象.getHours()
var minute = 时间对象.getMinutes()
var second = 时间对象.getSeconds()
var weekday = 时间对象.getDay()       // 0表示周日 1~6表示周一到周六
​
var datetime = 时间对象.getTime()     // 时间戳信息 毫秒数
// 设置信息
var year = 时间对象.setFullYear(年)
var month = 时间对象.setMonth(月)
var day = 时间对象.setDate(日)
var hour = 时间对象.setHours(时)
var minute = 时间对象.setMinutes(分)
var second = 时间对象.setSeconds(秒)
​
var datetime = 时间对象.setTime(时间戳)     

16、BOM操作。

// 浏览器的可视窗口尺寸
var width=window.innerWidth  // 可视窗口宽度
var height=window.innerHeight   // 可视窗口高度
// 浏览器的弹出层
window.alert('我是alert')   // 弹出内容
var con=window.confirm('我是confirm')  // 确认内容 确定/返回true 取消/返回false
var pro=window.prompt('我是prompt')  // 输入内容 确定/返回输入内容 取消/返回None
// 开启和关闭标签页
window.open('https://fanyi.baidu.com/')  // 开启指定页面
window.close()  // 关闭当前页
// 浏览器常用事件
window.onload=function(){}    // 资源加载完毕
window.onresize=function(){}  // 可视尺寸改变
window.onscroll=function(){}  // 滚动条位置改变
// 浏览器历史记录操作
window.history.back() //回退页面
window.history.forward() //前进页面
// 浏览器卷去的尺寸(滚动条滚上去的叫高度,滚动条滚左边的叫宽度)
// 卷去的高度
document.documentElement.scrollTop
document.body.scrollTop
var height = document.documentElement.scrollTop || document.body.scrollTop // 兼容写法
// 卷去的宽度
document.documentElement.scrollLeft
document.body.scrollLeft
var width = document.documentElement.scrollLeft || document.body.scrollLeft // 兼容写法
// 设置浏览器滚动条的位置
window.scrollTo(left,top) // left表示浏览器卷去的宽度 top表示浏览器卷去的高度 瞬间定位
window.scrollTo({left:xx,top:yy,behavior:'smooth'}) // smooth表示平滑滚动

17、定时器。

// 间隔定时器var c1=setInterval(函数,时间) //函数:每次要执行的内容 时间:间隔毫秒数 //返回是当前页面第几个定时器
// 延迟定时器var c2=setTimeout(函数,时间) // 函数:延时时间到达后要执行的内容 时间:延迟毫秒数
// 关闭定时器  clearInterval(要关闭的定时器返回值)
clearTimeout(要关闭的定时器返回值)
​
注意,不区分定时器种类。

18、DOM操作。

获取元素+操作元素。

// 获取元素    没有则为空null     Elements获取的是伪数组
document.getElementById('id名称')         // 根据id名称获取
document.getElementsByClassName('类名')   // 根据class名称获取
document.getElementsByTagName('标签名')   // 根据tag名称获取
document.querySelector('选择器')          // 根据css选择器获取第一个元素
document.querySelectorAll('选择器')       // 根据css选择器获取所有元素

操作元素内容。

// 操作元素文本内容 (不带标签)
元素.innerText  // 获取
元素.innerText='新内容'  // 设置
// 操作元素超文本内容 (带标签)
元素.innerHTML  // 获取
元素.innerHTML='新内容'  // 设置

操作元素属性。

// 操作元素原生属性
元素.属性名  // 获取
元素.属性名='属性值'  // 设置
// 操作元素自定义属性
元素.getAttribute('属性名')  // 获取
元素.setAttribute('属性名','属性值') // 设置
元素.removeAttribute('属性名')  // 删除

操作元素类名。

元素.className    // 获取
元素.className='新类名'   // 设置

操作元素行内样式。(样式名中如果包含-则改写为驼峰名)

元素.style.样式名   // 获取
元素.style.样式名='样式值'   // 设置

获取元素非行内样式。

window.getComputedStyle(元素).样式名  //也可以获取行内样式

创建设置元素。

document.createElement('标签名称')   // 创建节点
父节点.appendChild(子节点)  // 插入节点 插入到父元素尾部
父节点.insertBefore(要插入的节点,哪一个节点的前面)  //插入节点 插入到指定节点的前面
父节点.removeChild(子节点) // 删除节点 从父节点内删除某一个子节点
节点.remove()  // 删除节点 删除自己
父节点.replaceChild(换上节点,换下节点) // 替换节点
节点.cloneNode(是否克隆后代节点) // 克隆节点

获取元素尺寸。

// 获取元素 内容+padding+border 区域尺寸
​
元素.offsetHeight
元素.offsetWidth
​
// 获取元素 内容+padding 区域尺寸
​
元素.clientHeight
元素.clientWidth

19、事件。

// 事件绑定的三要素1、事件源:和谁做好约定;
2、事件类型:约定一个什么行为;
3、事件处理函数:当用户触发该行为的时候执行什么代码;
​
事件.on事件类型 = 事件处理函数
// 鼠标事件
​
click // 鼠标单击
dbclick // 鼠标双击
contextmenu // 左键单击
mousedown // 鼠标按下
mouseup // 鼠标抬起
mousemove // 鼠标移动
mouseover // 鼠标移入
mouseout // 鼠标移出
mouseenter // 鼠标移入
mouseleave // 鼠标移出
// 键盘事件
​
keydown // 键盘按下
keyup // 键盘抬起
keypress // 键盘输入
// 浏览器事件
​
load // 加载完毕
scroll // 滚动
resize // 尺寸改变
// 触摸事件
​
touchstart // 触摸开始
touchmove // 触摸移动
touchend // 触摸结束
// 表单事件focus // 聚焦
blue // 失焦
change // 改变
input // 输入
submit // 提交
reset // 重置

事件对象。

div.onclick=function(e){
    console.log(e)  // e是事件对象
} 

鼠标对象。

offsetX offsetY  // 鼠标相对于触发元素位置
clientX clientY  // 鼠标相对于浏览器可视窗口位置
pageX pageY  // 鼠标相对于页面文档流位置

键盘对象。

KeyCode // 键盘编码 表示触发的是哪一个键盘

事件传播。

// 浏览器响应事件的机制1、浏览器窗口最先知道事件的发生;
2、捕获阶段:从window按照结构子级的顺序传递到目标
3、目标阶段:准确触发事件的元素接收到行为;
4、冒泡阶段:从目标按照结构父级的顺序传递到window5、本次事件传播结束;
​
e.stopPropagation() // 在内部元素阻止传播

事件委托。

// 将自己的事件委托给父级结构的某一层
​
e.target // 获取事件目标
e.target.tagName // 获取事件目标的标签名 其为标签大写字母// 如果点击每一个子元素都会触发则将事件绑定在父元素上 同时在事件内部进行判断 是子元素触发的才做出处理
​
e.target.dataset.name // data自定义属性名前半部分 name自定义属性名后半部分

20、面向对象。

面向过程:按照事情执行的先后顺序;面向对象:按照事情执行的角色分配。

// 创建对象
1var obj={} //字面量方式创建对象
2var obj=new Object() //内置函数方式创建对象
// 前两种方式不擅长批量生产对象
3function createObj(){
    // 手动创建对象
    var obj={}
    // 手动添加属性
    obj.key=value
    // 手动返回对象
    return obj
}
var obj=createObj() //工厂函数方式创建对象(对象内容均一样)  //可通过传递参数的方式使其不一样
4function createObj(){
    // 自动创建对象
    // 手动添加属性
    // this指向的是调用该函数的对象
    this.key=value
    // 自动返回对象
}
var obj=new createObj() //构造函数要与new关键字连用  //可通过传递参数的方式使其不一样

构造函数。

1、构造函数在使用的时候需要与new关键字连用;
2、构造函数函数名首字母大写(一般规范);
3、如果构造函数不需要传递参数那么可以不使用小括号(不推荐);
4、函数内部的this指向当前实例即当前调用该函数的对象;
5、构造函数中return基本数据类型无意义而return复杂数据类型则构造函数白写;

每创建一个对象,构造函数中的方法就会被重复创建一次,这样会造成空间的浪费。

引入 ——> prototype原型。

1、每一个函数都有一个自带的属性prototype,其是一个对象,构造函数也是函数,其也有属性prototype,我们可以使用对象操作的方法,向prototype中添加一些内容。
2、每访问一个对象的属性时,如果其没有,其就会去其所属构造函数的原型上去查找;构造函数创建出来的也是对象,当访问其属性时,如果其没有,就会去其原型上查找;
3、这样只要将方法添加在构造函数的原型上,那么创建不同对象时就只会创建一次函数,解决上述问题;
1、每一个对象都有一个自带的属性__proto__,其指向所属构造函数的prototype;
2、Person.prototype===p1.__proto__; // true
3、每访问一个对象的属性时,如果其没有,其就会去其__proto__上去查找;
4、同一构造函数创建出来的不同对象,其__proto__指向的是同一个对象,保存着方法;
注意:ObjectFunction本身是构造函数!函数本身也是对象!
1、实例对象的__proto__指向的是所属构造函数的prototype;
2、构造函数的prototype对象的__proto__(其是Object)指向的是Object(内置构造函数)的prototype;
3、内置函数Object的prototype对象(所有对象都是Object实例)的__proto__指向的是Null(顶级原型);
4、构造函数(函数本身也是一个对象)的__proto__指向的是Function(所有函数是其实例)的prototype;
5Object(既是内置构造函数又是对象)的__proto__指向的是Function的prototype;
6Function的prototype对象的__proto__指向的是Object的prototype;
7Function的__proto__指向的是Function的prototype;
注意:所有函数均是Function实例!所有对象均是Object实例!

注意:使用__proto__串联起来的对象链状结构叫做原型链。原型链提供了一种对象访问机制,即如果访问一个对象的成员时,其首先在自己身上查找,如果有则直接使用,反之会自动去__proto__上查找,如果还没有,就继续去__proto__上查找,直至顶级原型Object的的prototype对象都没有,那么就返回undefined。

21、预解析。

Javascript是解释型语言。预解析指的是:将使用var定义的变量的声明部分提前到script头部,即假设定义name变量,那么在name被赋值之前输出name,其会显示undefined,而不是报错;将使用声明式定义的函数其也会提前到script头部,即假设定义function f1(){}函数,那么在其之前调用f1(),其也会正常调用函数,但是使用赋值方式定义的函数就会报错,比如var Func=function(){},其在定义之前调用Func()就会报错。这也叫做变量提升或者函数提升。

注意函数和变量重名问题:
​
var age=100
function age(){}
console.log(age)
​
其具体执行流程是:
var age 
function age(){}
age=100

注意:变量提升和函数提升只针对同一个script中有效!同时也需要注意函数中的变量其变量提升在函数作用域!

22、闭包。

如果函数有返回值且返回值为复杂类型并且赋值给外面的变量则不会被销毁内存空间,如果后面想销毁该对象则直接将其赋为空即可被销毁从而不会导致内存泄露。

闭包指的是函数内部返回一个函数,其被外界所引用,使得这个内部函数不会被销毁回收,且内部函数所用到的该内部函数的外部变量也不会被销毁。

function outer()
{
    var name="wxm"
    return function(){
                return  name+"666666"
    }
}
var func=outer()
console.log(func())  //wxm666666
func=null
​
优点:让临时变量永驻内存。

使用闭包记录列表下标:

for(var i=0;i<myli.length;i++)
{
    myli[i].onclick=(function(index){
        return function(){  //返回值为函数 使用外部的index变量
              console.log(index)
        }
    })(i)  //匿名自执行函数
}

23、函数防抖与节流。

函数防抖指的是,在一定时间内连续多次触发事件,方法只在最后一次触发事件的时候执行,比如jsonp中的输入查询内容,不是每输入一个字符就查询,而是间隔一定的时间执行。

函数节流指的是,一个方法在一段时间间隔内只执行一次,比如点淘宝抢购,可是有一段时间点了没效果。

防抖是将多次执行变成最后一次执行,而节流是将多次执行变成每间隔一段时间执行。