web API自做笔记

157 阅读18分钟

API第一天

变量声明

变量声明有三个:var let const

建议数组和对象使用const来声明,因为对象是引用类型,里面存储的是地址,值变地址不变就不会报错

DOM(Document Object Model)文档对象模型(操作网页内容)

用来呈现以及与任意HTML或XML文档交互的API

DOM树

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

DOM对象

  1. 浏览器根据HTML标签生成的JS对象
  2. 所有的标签属性都可以在这个对象上面找到
  3. 修改这个对象的属性会自动映射到标签身上
  4. DOM核心是把网页内容当做对象处理

document对象

  1. 属于DOM里提供的一个对象
  2. 提供的属性和方法都是用来访问和操作网页内容的
  3. 网页所有的内容都在document里

获取DOM对象

根据CSS选择器来获取DOM元素

1-选择匹配的第一个元素:

语法:

document.querySelector('css选择器')

参数:包含一个或多个有效的CSS选择器 字符串

返回值:css选择器匹配的第一个元素,一个HTMLElement对象

2-选择匹配的多个元素

语法:

document.querySelectorAll('css选择器')

返回值:css选择器匹配的NodeList对象集合

得到的值是一个伪数组,需要用for遍历来得到每一个元素,有长度有索引号,但是不能用pop() push()等数组方法

操作DOM元素内容

1-元素innerHTML属性(优先使用)

将文本内容添加到任意标签位置,会解析标签,多标签建议使用模板字符

const info = document.querySelector('.info')
info.innerHTML = `嗨喽,俺是<strong>刘德华</strong>~`
//在原有基础上追加元素
info.innerHTML += '我是如来佛祖'
2-元素innerText属性

将文本内容添加到任意标签位置,显示纯文本,不解析标签

const info = document.querySelector('.info')
info.innerText = '嗨喽,俺是刘德华~'

document.body 直接获取body元素 ​ document.documentElement 直接获取html标签 ​ document.head 直接获取head ​ document.title 直接获取title操作DOM元素属性

1-操作元素常用属性

对象.属性 = 值

2-操作元素样式属性

1)通过style属性操作CSS

对象.style.样式属性 = 值

2)通过类型(className)操作CSS

元素.className ='active'

会影响原先类名

3)通过classList操作控制CSS(重点)

//追加一个类* ​ 元素.classList.add('类名')

//删除一个类* ​ 元素.classList.remove('类名')

//切换一个类* ​ 元素.classList.toggle('类名')

//替换一个类名,两个参数第一个是原来的类,第二个是要替换的类名 ​ 元素.classList.replace("类名1","类名2")

//判断是否包含指定的类,返回是布尔值 ​ const flag=元素.classList.contains('类名') ​ console.log(flag)

classList一般不影响原先类名

3-操作表单元素属性

获取:DOM对象.属性名

设置:DOM对象.属性名 = 新值

checked(禁用吗?).disabled等用布尔值表示

4-自定义属性data

在html5中推出来了专门的data-自定义属性 在标签上一律以data-开头 在DOM对象上一律以dataset对象方式获取

<div data-index="1"data-spm="不知道">1</div>
​
const one = document.querySelector('div')
console.log(one.dataset.index)//1
console.log(one.dataset.spm)//不知道

定时器-间歇函数

1-开启定时器

setInterval(函数,间隔时间)

作用:每隔一段时间调用这个函数 间隔时间单位是毫秒

setInterval(function () {
      document.write('我是金角大王')
    }, 1000)
function repeat(){
console.log('前端程序员,就是头发多咋滴~~')
}
//1 每隔一秒调用repeat函数
setInterval(repeat, 1000)
2-关闭定时器

let 变量名 = setInterval(函数,间隔时间) clearInterval(变量名)

let timer = setInterval(function() {
    console.log('hi~~')
},1000)
clearInterval(timer)

API第二天

事件监听(注册事件)

语法:

元素对象.addEventListener('事件类型',要执行的函数)

事件监听三要素

