在最新的 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.