在最新的 ECMAScript 規範中,定義了7種數據類型閉包
其中前6種爲基礎數據類型,只有 object 爲引用類型app
基礎數據類型和引用類型劃分的依據是其在內存中存儲的形式ide
基礎數據類型在內存對應的位置存儲的是null,undefined,字符串,數值或布爾值(symbol)函數
引用類型在內存對應的位置存儲的是地址this
經過操做符 typeof 判斷數據類型,不過有如下例外spa
typeof null // 'object' typeof function(){} // 'function'
經過操做符 instanceof 判斷對象的類型prototype
The
instanceof operator tests whether the
prototype
property of a constructor appears anywhere in the prototype chain of an object.
只要該對象的原型鏈上有以該構造函數生成的對象,就返回truecode
[] instanceof Object // true [] instanceof Array // true [] instanceof Date // false
typeof function(){} // 'function'
函數也是對象對象
對象大都是經過函數new出來,不考慮函數對象ip
var obj = { a: 10, b: 20 }; // 將當作是一種語法糖 // 至關於 var obj = new Object(); obj.a = 10; obj.b = 20; var arr = [5, 'x', true]; // 至關於 var arr = new Array(); arr[0] = 5; arr[1] = 'x'; arr[2] = true;
函數Fn也是對象,具備屬性prototype,其指向一個對象P,經過new Fn()產生的對象fn,fn.__proto === Fn.prototype,Fn.prototype === P
Returns a reference to the
Object
constructor function that created the instance object.
對象經過 constructor 找到生母是誰
function Fn() { } let fn = new Fn() Fn.constructor === Function // true fn.constructor === Fn // true
.png)
經過 hasOwnPrototype ,判斷某屬性是對象自身擁有的,仍是其原型鏈上的
函數在執行以前會搜索函數體內全部經過 var 聲明的變量,將其移至函數體的開始
console.log(Person) // function Person(){} function Person(){ } var Person = 2 console.log(Person) // 2
console.log(Person) // function Person(){} var Person = 2 function Person(){ } Person // 2 // 至關於 console.log(Person) function Person(){ } var Person Person = 2
var v1 = {} function func(obj){ obj = { name: 'v1' } } func(v1) // 至關於 func(v1) function func(obj){ let obj = v1 obj = { name: 'v1' } }
函數中傳遞參數,至關於額外執行了let parameter = argument,在函數體內聲明變量名爲形參的局部變量,而且值爲實參
函數內部this指向的對象取決於函數被調用的情形。
函數能夠經過參數得到額外的變量,
函數也能夠經過this對象來得到額外的變量,
函數還能夠經過做用域得到額外的變量
相比於this對象,動態地得到額外的變量;經過做用域得到的額外的變量是在函數書寫的時候就肯定了,靜態做用域
let x = 10; function foo() { console.log(x); } function bar(funArg) { let x = 20; funArg(); // 10 } bar(foo);
函數在執行時,其上下文是基於它書寫的地方
閉包
1 function foo() { 2 var a = 2; 3 4 function bar() { 5 console.log( a ); 6 } 7 8 return bar; 9 } 10 11 var baz = foo(); 12 13 baz(); // 2
bar 內部包裹着一段代碼 console.log(a)
,雖然它在第13行,經過 baz 來調用,但實際上它執行時的上下文還是第5行的上下文
Closure is when a function is able to remember and access its lexical scope even when that function is executing outside its lexical scope.
閉包的本質是做用域
原本,當 foo() 執行完後,這個做用域及其內部的變量就被回收了,可是
bar() still has a reference to that scope, and that reference is called closure.