JavaScript笔记

JavaScript笔记

js组成

  • ECMAScript
    • js语言基础
  • Web APIs
    • DOM:页面文档对象模型
      操作文档,比如对页面元素的移动、大小、添加和删除
    • BOM:浏览器对象模型
      操作浏览器,比如页面弹窗,检测窗口宽度、存储数据到浏览器等等

书写位置

  • 行内

    • 在body标签上方
    • 通常写在底部
  • 内部

    • 写在标签内部
  • 外部

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

注释

    //单行注释
    /*
    多行注释
    */

;可加可不加

输入输出

输出

    document.write('内容')
    document.write('<h1>内容</h1>')

    alert('弹出内容')

    console.log('控制台打印')

输入

弹出对话框:

prompt('请输入你的名字:')

返回字符串

alert()与prompt()优先被执行,其他按文档流顺序执行

字面量

字面量是在计算机中描述事/物

变量

声明:

let var = 19, name = '张三'
var = 18

命名规范

  • 不能关键字
  • 只能下划线、字母、数字、$组成,不能数字开头
  • 严格区分大小写

规范:

  • 首字母小写,后面每个单词大写

数组

    let array = []
    let array = [1, 2, 3]
    let array = ['array', 'tete', 'tt']
    array[0]
    array.length

编号从0开始

常量

const G = 9.8

声明时必须赋值

数据类型

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

number

±*/%
加减乘除取模

string

  • 推荐使用’’
  • \为转义字符
  • 用+拼接字符串与变量

模板字符串

let age = 20
`我今年$(age)岁`

boolean

true
false

undefined

只声明不赋值就是该类型

null

把null作为尚未创建的对象

数据类型检测

typeof x
typeof(x)

类型转换

  • 隐式转换

      2 + '2' = '22'
      2 -'2' = 0
      +'123' = 123    //转换为number
    

任何数据类型和字符串相加为字符串
‘’、null转换为0,undefined转换为NaN

  • 显示转换

      Number(数据)
      parseInt(数据)  //只保留整数
      parseFloat(数据)    //可以保留小数
    

运算符

  1. 赋值

     =
     +=
     /=
     -=
     *=
     %=
    
  2. 一元

     正负号
     ++
     --
    
  3. 比较

     >
     <
     >=
     <=
     ==
     === 类型与值相同(推荐使用)
     !==
    
  4. 逻辑运算符

     &&  与
     ||  或
     !   非
    
  5. if

     if () {
    
     } else {
    
     } else if () {
    
     }
    
  6. 三元

     条件 ? 代码1 : 代码2
    

数字补0:

num = num < 10 ? 0 + num : num
  1. switch

    switch () {
    case 值1:
    代买1
    break
    default:
    代码n
    break
    }

循环

 while () {
    continue
    break
}

for (变量起始值; 终止条件; 变量变化量) {

}

数组

a[i] = 1
a.push()    //结尾添加新值,返回length
a.unshift() //开头添加
a.pop()     //结尾删除
a.shift()   //开头删除
a.splice(下标,删除个数)

函数

function 函数名(参数=0) {   //可以给默认值
        return 0
}

匿名函数

  1. 赋值

     let fn = function() {
    
     }
     fn()
    
  2. 立即执行

     (function () {})();
    

逻辑中断

&& 左边为false就短路
|| 左边为true就短路

转换为boolean

Boolean()   //0、''、undefined、false、null、NaN为false,其他为true

对象

let object = {
    属性名: 属性值,
    方法名: 函数
}
let object = new Object()

object.属性名           //查询
object['属性名']        //查询
object.属性名 = 值      //增加/修改
delete object.属性名    //删除

delete.func()           //方法

for (let k in object) {
    console.log(object[k])
}

内置对象

Math.random()
Math.cell()
Math.floor()
Math.max()
Math.min()
Math.pow()
Math.abs()

Web APIs

let or const
const优先,尽量使用const
建议数组和对象使用const声明

DOM

