農曆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 對閉包的引用。
關注的個人公衆號不按期分享前端知識,與您一塊兒進步!