JavaScript

本文详细介绍了JavaScript的数据类型,包括原始类型、合成类型和ES6新增的Symbol和BigInt。接着讨论了布尔运算符的用法,以及break和continue在循环中的作用。此外,还详细阐述了字符串的各种方法,如charAt、concat、substring等,并对比了它们的差异。文章还探讨了for in和for of的数组遍历方式,以及数组的常用方法如push、pop、shift、unshift等。最后,文章介绍了JavaScript中的对象、事件处理程序和定时器的相关概念,以及防抖和节流的概念,这些都是JavaScript开发中的重要知识点。

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

数据类型

原始类型(基础类型)

数值;字符串;布尔值

合成类型(复合类型)

对象:因为一个对象往往是多个原始类型的值的合成,可以看作是一个存放各种值的容器。

undefined和null:一般将它们看成两个特殊值。null一般代表对象为“没有‘,undefined一般代表数值为”没有“。

ES6新出的Symbol BinInt

Symbol 。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。

bigInt。是指安全存储、操作大整数。(但是很多人不把这个做为一个类型)。

运算符之布尔运算符

用于将表达式转为布尔值,取反运算符 !、且运算符 &&、或运算符 ||

取反运算符(!)

对于非布尔值,取反运算符会将其转为布尔值,以下六个值取反后为true,其他值都为false。

undefined、null、false、0、NaN、空字符串(‘’)
:NaN属性代表一个”不是数字“的值,这个特殊的值是因为运算不能执行而导致的,不能执行的原因是 运算对象之一非数字或者运算结果非数字。NaN类型为Number,NaN和任何东西比较(===)包括他自己都是false

break和continue

break 跳出整个循环,continue跳出本次循环,进入下次循环

字符串方法

charAt()

charAt 方法返回指定位置的字符,参数是从 0 开始编号的

如果参数为负数,或大于等于字符串的长度, charAt 返回空字符串

concat()

concat 方法用于连接两个字符串,返回一个新字符串,不改变原字符串。该方法可以接受多个参数。

如果参数不是字符串, concat 方法会将其先转为字符串,然后再连接。

concat和+的区别:
concat不管什么类型直接合并成字符串
加号遇到数字类会做运算,遇到字符串相连接

substring()

substring 方法用于从原字符串取出子字符串并返回,不改变原字符串。

它的第一个参数表示子字符串的开始位置,第二个位置表示结束位置(返回结果不含该位置)

如果省略第二个参数,则表示子字符串一直到原字符串的结束

如果第一个参数大于第二个参数, substring 方法会自动更换两个参数的位置

如果参数是负数, substring 方法会自动将负数转为0

substr()

substr 方法用于从原字符串取出子字符串并返回,不改变原字符串,跟 substring 方法的作用相同

substr 方法的第一个参数是子字符串的开始位置(从0开始计算),第二个参数是子字符串的长度

如果省略第二个参数,则表示子字符串一直到原字符串的结束

如果第一个参数是负数,表示倒数计算的字符位置。如果第二个参数是负数,将被自动转为0,因此会返回空字符串

indexOf()

indexOf 方法用于确定一个字符串在另一个字符串中第一次出现的位置,返回结果是匹配开始的位置。如果返回 -1 ,就表示不匹配

indexOf 方法还可以接受第二个参数,表示从该位置开始向后匹配

trim()

trim 方法用于去除字符串两端的空格,返回一个新字符串,不改变原字符串

该方法去除的不仅是空格,还包括制表符( \t 、 \v )、换行符( \n )和回车符( \r )
ES6扩展方法:trimEnd() 和 trimStart() 方法

"   itbaizhan   ".trimEnd(); //   itbaizhan
"   itbaizhan   ".trimStart(); // itbaizhan  

split()

split 方法按照给定规则分割字符串,返回一个由分割出来的子字符串组成的数组

如果分割规则为空字符串,则返回数组的成员是原字符串的每一个字符。

如果省略参数,则返回数组的唯一成员就是原字符串

split 方法还可以接受第二个参数,限定返回数组的最大成员数。

for in 和 for of 数组遍历