文档对象模型
操作网页内容,开发网页内容特效和实现用户交互

DOM树

将HTML文档以树状结构直观表现出来
直观体现了标签与标签之间的关系

DOM对象

浏览器根据HTML标签生成的js对象
标签属性在js对象上找到

核心思想:把网页当作对象处理

document对象

用来访问和操作网页内容
网页所有内容都在document里面

获取DOM对象

  • 通过CSS选择器来获取DOM元素

  • 其他

      document.querySelector('css选择器') //返回第一个元素
    
      document.querySelectorALL('css选择器')  //返回对象集合(数组),有长度有索引号  
    
      const lis = document.querySelector('.nav li')
      for (let i = 0; i < lis.length; i++) {
          console.log(lis[i])
      }
    
      document.getElementById('nav')
      document.getElementsByTagName('div')
      document.getElementsByClassName('w')
    

操作内容

对象.innerText属性  //修改内容,不解析标签
对象.innerHTML属性  //修改内容,会解析标签

修改元素内容

操作常用属性

  • href
  • title
  • src

操作样式属性

对象.style.属性 = 值

多组单词改为小驼峰

box.style.width = '300px'
box.style.backgroundColor = 'hotpink'

操作类名操作css

元素.className = 'active'   //替换

通过classList操作css

元素.classList.add('类名')  //追加
元素.classList.remove('类名')   //删除
元素.classList.toggle('类名')   //切换,有就删除,没有就加上

操作表单属性

表单.value = '用户名'
表单.type = 'password'

修改true/false:

  • disabled
  • checked
  • selected

自定义属性

data-开头的都是自定义属性

<div data-id = "1"></div>

const one = document.querySelector('div')
console.log(one.dataset.id)

定时器-间隙函数

let n = setInterval(函数, 间隔时间) //单位毫秒
clearInterval(n)

事件监听

给DOM元素添加事件监听

元素.addEventListener('事件类型', 函数)
  • 事件源:哪个DOM元素被事件触发了

  • 事件类型:click,mouseover

  • 事件调用函数

  • DOM L0

      事件源.on事件 = function () {}
    
  • DOM L2

      事件源.addEventListener(事件, 事件处理函数)
    

区别:on会被覆盖,addEventListener可以绑定多次

调用事件:

next.click()

事件类型

  • 鼠标事件(鼠标触发)
    • click
    • mouseenter
    • mouseleave
  • 焦点事件(表单获得光标)
    • focus
    • blur
  • 键盘事件(键盘触发)
    • Keydown
    • Keyup
  • 文本事件(表单输入触发)
    • input

事件对象

事件绑定的回调函数第一个参数就是事件对象

元素.addEventListener('click', function (e) {})

e为事件对象

常用属性

  • type:事件类型
  • clientX/clientY:获取光标相对于浏览器可见窗口左上角位置
  • offsetX/offsetY:获取光标相对于当前DOM元素左上角位置
  • key:用户按下的键盘键的值,不提倡用keyCode

trim方法

str.trim()

str的前缀与后缀空格去除

环境对象

函数内部特殊变量this,代表函数运行时所处环境(谁调用this就是谁,比如被加入事件函数的元素)

function fn() {
    console.log(this)   //这里this为window
}

window.fn() //等同于fn()

回调函数

函数A作为参数传递给函数B,则A为回调函数

:checked伪类

.ck:checked {
    // 选择被勾选的复选框
}

事件流

  • 捕获阶段

Document->html->body->div

  • 冒泡阶段

div->body->html->Document

事件捕获

从DOM根元素开始执行对应事件
addEventListener第三个参数为true代表捕获阶段触发,默认为false冒泡
L0事件监听只有冒泡

事件冒泡

一个元素的事件被触发,同样的事件会在该元素所有祖先元素中依次被触发

阻止冒泡

事件对象.stopPropagation

阻止事件流动(包括冒泡与捕获)

