日期:2014-05-16  浏览次数:20380 次

深入理解javascript的一些特性(静态作用域,this指针,闭包)

差不多都是这两天看书的一些总结,在这里记下来,算是个梳理。不是详细的讲解,主要记录要点。

关于javascript的静态作用域:

1. javascript的作用域完全由函数来决定,化括号不是独立的作用域。

2. javascript语言的特殊之处在于函数内部可以读取函数外部的变量。而函数外部无法读取函数内部变量。

子对象会一级一级向上寻找所有父对象变量。父对象的所有变量对子对象可见,反之不成立。

3. 静态作用域的含义是函数作用域的嵌套关系由定义时决定而不是调用时决定。又成为词法作用域,其作用域嵌套关系

在语法分析时决定,而不是运行时决定。如:

var scope = 'out'
var f1 = function(){
  console.log(scope);
};
f1();//out
var f2 = funtion(){
  var scope = 'in';
  f1();
}
f2();//out
说明函数f1在查找变量定义时,在词法分析时就已经完成,而不需要等到f1被调用的时候才开始。

4. 不通过var声明直接赋值的变量是全局变量。


关于上下文对象(this指针):

1. 上下文对象是指被调用函数所处的环境。其作用是在一个函数内部引用调用它的对象本身。

与静态作用域相对,this所指向的对象是函数调用时刻调用该函数的对象。this指针是静态作用域的

一个补充。

var obj = {
	name: 'JS',
	show: function(){
		console.log(this.name);
	}
};
obj.show();//输出 JS

var foo = {
	name: 'foo',
	show: obj.show
};
foo.show();//输出 foo
当由foo对象调用函数show的时候,this指针指向的是foo对象。

把代码中的this.name直接改成this,输出可以看到结果分别为:

{ name: 'JS', show: [Function] }
{ name: 'foo', show: [Function] }
这样就一目了然了。

为了更深刻地理解这个问题我们运行如下代码:

name = 'foo'
function f(){
	console.log(this);
};
f();
将会得到如下结果:

{ ArrayBuffer: [Function: ArrayBuffer],
  Int8Array: { [Function: Int8Array] BYTES_PER_ELEMENT: 1 },
  Uint8Array: { [Function: Uint8Array] BYTES_PER_ELEMENT: 1 },
  Uint8ClampedArray: { [Function: Uint8ClampedArray] BYTES_PER_ELEMENT: 1 },
  Int16Array: { [Function: Int16Array] BYTES_PER_ELEMENT: 2 },
  Uint16Array: { [Function: Uint16Array] BYTES_PER_ELEMENT: 2 },
  Int32Array: { [Function: Int32Array] BYTES_PER_ELEMENT: 4 },
  Uint32Array: { [Function: Uint32Array] BYTES_PER_ELEMENT: 4 },
  Float32Array: { [Function: Float32Array] BYTES_PER_ELEMENT: 4 },
  Float64Array: { [Function: Float64Array] BYTES_PER_ELEMENT: 8 },
  DataView: [Function: DataView],
  DTRACE_NET_SERVER_CONNECTION: [Function],
  DTRACE_NET_STREAM_END: [Function],
  DTRACE_NET_SOCKET_READ: [Function],
  DTRACE_NET_SOCKET_WRITE: [Function],
  DTRACE_HTTP_SERVER_REQUEST: [Function],
  DTRACE_HTTP_SERVER_RESPONSE: [Function],
  DTRACE_HTTP_CLIENT_REQUEST: [Function],
  DTRACE_HTTP_CLIENT_RESPONSE: [Function],
  global: [Circular],
  process: 
   { title: 'node',
     version: 'v0.10.10',
     moduleLoadList: 
      [ 'Binding evals',
        'Binding natives',
        'NativeModule events',
        'NativeModule buffer',
        'Binding buffer',
        'NativeModule assert',
        'NativeModule util',
        'NativeModule path',
        'NativeModule module',
        'NativeModule fs',
        'Binding fs',
        'Binding constants',
        'NativeModule stream',
        'NativeModule _stream_readable',
        'NativeModule _stream_writable',
        'NativeModule _stream_duplex',
        'NativeModule _stream_transform',
        'NativeModule _stream_passthrough',
        'NativeModule console',
        'Binding tty_wrap',
        'NativeModule tty',
        'NativeModule net',
        'NativeModule timers',
        'Binding timer_wrap',
        'NativeModule _linklist',
        'Binding cares_wrap',
        'Binding signal_wrap' ],
     versions: 
      { http_parser: '1.0',
        node: '0.10.10',
        v8: '3.14.5.9',
        ares: '1.9.0-DEV',
        uv: '0.10.10',
        zlib: '1.2.3',
        modules: '11',
        openssl: '1.0.1e' },