事件源:那个dom元素被事件触发了,要获取dom元素 事件类型: 用什么方式触发,比如鼠标单击 click、鼠标经过 mouseover 等 事件调用的函数: 要做什么事


<button>按钮</button>
<script>
const btn = document.querySelector('.btn')
//1修改元素样式
btn.addEventListener('click', function (){
alert('点击了~')
})
</script>

事件类型

鼠标事件:

click 鼠标点击 mouseenter 鼠标经过 mouseleave 鼠标离开 mouseover可以冒泡 mousemive鼠标移动 conlose.log(e.clientX,e.clientY)鼠标在窗口的坐标 conlose.log(e.offsetX,e.offsetY)鼠标在当前标签的坐标

*conlose.log(e.pageX,e.pageY)鼠标在整个页面中的坐标

change改变事件

焦点事件:表单获得光标

focus 获得焦点 blur 失去焦点

键盘事件:

keydown 键盘按下触发 keyup 键盘抬起触发

文本事件:input 用户输入事件

事件对象event:

语法:如何获取 在事件绑定的回调函数的第一个参数就是事件对象 一般命名为event、ev、e

元素.addEventListener('click',function(e){
}
部分常用属性
type
  获取当前的事件类型
clientX/clientY
  获取光标相对于浏览器可见窗口左上角的位置
offsetX/offsetY
  获取光标相对于当前DOM元素左上角的位置
key
  用户按下的键盘键的值
  现在不提倡使用keyCode

去除空格trim方法

tx.addEventListener('keyup', function (e) {
      if (e.key === 'Enter') {
        if (tx.value.trim()) {
          item.style.display = 'block'
          text.innerHTML = tx.value
        }
        tx.value = ''
      }
    })

环境对象this:

指的是函数内部特殊的变量this,它代表着当前函数运行时所处的环境

作用:
弄清楚this的指向,可以让我们代码更简洁
函数的调用方式不同,this指代的对象也不同
【谁调用,this就是谁】是判断this指向的粗略规则
<button>点击</button>
    const btn = document.querySelector('button')
    btn.addEventListener('click', function () {
      this.style.color = 'red'
    })

回调函数:

如果将函数A做为参数传递给函数B时,我们称函数A为回调函数 简单理解:当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数

function fn(){
console.1og('我是回调函数...')
}
// fn传递给了setInterval,fn就是回调函数
setInterval(fn, 1000)
box.addEventListener('click', function () {
console.log'我也是回调函数')
})

API第三天

事件流:

事件完整执行过程中的流动路径

捕获阶段 从父到子 从大到小

DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
addEventListener第三个参数传入 true 代表是捕获阶段触发(很少使用)
若传入false代表冒泡阶段触发,默认就是false
若是用 L0 事件监听,则只有冒泡阶段,没有捕获

冒泡阶段 从子到父** 从小到大

当一个元素触发事件后,会依次向上调用所有父级元素的 同名事件

<body>
  <div class="father">
    <div class="son"></div>
  </div>
  <script>
    const fa = document.querySelector('.father')
    const son = document.querySelector('.son')
    document.addEventListener('click', function () {
      alert('我是爷爷')
    })
    fa.addEventListener('click', function () {
      alert('我是爸爸')
    })
    son.addEventListener('click', function () {
      alert('我是儿子')
    })
  </script>
</body>

阻止冒泡:

事件对象.stopPropagation()
son.addEventListener('click', function (e) {
      alert('我是儿子')
      // 组织流动传播  事件对象.stopPropagation()
      e.stopPropagation()
    })
阻止元素默认行为,比如阻止链接的跳转,表单域跳转
e.preventDefault()

解绑事件:

btn.onclick只冒泡,不能捕获

**on注册事件L0**事件方式,直接使用null覆盖偶就可以实现事件的解绑
const btn = document.querySelector('button')
    btn.onclick = function () {
      alert('点击了')
      // L0 事件移除解绑
      btn.onclick = null
    }