两者都可以用于遍历,不过for in遍历的是数组的索引(index)即键名,而for of遍历的是数组元素值(value)
for in
1、索引是字符串型的数字,因而不能直接进行几何运算
2、遍历顺序可能不是实际的内部顺序
3、for in会遍历数组所有的可枚举属性,包括原型。例如的原型方法method和name属性
for of:
for of不支持普通对象,想遍历对象的属性,可以用for in循环, 或内建的Object.keys()方法:
Object.keys(myObject)获取对象的实例属性组成的数组,不包括原型方法和属性

for (var key of Object.keys(Object))
    console.log(key + ": " + Object[key])

一般用for in遍历对象 for of 遍历数组

数组方法

数组静态方法 Array.isArray()

Array.isArray 方法返回一个布尔值,表示参数是否为数组。它可以弥补typeof 运算符的不足

push()/pop()

push 方法用于在数组的末端添加一个或多个元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组

pop 方法用于删除数组的最后一个元素,并返回该元素。注意,该方法会改变原数组

shift()/unshift()

shift 方法用于删除数组的第一个元素,并返回该元素。注意,该方法会改变原数组,shift 方法可以遍历并清空一个数组

unshift 方法用于在数组的第一个位置添加元素,并返回添加新元素后的数组长度。注意,该方法会改变原数组

unshift 方法可以接受多个参数,这些参数都会添加到目标数组头部

join()

join 方法以指定参数作为分隔符,将所有数组成员连接为一个字符串返回。如果不提供参数,默认用逗号分隔

如果数组成员是 undefined 或 null 或空位,会被转成空字符串

[undefined, null].join('#') // '#'
 ['a',, 'b'].join('-') // 'a--b'

数组的 join 配合字符串的 split 可以实现数组与字符串的互换

concat()

concat 方法用于多个数组的合并。它将新数组的成员,添加到原数组成员的后部,然后返回一个新数组,原数组不变

除了数组作为参数, concat 也接受其他类型的值作为参数,添加到目标数组尾部。

reverse()

reverse 方法用于颠倒排列数组元素,返回改变后的数组。注意,该方法将改变原数组

indexOf()

indexOf 方法返回给定元素在数组中第一次出现的位置,如果没有出现则返回 -1

indexOf 方法还可以接受第二个参数,表示搜索的开始位置

对象

对象就是一组“键值对”(key-value)的集合,是一种无序的复合数据集合

如果一个属性的值为函数,通常把这个属性称为“方法”,它可以像函数那样调用

如果属性的值还是一个对象,就形成了链式引用

Math对象

Math是 JavaScript 的原生对象,提供各种数学功能

Math.abs() 返回参数值的绝对值

Math.max 方法返回参数之中最大的那个值, Math.min 返回最小的那个值。如果参数为空, Math.min 返回 Infinity , Math.max 返回 -Infinity 。

Math.floor 方法返回小于参数值的最大整数,Math.ceil 方法返回大于参数值的最小整数

Math.random() 返回0到1之间的一个伪随机数,可能等于0,但是一定小于1

Date对象

Date 对象是 JavaScript 原生的时间库。它以1970年1月1日00:00:00作为时间的零点,可以表示的时间范围是前后各1亿天(单位为毫秒)

Date.now 方法返回当前时间距离时间零点(1970年1月1日 00:00:00UTC)的毫秒数,相当于 Unix 时间戳乘以1000
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

Date 对象提供了一系列 get* 方法,用来获取实例对象某个方面的值

getTime():返回实例距离1970年1月1日00:00:00的毫秒数
getDate():返回实例对象对应每个月的几号(从1开始)
getDay():返回星期几,星期日为0,星期一为1,以此类推
getYear():返回距离1900的年数
getFullYear():返回四位的年份
getMonth():返回月份(0表示1月,11表示12月)
getHours():返回小时(0-23)
getMilliseconds():返回毫秒(0-999)
getMinutes():返回分钟(0-59)
getSeconds():返回秒(0-59)

document对象_方法/获取元素

document.getElementsByTagName()

document.getElementsByTagName 方法搜索 HTML 标签名,返回符合条件的元素。它的返回值是一个类似数组对象( HTMLCollection 实例),可以实时反映 HTML 文档的变化。如果没有任何匹配的元素,就返回一个空集

var paras =document.getElementsByTagName('p')

如果传入 * ,就可以返回文档中所有 HTML 元素

document.getElementsByClassName()

