农历2019即将过去,趁着年前几天上班事情少,整理了一下javascript的基础知识,在此给你们作下分享,喜欢的大佬们能够给个小赞。本文在github也作了收录。javascript
本人github: github.com/Michael-lzg前端
Javascript 变量的做用域无非就是两种:全局变量和局部变量。Javascript 语言的特殊之处,就在于函数内部能够直接读取全局变量。vue
在代码中任何地方都能访问到的对象拥有全局做用域,通常来讲一下几种情形拥有全局做用域:java
var name = 'Jack' // 全局定义
function foo() {
var age = 23 // 局部定义
function inner() {
// 局部函数
console.log(age) //age 23
}
inner()
}
console.log(name) // yuan
console.log(age) // Uncaught ReferenceError: age is not defined,在外部没有这个变量
foo() // 内嵌函数的打印23
inner() // Uncaught ReferenceError: inner is not defined 由于内嵌函数,找不到这个函数
复制代码
var name = 'yuan'
function foo() {
age = 23 // 全局定义
var sex = 'male' // 局部定义
}
foo()
console.log(age) // 23
console.log(sex) // sex is not defined
复制代码
当代码在一个环境中执行时,会建立变量对象的一个做用域链(做用域造成的链条)webpack
当在内部函数中,须要访问一个变量的时候,首先会访问函数自己的变量对象,是否有这个变量,若是没有,那么会继续沿做用域链往上查找,直到全局做用域。若是在某个变量对象中找到则使用该变量对象中的变量值。git
内部环境能够经过做用域链访问全部外部环境,但外部环境不能访问内部环境的任何变量和函数。github
ES6 以前咱们通常使用 var 来声明变量,变量提高以下例子:web
function test() {
console.log(a) //undefined
var a = 123
}
// 它的实际执行顺序以下
function test() {
var a
console.log(a)
a = 123
}
test()
复制代码
javascript 中不只仅是变量声明有提高的现象,函数的声明也是同样。具名函数的声明有两种方式:算法
//函数声明式
function bar() {}
//函数字面量式
var foo = function() {}
复制代码
函数提高是整个代码块提高到它所在的做用域的最开始执行vue-cli
console.log(bar)
function bar() {
console.log(1) //ƒ bar () { console.log(1)}
}
// 实际执行顺序
function bar() {
console.log(1)
}
console.log(bar)
复制代码
闭包就是可以读取其余函数内部变量的函数,函数没有被释放,整条做用域链上的局部变量都将获得保留。因为在 javascript 语言中,只有函数内部的子函数才能读取局部变量,所以能够把闭包简单理解成“定义在一个函数内部的函数”。
建立闭包最多见方式,就是在一个函数内部建立另外一个函数。闭包的做用域链包含着它本身的做用域,以及包含它的函数的做用域和全局做用域。
function fn() {
var a = 1,
b = 2
function f1() {
return a + b
}
return f1
}
复制代码
上面例子中的 f1 就是一个闭包
function Animal() {
// 私有变量
var series = '哺乳动物'
function run() {
console.log('Run!!!')
}
// 特权方法
this.getSeries = function() {
return series
}
}
复制代码
var objEvent = objEvent || {}
(function() {
var addEvent = function() {
// some code
}
function removeEvent() {
// some code
}
objEvent.addEvent = addEvent
objEvent.removeEvent = removeEvent
})()
复制代码
addEvent 和 removeEvent 都是局部变量,但咱们能够经过全局变量 objEvent 使用它,这就大大减小了全局变量的使用,加强了网页的安全性。
function module() {
var arr = [];
function add(val) {
if (typeof val == 'number') {
arr.push(val);
}
}
function get(index) {
if (index < arr.length) {
return arr[index]
} else {
return null;
}
}
return {
add: add,
get: get
}
}
var mod1 = module();
mod1.add(1);
mod1.add(2);
mod1.add('xxx');
console.log(mod1.get(2));
复制代码
function makeAdder(x) {
return function(y) {
return x + y
}
}
var add5 = makeAdder(5)
var add10 = makeAdder(10)
console.log(add5(2)) // 7
console.log(add10(2)) // 12
// 释放对闭包的引用
add5 = null
add10 = null
复制代码
add5 和 add10 都是闭包。它们共享相同的函数定义,可是保存了不一样的环境。在 add5 的环境中,x 为 5。而在 add10 中,x 则为 10。最后经过 null 释放了 add5 和 add10 对闭包的引用。
关注的个人公众号不按期分享前端知识,与您一块儿进步!