**事件监听注册L2**addEventListener方式,必须使用:
removeEventListener(事件类型, 事件处理函数,  [获取捕获或者冒泡阶段])
const btn = document.querySelector('button')
    function fn() {
      alert('点击了')
    }
    btn.addEventListener('click', fn)
    // L2 事件移除解绑
    btn.removeEventListener('click', fn)

两种注册事件区别:

传统on注册(L0)
Ø同一个对象,后面注册的事件会覆盖前面注册(同一个事件)
Ø直接使用null覆盖偶就可以实现事件的解绑
Ø都是冒泡阶段执行的
事件监听注册(L2)
Ø语法: addEventListener(事件类型, 事件处理函数, 是否使用捕获)
Ø后面注册的事件不会覆盖前面注册的事件(同一个事件)
Ø可以通过第三个参数去确定是在冒泡或者捕获阶段执行
Ø必须使用removeEventListener(事件类型, 事件处理函数, 获取捕获或者冒泡阶段)
Ø匿名函数无法被解绑
鼠标经过事件:

mouseover 和 mouseout 会有冒泡效果

mouseenter 和 mouseleave 没有冒泡效果 (推荐)

事件委托:

利用事件流的特征解决一些开发需求,减少注册次数,提高程序性能,为未来元素预备一个事件

给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素身上,从而触发父元素的事件

● this 指向绑定事件的对象 调用者 ● e.target 指向触发事件的对象 触发对象

事件对象e.target. tagName 可以获得真正触发事件的元素
<script>
    const ul = document.querySelector('ul')
    ul.addEventListener('click', function (e) {
      if (e.target.tagName === 'LI') {
        this.style.color = 'pink'
      }
    })
  </script>

其他事件:

页面加载事件:

load事件:

加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件

  //页面加载事件
window.addEventListener('load', function () {
  //执行的操作
})
//监听整个页面自由给window加
DOMContentLoaded:

当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像等完全加载

document.addEventListener('DOMContentLoaded', function () {
  //执行的操作
})
  //给 document 加

元素滚动事件:

scroll:
//页面滚动事件
window.addEventListener('scroll', function () {
//执行的操作
})
//给 window 或 document 添加 scroll 事件
scrollTop (属性)-获取位置:

const n = document.documentElement.scrollTop

div.addEventListener('scroll', function () {
console.log(this.scrollTop)
})
  //页面滚动事件
window.addEventListener('scroll', function () {
  
  // document.documentElement 是html元素获取方式
  
const n = document.documentElement.scrollTop
console.log(n)
})
  //document.documentElement   HTML 文档返回对象为HTML元素
win.pageYOffset
document.documentElement.scrollTop
获取时两个功能一样,但pageYOffset不能设置
滚动到指定的坐标:scrollTo()

元素.scrollTo(x, y)

//让页面滚动到y轴1000像素的位置
window.scroll1To(0, 1000)
​

页面尺寸事件:

resize:
window.addEventListener('resize', function () {
//执行的代码
  let w = document.documentElement.clientWidth
  console.log(w)
})
​

2元素尺寸与位置:

通过js的方式,得到元素在页面中的位置

获取宽高:
  获取元素的自身宽高、包含元素自身设置的宽高、paddingborder
  
  offsetWidth和offsetHeight  
  
  获取出来的是数值,方便计算
  注意: 获取的是可视宽高, 如果盒子是隐藏的,获取的结果是0
  
获取位置:
  获取元素距离自己定位父级元素的左、上距离
  offsetLeft和offsetTop  注意是只读属性
元素尺寸于位置-尺寸

element.getBoundingClientRect()

方法返回元素的大小及其相对于视口的位置

总结:

属性作用说明
scrollTop被卷去的头部配合页面滚动来用,可读写
clientWidth 和 clientHeight获得元素宽度和高度不包含border,margin,滚动条 用于js获取元素大小,只读属性
offsetWidth和offsetHeight获得元素宽度和高度包含border、padding,滚动条等,只读
offsetLeft和offsetTop获取元素距离自己定位父级元素的左、上距离获取元素位置的时候使用,只读属性

