js--理解

本文深入讲解JavaScript核心概念,包括事件流、数据类型、对象管理、垃圾回收、闭包原理、面向对象、深浅拷贝、正则表达式、HTTP请求方式、this指向规则、防抖与节流技术等,助你掌握前端开发关键技能。

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

记录下

1.DOM事件流存在三个:事件捕获,目标事件,事件冒泡

事件捕获:由外到内
事件冒泡:由内到外

2.基本数据类型的symbol

https://www.jianshu.com/p/f40a77bbd74e
https://www.jianshu.com/p/71b2f4e8d6db
symbol应用场景
(1)定义对象的属性名
注意:symbol类型的key用for …in或者Object.keys()是拿不到的
(2)使用symbol来代替常量
(3)使用symbol定义类的私有属性/方法
在这里插入图片描述

3.对象

(1)内建对象:function,array ,math,string,
(2)宿主对象:浏览器(BOM),文档流(DOM)
(3)自定义对象

  • obj[n]—n表示的是变量
  • 基本数据类型存在栈,引用类型是存在堆中
  • 对象的属性是函数叫做对象的方法
4.垃圾回收

当对象没有属性或方法进行引用的话,对象就是垃圾,垃圾会占用内存空间,导致程序运行慢。
浏览器有自带的垃圾回收机制,不同浏览器的垃圾回收机制不一样,我们手动回收垃圾就是将不用的对象设置为null

5.闭包理解

闭包就是函数能够访问另一个函数作用域中的变量,一直持有对变量的访问,一直占有内存,所以不会被垃圾回收机制回收,内存在一定的情况下会造成内存泄漏。解决的办法是在退出函数之前,将不使用的变量手动清除

闭包的优点可以避免全局变量的污染,封装对象的属性和私有方法。缺点是占用内存可能内存泄漏
https://www.jianshu.com/p/26c81fde22fb
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
https://www.jb51.net/article/126565.htm
首先,函数可以构成闭包,这个函数可以访问到另一个函数的变量。闭包的作用就是间接的访问数据,延长了变量的作用域。
因为0级链无法操作1级链的,通过2级链可以操作1级链,然后将2级链返回回去,再赋值给0级链

var a = 1;
function fn(){
    var b = 2;
    function fn1(){
        console.log(b);
    }
    fn1();
}
fn();

每个函数都有自己的执行环境,当一个函数被执行时,它的执行环境就会被推入环境栈,其活动对象(存储环境中定义的变量及函数)加入作用域链中,一旦函数执行完,栈将其环境弹出,活动对象被销毁。
在这里插入图片描述
闭包带来的问题:
a.引用的变量发生变化
b.this指向问题
c.内存泄漏问题

使用闭包的好处:
a.解决递归调用问题
b.模仿块级作用域

null释放闭包
闭包的应用
a. 获得超过1个数据=>用对象打包
在这里插入图片描述
b:如何读取一个数据和修改这个数据

在这里插入图片描述

