在 ES5 中,顶层对象的属性和全局变量是等价的,var 命令和 function 命令声明的全局变量,自然也是顶层对象。
但 ES6 规定,var 命令和 function 命令声明的全局变量,依旧是顶层对象的属性,但 let 命令、const 命令、class 命令声明的全局变量,不属于顶层对象的属性。
const 和 let 会生成块级作用域。
var 是全局变量,存在变量作用域提升。
变量生命周期:声明(作用域注册一个变量)、初始化(分配内存,初始化为 undefined)、赋值
var:遇到有 var 的作用域,在任何语句执行前都已经完成了声明和初始化,也就是变量提升而且拿到 undefined 的原因由来
function: 声明、初始化、赋值一开始就全部完成,所以函数的变量提升优先级更高
let:解析器进入一个块级作用域,发现 let 关键字,变量只是先完成声明,并没有到初始化那一步。此时如果在此作用域提前访问,则报错 xx is not defined,这就是暂时性死区的由来。等到解析到有 let 那一行的时候,才会进入初始化阶段。如果 let 的那一行是赋值操作,则初始化和赋值同时进行
var name = "The Window";
var object = {
name: "My object",
getNameFunc: function() {
return function() {
return this.name;
};
}
}
alert(object.getNameFunc()()); // "The Window"
把最后的一句拆成两个步骤执行:
var first = object.getNameFunc();
var second = first();
其中第一步,获得的first为返回的匿名函数,此时的getNameFunc()作为object的方法调用,如果在getNameFunc()中使用this,此时的this指向的是object对象。
第二部,调用first函数,可以很清楚的发现,此时调用first函数,first函数没有在对象中调用,因此是作为函数调用的,是在全局作用域下,因此first函数中的this指向的是window。
var name = "The Window";
var object = {
name: "My object",
getNameFunc: function() {
var that = this; // 将getNameFunc()的this保存在that变量中
var age = 15;
return function() {
return that.name;
};
}
}
alert(object.getNameFunc()()); // "My object"
其中,getNameFunc()执行时的活动对象有:that/age/匿名函数,在执行匿名函数时,同时引用了getNameFunc()中的活动对象,因此可以获取that和age的值。但是由于是在全局环境中调用的匿名函数,因此匿名函数内部的this还是指向window。
防抖和节流
防抖:触发高频事件后 n 秒内函数只会执行一次,如果 n 秒内高频事件再次被触发,则重新计算时间。
节流:高频事件触发,但在 n 秒内只会执行一次,所以节流会稀释函数的执行频率。
判断是否为数组的方法
模块化发展历程
模块化主要是用来抽离公共代码,隔离作用域,避免变量冲突等。思维导图
全局作用域
变量生命周期:声明(作用域注册一个变量)、初始化(分配内存,初始化为 undefined)、赋值
箭头函数和普通函数的区别
箭头函数是普通函数的简写,可以更优雅的定义一个函数,和普通函数相比,有以下几点差异:
ES6 转 ES5 的思路
参考 Babel 的实现方式,其大致分为三步:
setTimeout、Promise、Async/Await 的区别
JS Intel 对象介绍
Intl 对象是 ECMAScript 国际化 API 的命名空间,它提供对语言敏感的字符串比较、支持数字格式化以及日期和时间的格式化。
JS DOM innerText 和 textContent 的区别
JS DOM变化的监听检测
分析地址栏url,获取参数
浏览器已经有了内置的API接口可以对URL进行处理,这个API就是URLSearchParams()以及URL()
form原生JS验证方法和属性
js工具
zepto和jquery的区别
js闭包this解决