记录下
文章目录
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区别
区别 | get | post |
---|---|---|
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来优化网站性能。但这是一个坑!跳入需谨慎。为什么?
-
GET与POST都有自己的语义,不能随便混用。
-
据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
-
并不是所有浏览器都会在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秒内只会触发一次事件,从最后一次触发开始计时开始
节流是在一段时间内就会触发一次事件