scroll系列属性:标签内部真实内容的大小、位置

client系列属性:标签容纳范围(border里面)的大小、位置

offset系列属性:标签本身的大小、位置

1-offsetWidth和offsetHeight是得到元素什么的宽高? 内容+padding+border 2-offsetTop和offsetLeft得到位置以谁为准? 带有定位的父级 如果都没有则以文档左上角为准

 遮罩层跟随鼠标在大盒子移动
 <body>
    <div class="box">
      <div class="son"></div>
    </div>
    <script>
      // 得到鼠标在盒子中的相关坐标
      // mousemove 鼠标移动事件 触发频率比较高
      let box = document.querySelector(".box")
      let son = document.querySelector(".son")
      box.addEventListener('mousemove', function (e) {
        let x = e.pageX - box.offsetLeft
        let y = e.pageY - box.offsetTop
        son.style.left = x + 'px'
        son.style.top = y + 'px'
      })
    </script>
  </body>

API第四天

日期对象:

用来记录时间信息的对象

实例化:new
//获得当前时间
const date = new Date()
//获得指定时间
const date = new Date('2008-8-8')
console.log(date)
 <script>
    let d = new Date()
    let year = d.getFullYear()
    let month = d.getMonth()
    let date = d.getDate()
    let day = d.getDay()
    let hour = d.getHours()
    let minute = d.getMinutes()
    let second = d.getSeconds()
  </script>
日期对象方法
方法作用说明
get FullYear()获得年份获取四位年份
get Month()获得月份取值为 0 ~ 11
get Date()获取月份中的每一天不同月份取值也不相同
get Day()获取星期取值为 0 ~ 6
get Hours()获取小时取值为 0 ~ 23
get Minutes()获取分钟取值为 0 ~ 59
get Seconds()获取秒取值为 0 ~ 59

toLocaleString自动获取时间信息

时间戳:获取毫秒数

三种方法

1--使用 getTime()  方法
  const date = new Date()
  console.log(date.getTime())
​
**2--简写  +new Date()**
  console.log(+new Date())
​
3--使用 Date.now()
  console.log(Date.now())
时间转换公式:
d=parseInt(总秒数/60/60/24);//计算天数
h=parseInt(总秒数/60/60%24)//计算小时
m=parseInt(总秒数/60%60);//计算分数
s=parseInt(总秒数%60);//计算当前秒数

节点操作:

DOM节点:DOM树里每一个内容都称之为节点

浏览器使用对象来记录网页内容 浏览器把网页内容翻译成一个个的对象,浏览器会把网页内容的特征翻译成对象的属性 这个对象就称为DOM对象

DOM树 每个DOM对象中都有表示层级关系的属性,这些属性把所有DOM对象联系在了一起,形成一个树状结构,称为DOM树

节点类型:
**元素节点:**
    所有的标签 比如 bodydiv
    html 是根节点
属性节点:
    所有的属性 比如 href
文本节点:
    所有的文本 
其他节点
查找节点:
**父节点查找:parentNode 属性  
    子元素.parentNode
​
**子节点查找:
  *children属性(重点):
      仅获得所有元素节点
      返回的还是一个伪数组
      父元素.children
​
  childNodes:获得所有子节点、包括文本节点(空格、换行)、注释节点等
  
  **兄弟关系查找:
    下一个兄弟节点:
    nextElementSibling 属性  
    上一个兄弟节点:
    previousElementSibling 属性
阻止元素默认行为,比如阻止链接的跳转,表单域跳转
e.preventDefault()
清空表单:this.reset()
增加节点:
**创建节点:
    //创造一个新的元素节点
    document.createElement('标签名')
**追加节点:
  插入到父元素的最后一个子元素:
    //插入到这个父元素的最后
    父元素.appendChild(要插入的元素)
  插入到父元素中某个子元素的前面:
    //插入到某个子元素的前面
    父元素.insertBefore(要插入的元素,在哪个元素前面)