document.getElementsByClassName 方法返回一个类似数组的对象( HTMLCollection 实例),包括了所有 class 名字符合指定条件的元素,元素的变化实时反映在返回结果中

由于 class 是保留字,所以 JavaScript 一律使用 className 表示 CSS 的 class,参数可以是多个 class ,它们之间使用空格分隔

var paras =document.getElementsByClassName('foo bar')

document.getElementsByName()

document.getElementsByName 方法用于选择拥有 name 属性的 HTML 元素(比如 、 、 等),返回一个类似数组的的对象( NodeList 实例),因为 name 属性相同的元素可能不止一个

// 表单为 <form name="itbaizhan"></form>
var forms =document.getElementsByName('itbaizhan');

document.getElementById()

document.getElementById 方法返回匹配指定 id 属性的元素节点。如果没有发现匹配的节点,则返回 null

注意,该方法的参数是大小写敏感的。比如,如果某个节点的 id 属性是 main ,那么 document.getElementById(‘Main’) 将返回 null

document.querySelector()

document.querySelector 方法接受一个 CSS 选择器作为参数,返回匹配该选择器的元素节点。如果有多个节点满足匹配条件,则返回第一个匹配的节点。如果没有发现匹配的节点,则返回 null

var el1 = document.querySelector('.myclass');

document.querySelectorAll()

document.querySelectorAll 方法与 querySelector 用法类似,区别是返回一个NodeList 对象,包含所有匹配给定选择器的节点

document对象_方法/创建元素

document.createElement()

document.createElement 方法用来生成元素节点,并返回该节点

var newDiv = document.createElement('div');

document.createTextNode()

document.createTextNode 方法用来生成文本节点( Text 实例),并返回该节点。它的参数是文本节点的内容

var newDiv = document.createElement('div');
var newContent =document.createTextNode('Hello');
newDiv.appendChild(newContent);

document.createAttribute()

document.createAttribute 方法生成一个新的属性节点( Attr 实例),并返回它

var attribute =document.createAttribute(name);
var root = document.getElementById('root');
var it =document.createAttribute('itbaizhan');
it.value = 'it';
root.setAttributeNode(it);

Element对象_属性

Element对象对应网页的 HTML 元素。每一个 HTML 元素,在DOM 树上都会转化成一个Element节点对象(以下简称元素节点)

Element.id

Element.id 属性返回指定元素的 id 属性,该属性可读写

// HTML 代码为 <p id="foo">
var p = document.querySelector('p');
p.id // "foo"

Element.className

className 属性用来读写当前元素节点的 class 属性。它的值是一个字符串,每个 class 之间用空格分割

// HTML 代码 <div class="one two three"id="myDiv"></div>
var div = document.getElementById('myDiv');
div.className

Element.classList

classList 对象有下列方法

add() :增加一个 class。
remove() :移除一个 class。
contains() :检查当前元素是否包含某个 class。
toggle() :将某个 class 移入或移出当前元素

var div = document.getElementById('myDiv');
div.classList.add('myCssClass');
div.classList.add('foo', 'bar');
div.classList.remove('myCssClass');
div.classList.toggle('myCssClass'); // 如果myCssClass 不存在就加入,否则移除
div.classList.contains('myCssClass'); // 返回true 或者 false

Element.innerHTML

Element.innerHTML 属性返回一个字符串,等同于该元素包含的所有HTML 代码。该属性可读写,常用来设置某个节点的内容。它能改写所有元素节点的内容,包括 和 元素

el.innerHTML = '';

Element.innerText

innerText 和 innerHTML 类似,不同的是 innerText 无法识别元素,会直接渲染成字符串

Element获取元素位置

在这里插入图片描述
在这里插入图片描述

Element.clientHeight,Element.clientWidth

Element.clientHeight 属性返回一个整数值,表示元素节点的 CSS 高度(单位像素),只对块级元素生效,对于行内元素返回 0 。如果块级元素没有设置 CSS 高度,则返回实际高度。如果有水平滚动条,还要减去水平滚动条的高度。注意,这个值始终是整数,如果是小数会被四舍五入。

Element.clientWidth 属性返回元素节点的 CSS 宽度,同样只对块级元素有效,也是只包括元素本身的宽度和 padding ,如果有垂直滚动条,还要减去垂直滚动条的宽度。注意,这个值始终是整数,如果是小数会被四舍五入。

