.
timg.jpeg
1.关于什么是js提升
无论作用域中的声明出现在什么地方,都将在代码本身被执行前首先进行处理。即所有声明(变量和函数)都会被“移动”到各自作用域的最顶端,该过程称为“提升”。
a = 2;//赋值->执行阶段
var a;//声明->编译阶段
console.log(a);//2执行阶段
//定义声明是在编译阶段进行的,而赋值声明是在执行阶段进行的
函数同样会提升,且函数的提升优先于变量的提升
foo();
var foo;
function foo(){
console.log(1);
}
foo = function(){
console.log(2);
};
//最终的打印结果是1
后面的函数声明会覆盖前面的
foo();
function foo(){
console.log(1)
}
var foo = function(){
console.log(2)
}
function foo(){
console.log(3)
}
//打印结果为3
2.TDS
暂时性死区Temporal Dead Zone
3.什么是暂时性死区
简单说只有当变量被初始话赋值后才能使用,在初始话赋值前使用会报错ReferenceError这个阶段就是暂时性死区.let和const有死区.
4.js变量
分创建create(编译阶段)、初始化initialize和赋值assign(运行时)
5.var和function的提升
function foo () {
console.log(x)//x = undefined
var x = 'a'
//var创建和初始话提升了,赋值阶段没有提升
}
foo()
function foo (){
console.log(2)//2
function的创建,初始话,赋值都被提升了
}
6.let变量和const能不能被提升?
先看一段代码
function foo () {
console.log(x)
let x = 0;
}
这段代码编译时不会有问题,运行时会报错Uncaught ReferenceError: x is not defined,也就是说在创建时let变量被提升了,但是初始话的时候没有被提升.
const同理
7.let,const和for搭配使用注意事项
let/const 在与 for 一起用时,会有一个 perIterationBindings 的概念(一种语法糖)。会有一个隐藏的作用域.
// 代码段1
var liList = document.querySelectorAll('li') // 共5个li
for( var i=0; i<liList.length; i++){
liList[i].onclick = function(){
console.log(i)
}
}
//5,5,5,5,5
// 代码段2
var liList = document.querySelectorAll('li') // 共5个li
for( let i=0; i<liList.length; i++){
liList[i].onclick = function(){
console.log(i)
}
}
//0,1,2,3,4
//代码段2其实有一个隐藏的作用域见代码段3
// 代码段3
var liList = document.querySelectorAll('li') // 共5个li
for( let i=0; i<liList.length; i++){
//隐藏作用域
let i1 = i // 看这里看这里看这里
liList[i].onclick = function () {
console.log(i1);
}
}
8.普通函数和箭头函数
(1)普通函数
function func () {
}
(2)箭头函数
let func = () => {
}
(3)普通函数可以是具名函数也可以是匿名函数,箭头函数都是匿名函数
function func () {
//具名函数
}
let func = function () {
//匿名函数,只不过是将函数赋值给了func
}
let func = () => {
//匿名函数,只不过是将函数赋值给了func
}
(4)箭头函数不可以用来构造函数 报错,普通函数可以构造函数创建对象实例
let func = function (name) {
console.log(name)
}
let fun = new func('构造函数')
//fun是一个函数实例
(5)this的指向不同
谁调用就指向谁
普通函数调用
var a = 'cn'
function func () {
console.log(this.a)
}
func()//打印cn
//因为func是被window调用的,所以this指向的window
匿名函数调用
var a = 'cn'
let func = function () {
console.log(this.a)
}
func()//打印cn
//理由同上被window调用
对象函数调用
let obj = {
a:'cn',
fn:function () {
console.log(this.a)
}
}
obj.fn()//打印cn
//fn是被obj调用的所以this指向的是obj
构造函数调用
var name = 'dong'
let test = function () {
this.name = 'wu'
console.log(this.name)
}
let testClass = new test()
console.log(testClass.name)//wu
有一个特例,当有return时实例对象指向的是需要返回的那个对象,返回的不是对象比如值的时候实例对象仍指向当前函数
9.let定义的全局变量不能使用this和window指向
继续看一下下面三篇文章
https://www.cnblogs.com/pssp/p/5216085.html
https://www.cnblogs.com/honkerzh/p/10270624.html
https://blog.csdn.net/latency_cheng/article/details/80022066
参考链接
参考链接1







网友评论