**克隆节点:
     //克隆一个已有的元素节点
    元素.cloneNode(布尔值)
删除节点:
父元素.removeChild(要删除的元素)
被删除的元素.remove()

M端事件:

触屏事件 touch:
触屏TOUCH事件说明
touchstart手指触摸到一个DOM元素时触发
touchmove手指在一个DOM元素上滑动时触发
touchend手指从一个DOM元素上移开时触发

插件:swiper

插件: 就是别人写好的一些代码,我们只需要复制对应的代码,就可以直接实现对应的效果
学习插件的基本过程
熟悉官网,了解这个插件可以完成什么需求           https://www.swiper.com.cn/ 
看在线演示,找到符合自己需求的demo      https://www.swiper.com.cn/demo/index.html
查看基本使用流程      https://www.swiper.com.cn/usage/index.html
查看APi文档,去配置自己的插件      https://www.swiper.com.cn/api/index.html
注意: 多个swiper同时使用的时候, 类名需要注意区分
​

API第五天

Window对象:

1.BOM:浏览器对象模型

window对象是一个全局对象,也可以说是JavaScript中的顶级对象
像documentalert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的。
所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法
window对象下的属性和方法调用的时候可以省略window

2.定时器-延时函数:setTimeout

语法:
setTimeout(回调函数,等待的毫秒数)
           
清除延时函数:
let timer=setTimeout(回调函数,等待的毫秒数)
clearTimeout(timer)
延时器需要等待,所以后面的代码先执行
每一次调用延时器都会产生一个新的延时器
 setTimeout(function(){
      console.log('gogo');
    },3000)

3.JS 执行机制

问题:
JavaScript 语言的一大特点就是单线程,同一个时间只能做一件事。
avaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的。比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
解决方法:
*同步
  前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。同步任务都在主线程上执行,形成一个执行栈。
*异步
  JS 的异步是通过回调函数实现的。
一般而言,异步任务有以下三种类型:
1、普通事件,如 click、resize 等
2、资源加载,如 load、error 等
3、定时器,包括 setInterval、setTimeout 等
异步任务相关添加到任务队列中(任务队列也称为消息队列)。
event loop
执行机制:
  1. 先执行执行栈中的同步任务。
  2. 异步任务放入任务队列中。
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(event loop)。

4.location对象

location 的数据类型是对象,它拆分并保存了 URL 地址的各个组成部分

常用属性和方法:
1-*href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转
  //可以得到当前文件URL地址
  console.log(location.href)
  //可以通过js方式跳转到目标地址
  location.href = 'http://www.itcast.cn'
2-*replace,新地址替换原来地址,不能后退
   btn.addEventListener('click', function () {location.replace('https://www.qq.com')
    })
3-*reload() 方法用来缓存刷新当前页面,传入参数 true 时表示强制刷新
  <button>点击刷新</button>
  <script>
  let btn = document.querySelector('button')
  btn.addEventListener('click', function () {
  location.reload(true)
  //强制刷新 类似ctrl+f5
  })
  </script>
4-*search 属性获取地址中携带的参数,符号 ?后面部分
  console.log(location.search)
5-*hash 属性获取地址中的啥希值,符号 # 后面部分
  console.log(location.hash)
​

5.navigator对象(客户端信息)

navigator的数据类型是对象,该对象下记录了浏览器自身的相关信息,自动跳转到移动端

6.history对象

history 的数据类型是对象,主要管理历史记录, 该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等


本地存储

1、数据存储在用户浏览器中
2、设置、读取方便、甚至页面刷新不丢失数据
3、容量较大,sessionStorage和localStorage约 5M 左右

1.本地存储分类-localStorage

能够使用localStorage 把数据存储的浏览器中,只能存储string类型