除了元素本身的高度,它l俩还包括 padding 部分,但是不包括 border 、 margin 。

document.documentElement 的 clientHeight 属性,返回当前视口的高度(即浏览器窗口的高度)。 document.body 的高度则是网页的实际高度。

// 视口高度
document.documentElement.clientHeight
// 网页总高度
document.body.clientHeight

Element.scrollHeight,Element.scrollWidth

Element.scrollHeight 属性返回一个整数值(小数会四舍五入),表示当前元素的总高度(单位像素),它包括 padding ,但是不包括 border 、 margin 以及水平滚动条的高度(如果有水平滚动条的话)

Element.scrollWidth 属性表示当前元素的总宽度(单位像素),其他地方都与 scrollHeight 属性类似。这两个属性只读

整张网页的总高度可以从 document.documentElement 或 document.body 上读取

// 返回网页的总高度
document.documentElement.scrollHeight
document.body.scrollHeight

Element.scrollLeft,Element.scrollTop

Element.scrollLeft 属性表示当前元素的水平滚动条向右侧滚动的像素数量,

Element.scrollTop 属性表示当前元素的垂直滚动条向下滚动的像素数量。对于那些没有滚动条的网页元素,这两个属性总是等于0

如果要查看整张网页的水平的和垂直的滚动距离,要从document.documentElement 元素上读取

document.documentElement.scrollLeft
document.documentElement.scrollTop

Element.offsetHeight,Element.offsetWidth

Element.offsetHeight 属性返回一个整数,表示元素的 CSS 垂直高度(单位像素),包括元素本身的高度、padding 和 border,以及水平滚动条的高度(如果存在滚动条)。

Element.offsetWidth 属性表示元素的 CSS 水平宽度(单位像素),其他都与 Element.offsetHeight 一致。

这两个属性都是只读属性,只比 Element.clientHeight 和 Element.clientWidth 多了边框的高度或宽度。如果元素的 CSS 设为不可见(比如 display: none; ),则返回 0

Element.offsetLeft,Element.offsetTop

Element.offsetLeft 返回当前元素左上角相对于 Element.offsetParent 节点的水平位移, Element.offsetTop 返回垂直位移,单位为像素。通常,这两个值是指相对于父节点的位移

操作CSS

操作 CSS 样式最简单的方法,就是使用网页元素节点的 setAttribute 方法直接操作网页元素的 style 属性

div.setAttribute('style','background-color:red;' + 'border:1px solidblack;');

事件处理程序

HTML事件处理

<div id="div">
    <button id="btn1"onclick="demo()">按钮</button>
 </div>
 function demo(){
                alert("hello html事件处理");
           }

DMO0级事件处理

<div id="div">
    <button id="btn1"onclick="demo()">按钮</button>
 </div>
 var btn1=document.getElementById("btn1");
        btn1.onclick=function(){alert("Hello,DOM0级事件处理程序1");}//被覆盖掉
        btn1.onclick=function(){alert("Hello,DOM0级事件处理程序2");}

DOM2级事件处理

<div id="div">
    <button id="btn1"onclick="demo()">按钮</button>
 </div>
 var btn1=document.getElementById("btn1");
      btn1.addEventListener("click",demo1);
      btn1.addEventListener("click",demo2);
      btn1.addEventListener("click",demo3);
        function demo1(){
            alert("DOM2级事件处理程序1")
       }
        function demo2(){
            alert("DOM2级事件处理程序2")
       }
        function demo3(){
            alert("DOM2级事件处理程序3")
       }
      btn1.removeEventListener("click",demo2);

定时器之 setTimeout()

定时执行代码的功能,叫做定时器(timer),主要由 setTimeout() 和 setInterval() 这两个函数来完成。它们向任务队列添加定时任务

setTimeout 函数用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。

setTimeout 函数接受两个参数,第一个参数 func|code 是将要推迟执行的函数名或者一段代码,第二个参数 delay 是推迟执行的毫秒数

var timerId = setTimeout(func|code, delay);

注意:如果回调函数是对象的方法,那么setTimeout 使得方法内部的 this 关键字指向全局环境,而不是定义
时所在的那个对象

定时器可以进行取消, clearTimeout(id);

定时器之 setInterval()