解绑事件

  • on事件方法,用null覆盖

  • removeEventListener(匿名函数无法解绑)

      元素.removeEventListener('事件类型', 函数名[, false)
    

mouseover、mouseout、mouseenter和mouseleave

  • mouseover和mouseout有冒泡效果
  • mouseenter和mouseleave没有冒泡效果

事件委托

是一种技巧
利用事件冒泡特点

即给父元素注册事件

e.target    //事件对象的元素对象
e.target.tagName    //事件对象的元素

if (e.target.tagName === 'LI') {    //注意大写
    e.target.style.color = 'red'
}

阻止默认行为

比如阻止链接的跳转/表单域的跳转

e.preventDefault()

其他事件

  • 页面加载事件

      window.addEventListener('load', function () {
    
      })
    
      img.addEventListener('load', function () {  //也可以针对某个资源绑定
    
      })
    
    
      document.addEventListener('DOMContentLoaded', function () { //无需等样式表、图像完全加载
    
      })
    
  • 页面滚动事件

      window.addEventListener('scroll', function () {
    
      })
    

属性(没有单位,可以修改):

  • scrollLeft
    距离左边滚动距离

  • scrollTop
    距离上边滚动距离

    div.add...
    div.scrollTop
    
    window.addEventListener('scroll', function () {
        const n = document.documentElement.scrollTop
    })
    
  • 页面尺寸事件

      window.addEventListener('resize', function () {
    
      })
    

检测元素宽度(不包括边框、margin和滚动条):

document.documentElement.clientwidth
div.clientwidth

元素尺寸位置

获取宽高,包含padding、border:

  • offsetWidth
  • offsetHeight

如果是隐藏的,为0

获取位置,只读,相对于最近一级带有定位的祖先元素的左、上:

  • offsetLeft
  • offsetTop

属性选择器

input[value] {
    color: red;
}

input[type=text] {
    color: red;
}

<input type="text" value="123">
<input type="password">

const input = document.querySelector('input[value]')

日期对象

实例化

const date = new Date()
const date1 = new Date('2022-5-1 08:30:00')

时间对象方法

getFullYear()   //获取四位年份
getMonth()      //0~11
getDate()       //获得月份中的每一天
getDay()        //获取星期,0~6,0为星期天
getHours()      //0~23
getMinutes()    //0~59
getSeconds()    //0~59

const date = new Date()
date.toLocaleString()   //2022/4/1 09:41:21
date.tolocaleDateString()
date.toLocaleTimeString()

时间戳

毫秒数
1970/01/01 00:00:00开始的毫秒数

  • getTime()方法

      const date = new Date()
      date.getTime()
    
  • +new Date()

      console.log(+new Date())
    
  • Date.now()

      Date.now()
    

节点操作

DOM节点

DOM数中每个节点都为DOM节点

  • 元素节点
    • 所有标签
    • html为根节点
  • 属性节点
  • 文本节点
  • 其他

查找节点

根据节点关系查找目标节点

  • 父节点

      子元素.parentNode   //dom对象
    
  • 子节点

      父元素.childNodes
      父元素.children     //所有元素节点,然会伪数组
    
  • 兄弟节点

    .nextElementSibling
    .previousElementSibling

增加节点

  • 创建节点

      document.createElement('标签名')
    
  • 增加节点

      父元素.appendChild('子元素')
      父元素.insertBefore(要插入的元素, 在哪个元素前面)
    
  • 克隆节点

    元素.cloneNode(boolean) //true会复制后代,false不包含后代,默认为false

删除节点

父元素.removeChile(要删除的元素)

M端事件

移动端事件

  • touchstart
  • touchmove
  • touchend

js插件

swiper插件

  • 下载,找到package文件夹

  • 复制css,js文件夹到lib

  • 引入

      link swiper.min.css
    
  • 复制

Window对象

var定义的、console、document等都在windown对象中

BOM浏览器对象模型

定时器-延时函数

setTimeout(函数, 等待的毫秒数)  //返回id

clearTimeout(timer)

js执行机制

单线程
可以创建多个线程,出现同步异步

  • 同步:
    形成执行栈

  • 异步:
    添加到任务队列

    • 普通事件
    • 资源加载
    • 定时器

js首先执行同步任务,将异步任务放入任务队列
然后按次序读取任务队列中的异步任务 JS执行机制
js主线程事件循环:获得任务-执行任务-获得任务-执行任务

location对象

拆分保存url地址的各个部分

属性与方法:

  • href:完整的网站地址
  • search:获取地址中携带的参数,符号?后面部分
  • hash:获取地址中的哈希值,符号#后面部分
  • reload(boolean):刷新当前页面,true表示强制刷新

navigator对象

浏览器自身的相关信息

属性与方法:

  • userAgent:检测浏览器版本及平台

立即执行匿名函数:

    !function(){}()
    (function(){})()

history对象

  • back() //后退
  • forward() //前进
  • go(参数) //前进后退,1为前进1个,-1为后退1个

本地存储

介绍

页面刷新不丢失数据

分类

localStorage

  • 多窗口共享

  • 键值对形式存储

      localStorage.setItem('key', 'value')
      localStorage.getItem('key') //获得的都是字符串
      localStorage.removeItem('key')
    

sessionStorage

  • 生命周期为关闭浏览器窗口
  • 同一个窗口下共享
  • 键值对
  • 和localStorage类似

存储复杂数据类型

转换为JSON字符串,存储到本地

JSON.stringify(复杂数据类型)
localStorage.setItem('obj', JSON.stringify(obj))
JSON.parse(localStorage.getItem('obj'))

map()

const arr = ['pink', 'red', 'blue']
const newarr = arr.map(function (item, index) {
    console.log(item)
    console.log(index)
    return item + '老师'
})

join()

const arr = ['pink', 'red', 'blue']
console.log(arr.join(''))   //数组元素连在一起

正则表达式

const regObj = /表达式/
regObj.test(被检测的字符串) //返回boolean
regObj.exec(被检测字符串)   //查找符合规则的字符串,返回数组,否则返回null

或者

|

边界符

  • ^:开头
  • $:结尾

量词

  • ?:0或1
  • *:任意值
  • +:大于0
  • {n}:重复n次
  • {n,}:重复大于等于n次
  • {n, m}:重复n~m次

元字符

  • [a]:匹配集合
  • [^a]:除了a的匹配集合
  • .:除了换行任何字符
  • [a-z]:所有小写字符

预定义类

  • \d:数字
  • \D:除了数字
  • \w:字母数字和下划线
  • \W:除了字母数字下划线
  • \s:空格(换行符、制表符、空格)
  • \S:除了换行符制表符空格

修饰符

/表达式/修饰符
  • i:不区分大小写

  • g:匹配所有满足正则表达式的结果

    const str = 字符串.replace(/正则表达式/gi, ‘替换的文本’)

原型与原型链

原型

函数的prototype属性默认指向一个object空对象(原型对象)
原型对象有个属性constructor指向函数对象
给原型对象添加属性(方法),则函数的所有实例对象自动拥有原型中的属性(方法)

显式原型/隐式原型

  • prototype即显示原型
    • 定义函数时自动添加,默认为空object对象
  • 隐式原型:
    • 创建对象时自动添加,默认值为构造函数的prototype属性值
__proto__
  • 对象的隐式原型的值为其对应构造函数的显示原型的值

原型链

  • 访问一个对象的属性时:
    • 先在自身属性中查找,找到返回
    • 若没有,再沿着__proto__这条链向上查找
    • 若最终没有,返回undefined
  • 即隐式原型链
  • 作用:查找对象属性(方法)
    原型关系1

定义一个函数,该函数也是一个叫Function类的实例,其__proto__指向Function的显示原型
原型关系2

函数的显示原型指向的对象默认是空Object实例对象(Object不满足)

myfun.protype instanceof Object// ture
Object.protype instanceof Object    // false
Function.protype instanceof Object  // true

所有函数都是Function的实例(包括Function)

Function.__proto__ === Function.prototype   // true

Object的原型对象是原型链尽头

属性

  • 读取对象属性,自动到原型链中查找
  • 设置对象属性时,不会查找原型链
  • 方法一般定义在原型中,属性一般通过构造函数定义在对象本身上

instanceof

在原型链上就是true

备注

  • new之后__proto__不会更改,即使构造函数的原型改变指向,改之前创建的对象实例的__proto__也不会更改
function F(){}
Object.prototype.a = function(){

}
Function.prototype.b = function(){

}
let f = new F()
f.a()   // 有
f.b()   // 无
F.a()   // 有
F.b()   // 有

执行上下文

变量提升/函数提升

var a = 3
function fn () {
    console.log(a)
    var a = 4
    <!-- 相当于:
        var a;
        console.log(a)
        a = 4;
    -->
}
fn()    // undefined

变量提升:通过var定义,在定义之前就能访问,但值为undefined
函数提升:定义之前可以调用

f3()    // 不能调用,为undefined
var f3 = function(){

}

执行上下文

全局执行上下文:

  • window确定为全局执行上下文
  • 对全局数据预处理
    • var定义的全局变量=>undefined,添加为window属性
    • function声明的全局函数,添加为window方法
    • this=>赋值(window)
  • 开始执行全局代码
    函数执行上下文:
  • 调用函数,创建对应函数执行上下文对象(存在栈中)
  • 局部数据预处理
    • 形参变量添加为执行上下文的属性
    • arguments(伪数组)添加为执行上下文属性
    • var定义的局部变量=>undefined,添加为执行上下文的属性
    • function声明添加为执行上下文方法
    • this=>赋值(调用函数的对象)

执行上下文栈

  • 全局代码执行前,js引擎创建一个栈存储管理所有执行上下文对象
  • 将全局执行上下文(window)压栈
  • 函数执行上下文创建后压栈
  • 执行完毕后出栈
function a(){}
var a;
console.log(typeof a)   // 'function' 先变量提升,再函数提升
if (!(b in window)) {
    var b = 1
}
console.log(b)      // undefined
var c = 1
function c(c) {
    console.log(c)
}
c(2)    // 报错,c不是函数
// 变量函数提升后再用1覆盖了c

作用域与作用域链

  • 全局作用域
  • 函数作用域
  • 块作用域(let)

作用域是静态的,函数定义域在函数定义时已经确定

var x = 10
function fn() {
    console.log(x);
}
function show (f) {
    var x = 20;
    f();
}
show(fn);   // 10
var fn = function(){
    console.log(fn) // function
}
fn()

var obj = {
    fn2: function(){
        console.log(fn2)    // 报错,fn2未定义
    }
}
obj.fn2()

闭包

嵌套的内部函数引用了嵌套的外部函数的变量(函数)时,就产生了闭包
闭包存在于嵌套的内部函数中
产生条件:

  • 函数嵌套
  • 内部函数引用外部函数的数据

闭包是包含被引用变量的对象,作为嵌套的引用外部函数数据的内部函数的属性
定义函数就会产生闭包,不必执行内部函数,但需要执行外部函数

作用

延长局部变量生命周期
让函数外部可以操作读写到函数内部的数据

生命周期

产生:内部函数定义执行完时产生
死亡:内部函数成为垃圾对象时

应用

自定义js模块

缺点

函数执行完后,局部变量没有释放,占用内存时间长
容易造成内存泄漏

能不用就不用
及时释放

内存溢出

超出剩余内存

内存泄漏

占用的内存没有及时释放,多了就导致内存溢出
常见内存泄漏:

  • 意外的全局变量
  • 没有及时清理的计时器或回调函数
  • 闭包
var name = 'window'
var o = {
    name : 'zdp';
    getNameFunc: function(){
        return function(){
            return function(){
                return this.name;
            }
        }
    }
}
var name = 'window'
var o = {
    name : 'zdp';
    getNameFunc: function(){
        vat that = this;
        return function(){
            return function(){
                return that.name;
            }
        }
    }
}
function fun(n, o) {
    console.log(o);
    return {
        fun: function(m) {
            return fun(m, n)
        }
    }
}
var a = fun(0);
// undefined a = {fun(m){return fun(m, 0)}}
a.fun(1);               // 0
a.fun(2);               // 0
a.fun(3);               // 0
var b = fun(0).fun(1).fun(2).fun(3);
// undefined b = {fun(m){return fun(m, 0)}}
// 0 b = {fun(m){return fun(m, 1)}}
// 1 b = {fun(m){return fun(m, 2)}}
// 2 b = {fun(m){return fun(m, 3)}}
var c = fun(0).fun(1);
// undefined 0 b = {fun(m){return fun(m, 1)}}
c.fun(2);   // 1
c.fun(3);   // 1 

创建对象

  1. Object
var p = new Object()
p.name = 'zdp';
  1. 字面量
var p = {
    name: 'zdp',
    setName: function(){

    }
}
  1. 工厂模式
// 工厂函数
function createPerson(name, age) {
    var obj = {
        name: name,
        age: age
    }
    return obj
}
  1. 自定义构造函数模式
function Person(name, age) {
    this.name = name
    this.age = age
    this.setName = function (name) {
        this.name = name
    }   
}
var s = new Person('zdp', 12);
  1. 构造函数+原型
function Person(name, age) {
    this.name = name
    this.age = age
}
Person.prototype.setName = function (name) {
    this.name = name
}   
var s = new Person('zdp', 18);

继承模式

原型链的继承

  1. 定义父类型构造函数
  2. 给父类型的原型添加方法
  3. 定义子类型的构造函数
  4. 创建一个父类型的实例赋值给子类型的原型
  5. 将子类型原型的构造属性设置为子类型
  6. 给子类型原型添加方法
  7. 创建子类型的对象:可以调用父类型的方法
  8. 让子类型的原型的构造器指向子类型

子类型的原型为父类型的一个实例对象

call函数继承

function Person(name, age){
    this.name = name;
    this.age = age;
}
function s(name, age){
    Person.call(this, name, age)// this.Person(name, age);
}
var t = new s(1, 2);

组合继承

function Person(name, age){
    this.name = name
    this.age = age
}
Person.prototype.setName = function(name){
    this.name = name
}
function Student(name, age){
    Person.call(this, name, age)// this.Person(name, age)
}
Student.prototype = new Person()
Student.prototype.constructor = Student

var s = new Student('zdp', 25)

线程机制与事件机制

线程进程

js单线程
使用Web Workers可以多线程运行
浏览器多线程运行
浏览器有多进程:chrome/新ie
单进程:老ie/firefox

浏览器内核

chrome,safari:webkit
firefox:Gecko
ie: trident
360+搜狗:trident+webkit

  • js引擎模块
  • html/css解析模块
  • DOM/css模块
  • 布局渲染模块
  • 定时器模块
  • 事件响应模块
  • 网络请求模块

定时器

定时器回调函数在js主(单)线程执行
不是完全精准执行,会延迟一会儿

js单线程执行

alert暂停线程而且会暂停计时,点击确定后恢复

  • 先执行初始化代码
    • 设置定时器
    • 绑定监听
    • 发送ajax请求
  • 回调代码

事件循环模型

事件循环模型

  • 事件管理模块
  • 回调队列
  1. 执行初始化代码,将事件回调函数给对应模块
  2. 事件发生时,将回调函数与数据添加到回调队列
  3. 当初始化代码执行完毕后,遍历读取回调队列中的回调函数执行
  • 执行栈
  • 浏览器内核
  • 任务队列/消息队列/事件队列:回调队列
  • 事件轮询
  • 事件驱动模型
  • 请求响应模型

Web Workers

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值