1.变量作用域
1.1 var与let
区别:(let是以代码块为作用域,let定义的全局变量不是window对象,在相同的块中不能重复声明let变量,let声明的变量不会提升到顶端)
var变量的定义并不是以代码块作为作用域的,而是以函数作为作用域。,他并不像JAVA一样在for循环内部声明的变量,在for循环外部就不能使用
函数内部定义变量的时候如果没有加var,就是全局变量;否则为局部变量;当fun()没有执行的时候,方法内部的全局变量是不会声明并且定义的
1.2变量提升
var a=2;
function x(){
console.info(a);//undefinded
var a=6;//变量声明提示至函数开始位置
console.info(a);//6
}
当js执行过程进入新的函数时,这个函数内被声明的所有变量所有变量都会被移动(或者说提升)到函数最开始的地方。另外,需要注意,被提升的只有变量的声明,而与之相关的赋值操作并不会被提升,它还在原来的位置上。
1.3变量作用域延长
with(变量名)、try-catch :with为了简化多次编写访问同一对象的工作,将一个特定的变量对象存储到作用域链的最上层 var obj={a:3,b=4} 用with(obj){a=2,b=5}相当与obj.a=2;obj.b=5 简化了代码
1.4垃圾回收机制GC
(把不可达无法访问的数据块从内存中删除)
算法:标记清除(常用 标记根及其引用,剩下的所有对象没有被标记的对象都被删除 )、引用计数(不常用)
优化GC:分代回收(多回收临时对象区,少回收持久对象区)
常见内存泄漏的原因:全局变量、闭包、循环引用
2.运算符
算术运算符(+-*/)、赋值运算符(=,+=,-=...)、字符串运算符(+,+=)
比较运算符(=,>,<,!=,>=,<=)
!== | 值与类型均不等(不恒等于) |
=== | 值及类型均相等(恒等于) |
条件运算符(变量 = (条件) ? 值1:值2)、逻辑运算符(&&,||,!)
位运算符
& | AND | x = 5 & 1 | 0101 & 0001 | 0001 | 1 |
| | OR | x = 5 | 1 | 0101 | 0001 | 0101 | 5 |
~ | 取反 | x = ~ 5 | ~0101 | 1010 | -6 |
^ | 异或 | x = 5 ^ 1 | 0101 ^ 0001 | 0100 | 4 |
<< | 左移 | x = 5 << 1 | 0101 << 1 | 1010 | 10 |
>> | 右移 | x = 5 >> 1 | 0101 >> 1 | 0010 | 2 |
=>是箭头函数的简写方式,x => x * x 相当于 function(x){return x*x} 是ES6新规范*(区别于匿名函数:箭头函数修复了this的指向, this 总是指向词法作用域, 也就是外层调用者obj)
3.对象(属性+方法)
两种对象中属性调用方式 obj.property 或 obj["property"]
3.1 宿主对象中的BOM 与DOM
3.1.1 BOM:浏览器对象模型(运行javascript与浏览器对话)
window对象是BOM的核心对象,包括6大属性同时也是方法:document、location、navigation、screen、history、frames
Document是DOM的核心对象(根节点),window.document=document ==>BOM包含了DOM
https://www.jianshu.com/p/f5409202a835
常用方法:
- window.innerHeight - 浏览器窗口的内高度(以像素计)
- window.innerWidth - 浏览器窗口的内宽度(以像素计)
- window.open() - 打开新窗口
- window.close() - 关闭当前窗口
- window.moveTo() -移动当前窗口
- window.resizeTo() -重新调整当前窗口
- window.alert()、window.confirm
- window.onload() 在文档树和所有文件加载完成之后的入口函数
3.1.2 DOM document对象
当浏览器载入html后,就会生成一个document对象,document对象是HTML文档的根节点
属性:document.anchors(返回对anchors对象的引用),还有document.links、document.forms等等
document.body、document.url、document.title
方法:document.getElementByClassName()、getElementBybyId()、getElementByName()、getElementByTagName()
document.addEventListener(事件名,function),监听整个文档
document. write()向文档写 HTML 表达式 或JavaScript 代码
document.open() document.close() 打开/关闭一个流 文件流
document.createElement()、document.createAttribute()、 document.createTextNode()创建元素/属性/文本节点
3.1.3 DOM元素对象(元素节点)
常用属性:
element.innerHTML、.innerText(设置或者返回元素的内容,后者不包含节点中的子标签以及内容)
element.nodeType 、.nodeName 、.nodeValue(返回节点的名字(大写)、类型、节点值,元素节点的节点值为null)
element.id 、.className、 .tagName(大写)
element.childNodes 返回元素的子节点的nodeslist对象,nodelist类似于数组(!=),有length属性,可以使用方括号 [index] 访问指定索引的值(也可以使用item(index)方法)。
element.firstChild / element.lastChild(包含注释节点和文本节点) element.firstElementChild /lastElementChild (不包含)
element.parentNode 返回该结点的父节点
element.previousSibling 、element.nextSibling上一个或下一个兄弟节点
element.style 设置或返回元素的样式属性
宽高计算属性
- element.clientHeight/clientWidth 返回内容的可视高度/宽度(不包括边框,边距或滚动条)
- element.offsetHeight/offsetWidth /offsetLeft/offsetTop 返回元素的高度/宽度/相对于父元素的左偏移/右偏移(包括边框和填充,不包括边距)
- element.scrollHeight/scrollWidth/scrollLeft/scrollTop返回整个元素的高度(包括带滚动条的隐蔽的地方)/宽度/返回当前视图中的实际元素的左边缘和左边缘之间的距离/上边缘的距离
元素节点常用方法
element.appendChild(node) 向元素添加新的子节点(添加新元素,必须创建该元素,然后把它追加到已有的元素上)
element.removeChild() 从元素中移除子节点(移除的节点虽然不在文档树中了,但其实还在内存中,可以随时被引用)
element.getAttribute(attr)返回元素节点的指定属性值 element.setAttribute(attrName,attrValue) 设置指定属性值
element.getAttributeNode(para) 返回指定的属性节点
element.hasAttribute(para) 判断元素是否拥有指定属性
element.removeAttribute() 从元素中移除指定属性
3.1.4 DOM 事件对象
event对象代表事件的状态,包括导致事件的元素、事件的类型、以及其它与特定事件相关的信息等。这个对象是在执行事件时,浏览器通过函数传递过来的。(一旦事件发生就会生成event对象)
属性:target: firefox 下的 event.target = IE 下的 event.srcElement(触发事件源)
currentTarget:返回其监听器触发事件的节点,就是事件句柄写在的元素
event对象方法:event.preventDefault() 通知浏览器不要执行与事件关联的默认动作。
event.stopPropagation() 阻止冒泡或捕获
冒泡:事件从下到上响应 先fn2()
捕获:事件从上至下响应 先fn1()
<div οnclick="fn1()">
<p οnclick="fn2()">元素</p>
</div>
在W3C模型中,任何事件发生时,先从顶层开始进行事件捕获,直到事件触发到达了事件源元素。然后,再从事件源往上进行事件冒泡,直到到达document(这里的捕获阶段 冒泡阶段只是个事件传播过程的描述,而一般说的捕获冒泡,是两种不同的事件响应方式,概念问题,莫纠结了)。像这样(ele.onclick = doSomething2)的绑定事件方式,是采用的事件冒泡方式。
通过addEventListener函数,它有三个参数,第三个参数true=事件捕获,若是false=事件冒泡。(IE浏览器不支持捕获,没有addEventListener)现代浏览器默认都是冒泡类型。
preventDefault()方法,阻止事件的默认行为,如click<a>的跳转
jQuery 事件处理程序里return false 代表阻止事件向上冒泡,它实际包括3个步骤:
-
event.preventDefault();
-
event.stopPropagation();
-
停止回调函数执行并立即返回
事件绑定 DOM 元素绑定事件(事件是DOM元素的一个属性)
- 1.DOM元素中直接绑定
- 2.js中绑定
- document.getElementById('btn').onclick = function(){
- this.style.background = 'yellow';
- }
- 3.绑定事件监听函数 addEventListener() 或 attachEvent()
elementObject.addEventListener(eventName,handle,useCapture);
eventName | 事件名称。注意,这里的事件名称没有“ on ”,如鼠标单击事件 click ,鼠标双击事件 doubleclick ,鼠标移入事件 mouseover,鼠标移出事件 mouseout 等。 |
handle | 事件句柄函数,即用来处理事件的函数。 |
事件委托 = “事件在外层元素中的捕获:利用冒泡原理,把本应该添加到某个元素上的事件委托给他的父级(代为接收)
事件句柄:就是事件处理函数 ,比如onclick
事件源:就是即事件句柄的第一个参数(Event对象/事件对象)下的Event.target
4.js执行顺序
1.js的执行顺序,先同步后异步
2.异步中任务队列的执行顺序: 先微任务microtask队列,再宏任务macrotask队列
3.调用Promise 中的resolve,reject属于微任务队列,setTimeout属于宏任务队列
注意以上都是 队列,先进先出。
5.难搞懂概念
5.1 this
this指向正在调用当前方法的对象
1. obj.fun() fun中的this->obj,自动指向.前的对象
2. new Fun() Fun中的this->正在创建的新对象,new改变了函数内部的this指向,导致this指向实例化new的对象
3. fun()和匿名函数自调 this默认->window,函数内部的this,this默认是指向window的
4. 回调函数中的this默认是指向window的(当回调函数写成箭头函数时,箭头函数根本没有自己的this,导致内部的this就是外层代码块的this)
5.2 call()、apply()
call()、apply() 都是用来重定义 this 这个对象的,都是在特定的作用域中调用函数,等于设置函数体内this对象的值,以扩充函数赖以运行的作用域,this总是指向调用某个方法的对象(指向当前作用域最近的父对象即它的直接调用者,还与上下文有关,没找到直接调用者,则this指的是 window/undefined);不同点:接收参数的方式不同。
apply()方法 接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
call()方法 第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来
apply()和call()方法第一个参数为null时,都表示为函数调用模式,也就是this指向window
5.3 回调函数
回调是在另一个函数执行完成之后再被执行的函数,任何可以作为参数被传递的函数称为回调函数
误点: 回调函数一定会再父函数所有操作完成后运行?-----有异步时并不会,,
5.4 闭包
闭包是指能够访问另一个函数作用域的变量的函数
5.4 原型链
继续往上 Object.prototype.__proto__ // null, Object.prototype没有原型