setInterval 函数的用法与 setTimeout 完全一致,区别仅仅在于 setInterval 指定某个任务每隔一段时间就执行一次,也就是无限次的定时执行

var timer = setInterval(function() {console.log(2);}, 1000)

定时器可以进行取消,clearInterval(id);

防抖(debounce)

防抖严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死

从滚动条监听的例子说起

function showTop () {
    var scrollTop =document.documentElement.scrollTop; 
    console.log('滚动条位置:' + scrollTop);
    } 
    window.onscroll  = showTop

在运行的时候会发现存在一个问题:这个函数的默认执行频率,太!高!了!然而实际上我们并不需要如此高频的反馈,毕竟浏览器的性能是有限的
基于上述场景,首先提出第一种思路:在第一次触发事件时,不立即执行函数,而是给出一个期限值比如200ms,然后

如果在200ms内没有再次触发滚动事件,那么就执行函数
如果在200ms内再次触发滚动事件,那么当前的计时取消,重新开始计时

效果:如果短时间内大量触发同一事件,只会执行一次函数

实现:既然前面都提到了计时,那实现的关键就在于setTimeout这个函数,由于还需要一个变量来保存计时,考虑维护全局纯净,可以借助闭包来实现

function debounce(fn,delay){
    let timer = null //借助闭包
    return function() 
    {
            if(timer){
                 clearTimeout(timer)    
                     }
             timer = setTimeout(fn,delay) // 简化写法
     }
 }
 // 然后是旧代码
 function showTop () {
     var scrollTop =document.documentElement.scrollTop;
     console.log('滚动条位置:' + scrollTop);
  }
     window.onscroll = debounce(showTop,300)

防抖定义
对于短时间内连续触发的事件(上面的滚动事件),防抖的含义就是让某个时间期限(如上面的1000毫秒)内,事件处理函数只执行一次

闭包

要理解闭包,首先必须理解Javascript特殊的变量作用域。

变量的作用域无非就是两种:全局变量和局部变量。

Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

另一方面,在函数外部自然无法读取函数内的局部变量

这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!

如何从外部读取局部变量?

出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。

那就是在函数的内部,再定义一个函数。

function f1(){
   var n=999;
   function f2(){
   alert(n);//999
   }
}

在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1就是不可见的。这就是Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!

function f1(){

    var n=999;

    function f2(){
      alert(n);
    }

    return f2;

  }

  var result=f1();

  result(); // 999

代码中的f2函数,就是闭包。闭包就是能够读取其他函数内部变量的函数。

闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

注意
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

节流(throttle)

如果在限定时间段内,不断触发滚动事件(比如某个用户闲着无聊,按住滚动不断的拖来拖去),只要不停止触发,理论上就永远不会输出当前距离顶部的距离

我们可以设计一种类似控制阀门一样定期开放的函数,也就是让函数执行一次后,在某个时间段内暂时失效,过了这
段时间后再重新激活(类似于技能冷却时间)

效果:如果短时间内大量触发同一事件,那么在函数执行一次之后,该函数在指定的时间期限内不再工作,直至过了这段时间才重新生效
借助setTimeout来做一个简单的实现,加上一个状态位valid来表示当前函数是否处于工作状态

function throttle(fn,delay){
    let valid = true
    return function() {
       if(!valid){
           //休息时间 暂不接客
           return false
       }
       // 工作时间,执行函数并且在间隔期内把状态位设为无效
        valid = false
        setTimeout(function(){
            fn()
            valid = true;
       }, delay)
   }
 }

 function showTop () {
    var scrollTop =document.documentElement.scrollTop;
    console.log('滚动条位置:' + scrollTop);
 }
 window.onscroll = throttle(showTop,300)

如果一直拖着滚动条进行滚动,那么会以300ms的时间间隔,持续输出当前位置和顶部的距离

适用场景
1、搜索框input事件,例如要支持输入实时搜索可以使用节流方案(间隔一段时间就必须查询相关内
容),或者实现输入间隔大于某个值(如500ms),就当做用户输入完成,然后开始搜索,具体使
用哪种方案要看业务需求

2 、页面resize事件,常见于需要做页面适配的时候。需要根据最终呈现的页面情况进行dom渲染(这
种情形一般是使用防抖,因为只需要判断最后一次的变化情况)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值