作用: 可以将数据永久存储在本地(用户的电脑), 除非手动删除,否则关闭页面也会存在
特性:
可以多窗口(页面)共享(同一浏览器可以共享)
以键值对的形式存储使用
存储(改)数据:
localStorage.setItem('key', 'value')
获取数据:
localStorage.getItem('key')
删除数据:
localStorage.removeItem('key')

2.本地存储分类- sessionStorage

特性:
生命周期为关闭浏览器窗口
在同一个窗口(页面)下数据可以共享
以键值对的形式存储使用
用法跟localStorage 基本相同

3.存储复杂数据类型JSON

能够存储复杂数据类型以及取出数据

解决:需要将复杂数据类型转换成JSON字符串,在存储到本地
语法:JSON.stringify(复杂数据类型)
const goods ={
name:'小米10'price: 1999
}
localStorage.setItem('goods', JSON.parse(goods))
将复杂数据转换成JSON字符串    存储 本地存储中
解决:把取出来的字符串转换为对象
语法:JSON.parse(JSON字符串)
const obj = JSON.parse(localStorage.getItem('goods'))
console.log(obj)
将JSON字符串转换成对象     取出 时候使用

//存 //复杂数据类型—>JSON.stringify()—>JSON字符串—>存在本地存储中

//取 //从本地存储中取出—>JSON字符串—>JSON.parse()—>复杂数据类型

数组中map方法 迭代数组 映射方法
作用:map  迭代数组
语法:
const arr = ['pink', 'red', 'blue']
arr.map(function (item, index) {
console.log(item) // item得到数组元素 'pink'
'red' 'blue'
console.log(index)// index得到索引号 0 1 2
})
map 可以处理数据,并且返回新的数组
map 也称为映射。映射是个术语,指两个元素的集之间元素相互“对应”的关系
​
数组中join方法
作用:
  join() 方法用于把数组中的所有元素转换一个字符串
语法:
  const arr=['pink老师','red老师','blue老师']
  console.log(arr.join(''))//pink老师red老师blue老师
参数:
数组元素是通过参数里面指定的分隔符进行分隔的

API第六天

正则表达式:reg

正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象

通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式。

正则表达式在 JavaScript中的使用场景:
*验证表单(匹配):用户名表单只能输入英文字母、数字或 者下划线, 昵称输入框中可以输入中文(匹配)
 比如用户名:    /^[a-z0-9_-]{3,16}$/
*过滤掉页面内容敏感词(替换)
*从字符串中获取我们想要的特定部分(提取)等 
​

语法:

1. 定义正则表达式语法: const变量名=/表达式/
  其中 // 是正则表达式字面量 const reg=/前端/
2.判断是否有符合规则的字符串:  
  *test() 方法  用来查看正则表达式与指定的字符串是否匹配
    正则表达式.test(字符串)
  如果正则表达式与指定的字符串匹配 ,返回true,否则false
  
3.检索(查找)符合规则的字符串:
  exec() 方法 在一个指定字符串中执行一个搜索匹配
    regobj.exec(被检测字符串)
  如果匹配成功,exec() 方法返回一个数组,否则返回null

元字符:

1.边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾)

如果 ^ 和 $ 在一起,表示必须是精确匹配。

2.量词 (表示重复次数)逗号左右两侧不能出现空格
3.字符类 (比如 \d 表示 0~9)
(1)[ ] 里面加上 - 连字符 - 表示一个范围
console.log(/^[a-z]$/.test('c')) // true
[a-z]  表示 az 26个英文字母都可以
[a-zA-Z]   表示大小写都可以
[0-9]  表示 0~9 的数字都可以

[ ] 里面加上 ^ 取反符号

(2) . 匹配除换行符之外的任何单个字符
(3) 预定义:指的是 某些常见模式的简写方式

日期格式:/^\d{4}-\d{1,2}-\d{1,2}$/

修饰符:

修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等

/表达式/修饰符
i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
g 是单词 global 的缩写,匹配所有满足正则表达式的结果
console.log(/a/i.test('a'))// true
console.log(/a/i.test('A'))// true
替换 replace替换
字符串.replace(/正则表达式/'替换的文本')