c.利用闭包的方法得到当前li的索引

 <ul class="nav">
      <li>000</li>
      <li>111</li>
      <li>222</li>
      <li>333</li>
  </ul>

 var lis = document.querySelector('.nav').querySelectorAll('li')
 for(var i=0;i<lis.length;i++){
    (function (i){
   lis[i].onclick = function(){
       console.log(i)
   }
       })(i)

e.利用闭包:延迟打印li内容

for(var i=0;i<lis.length;i++){
    (function(i){
        setTimeout(function(){
          console.log(lis[i].innerHTML)
        },2000)
    })(i)
}
6.setTimeOut的第三个参数

=>给function函数传递参数

7.Object.assign(target,sources)

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
target-----目标对象
source-----源对象
返回目标对象
如果目标对象的具有和源对象相同的键值,则会被源对象给覆盖了。
Object.assign 方法只会拷贝源对象自身的并且可枚举的属性到目标对象。注意,Object.assign 不会在那些source对象值为 null 或 undefined 的时候抛出错误。针对深拷贝,需要使用其他办法,因为 Object.assign()拷贝的是属性值。假如源对象的属性值是一个对象的引用,那么它也只指向那个引用。

8.展开运算符(…)

https://www.jianshu.com/p/3935a80342a0
将一个数组转为用逗号分隔的参数序列
(0)浅拷贝
在这里插入图片描述
(1)合并数组
(2)代替apply,==>作为实参
let args =[1,2,3]
eg:fun(…args)
(3)解构赋值
解构赋值中展开运算符只能用在最后:
在这里插入图片描述
(4)将字符串数组转为单个字符的数组
在这里插入图片描述
(5)具有 Iterator 接口的对象,转换成数组

9.深浅拷贝

浅拷贝拷贝的是对象指针,共用了内存空间。所以浅拷贝对象如果还有对象的话就不行了,因为拷贝的是相同的引用,被修改了就都变了。所以才需要深拷贝。深拷贝的是完全一样的对象,不同的内存空间。深拷贝之后改变一个不会改变另一个。

var obj ={
    name:'dalin',
    age:18,
    sampleCopy:function(){
        var newObj = {};
        for(k in this){
            newObj[k] = this[k];
            return newObj
        }
    }
}
  var obj1 = obj.sampleCopy()

浅拷贝通过Object.assign()或者是(…)
深拷贝通过JSON.parse(JSON.stringify()),会忽略undefined,null,函数.循环引用对象。可以使用lodash的深拷贝函数

注意:用(…)展开运算符号解决浅拷贝问题(对象的属性没有引用型),
用JSON.parse(JSON.stringify(Object))来解决(对象的属性有引用型),
局限性:会忽略undefined,symbol,不能序列函数,不能解决循环引用的对象.
但是在通常情况下,复杂数据都是可以序列化的,所以这个函数可以解决大部分问题,并且该函数是内置函数中处理深拷贝性能最快的。

var deepCopy= function (){
    var temp = {};
    for(k in this){
        if( typeof this[k] === "Object"){
            temp[k] = this[k].deepCopy
        }else{
            temp[k] = this[k]
        }
    }
    return temp
}

var car = {name:"car"}
var p = {
    name:'p',
    gender:'boy',
    car:car
}
car.deepCopy = deepCopy
p.deepCopy = deepCopy

var newp = p.deepCopy();
p.name = "ppppp"
console.log("p.name:",p.name)
console.log("newp.name",newp.name)
10.面向对象的理解

面向过程:通过步骤一步步的完成,比如将大象装入冰箱,第一步是打开冰箱,第二步是将大象塞进冰箱,第三步是关冰箱
优点:性能比面向对象高
缺点:代码难维护,不易复用

面向过程是对面向过程的封装,对对象功能进行划分。找到大象,找到冰箱,给大象进去冰箱的功能,给冰箱打开和关闭的功能,然后再通过逻辑步骤去实现。冰箱先打开,大象进去冰箱,冰箱关闭。
优点:通过功能划分,分工明确,具有灵活性,代码可复用,容易维护和开发
缺点:性能低

特性:
抽象性:抽取核心数据,不在特定条件下不知道是什么。
封装性:对象是将数据和功能组合在一起
对象将属性和方法封装在一起
方法是将过程封装起来

继承:拿别人东西当作自己的用,继承是实现复用的手段
多态:一个引用类型在不同情况下有多种状态

11.类和对象

12.js的onload和jq的ready区别
js的onload是指html文档和外部资源下载完,
jq的ready只需要下载html文档即可

13.什么是js语言

基于原型,弱类型,基于对象,不需要编译的脚本,用来给HTML添加动态功能

14.||和&&
  • ||
    当||的左边为真时就返回左边的值,如果左边的是假的就是右边的值!
    一般用函数参数的兼容性
  • &&
    返回false,如果左边是false直接返回左边,如果左边不是false,返回右边的。
15.严格模式

在这里插入图片描述
使用严格模式之后的变化

1.变量必须声明再使用
2.不能删除已经声明的变量
3.全局作用域中this的指向undefined
4.函数不能有重名的函数名字
5.不能在函数声明外写函数,eg:如图所示
在这里插入图片描述
6.不能使用八进制

16.递归函数:在函数内部调用自己的函数,和循环效果差不多,需要return防止死循环。
17.正则表达式:用于匹配字符串中组合的模式,是对象。

应用:表单验证,过滤敏感词,从字符串中获得的特定部分

18.get/post区别
区别getpost
0把请求的数据放在url上把数据放在HTTP的包体内
1提交的数据少提交的数据多
2产生1个TCP数据包产生2个TCP数据包
3在浏览器回退时是无害的在浏览器回退时重新提交请求
4请求参数会被完整保留在浏览器历史记录请求参数不会被完整保留在浏览器历史记录
5只能进行url编码支持多种编码方式
6只接受ASCII字符的参数的数据类型没有限制

对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);

而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。

也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。

因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?

  1. GET与POST都有自己的语义,不能随便混用。

  2. 据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。

  3. 并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。

19.this问题

https://lijing0906.github.io/post/JSthis
this运行环境有全局和局部是因为内存的数据结构有关系
在这里插入图片描述
在这里插入图片描述
注意,foo属性的值保存在属性描述对象的value属性里面。
对于函数

在这里插入图片描述
由于函数是一个单独的值,所以它可以在不同的环境(上下文)执行。
所以,this就出现了,它的设计目的就是在函数体内部,指代函数当前的运行环境。

(1)默认绑定:默认全局为window,在严格模式下为undefined
(2)隐式绑定:带来隐式丢失的问题(函数别名和回调函数)原因在于调用的时候还是全局调用
(3)显示绑定:通过call,apply,bind指定(硬绑定后的不能再修改this ),无法解决丢失绑定的问题
(4)new绑定:new的过程做了什么
(5)箭头函数:箭头函数不能使用以上的四条规则,this绑定的对象在箭头函数定义的地方。
(6)绑定例外:当call,apply,bind传入的参数是null,undefined会忽略,采用默认绑定机制,解决办法是使用Object.create(nulll)创建没有原型属性的对象

20.防抖和节流

防抖是指在n秒内只会触发一次事件,从最后一次触发开始计时开始
节流是在一段时间内就会触发一次事件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值