JavaScript闭包和this绑定

本文最主要讲讲JavaScript闭包和this绑定相关的我的小发现,鉴于这方面的基础知识已经有很多很好的文章讲过了,所以基本的就不讲了,推荐看看酷壳上的理解Javascript的闭包阮一峰学习Javascript闭包(Closure),写的都非常好。

首先来讲讲阮一峰的文章中的两道思考题。

代码片段一


var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());

这段代码最后输出的是

The Window

原因在同一片文章的评论中已经有人指出了

George Wing 说:

上面本人说得不太正确。
this的指向是由它所在函数调用的上下文决定的,而不是由它所在函数定义的上下文决定的。

对于最后返回的这个匿名函数

function(){
return this.name;
};

它是作为一个独立的函数返回的,它的调用域是在全局上,所以会输出全局变量name。

代码片段二


var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
var that = this;
return function(){
return that.name;
};
}
};
alert(object.getNameFunc()());

代码片段二最后输出的是

My Object

这里就要考虑var that =
this;
这句的作用了,由于getNameFuncobject内部的函数,所以它调用的上下文this保存的是object的信息,将其保存到that变量,这样作为内部函数的匿名函数就可以直接访问了。

可以注意到的是,阮一峰文章中的代码,都是将通过一个JSON对象来访问内部的函数,这样其实有些地方还不够清晰,毕竟不怎么严格地说,闭包就是函数内部的函数,所以我借用CoolShell上的文章中的例子来进一步说明。

代码片段三


function greeting(name) {
var text = ‘Hello ‘ + name; // local variable
// 每次调用时,产生闭包,并返回内部函数对象给调用者
return function() { alert(text); }
}
var sayHello=greeting("Closure");
sayHello() // 通过闭包访问到了局部变量text

这段代码输出

Hello Closure

看上去好像很好理解,接下来看代码片段四:

代码片段四


var text = ‘findingsea‘;
function greeting(name) {
var text = ‘Hello ‘ + name; // local variable
// 每次调用时,产生闭包,并返回内部函数对象给调用者
return function() { alert(this.text); }
}
var sayHello=greeting("Closure");
sayHello() // 通过闭包访问到了局部变量text

这段代码输出

findingsea

这是为什么呢?

针对代码片段三,CoolShell上的原文有解释:

文法环境中用于解析函数执行过程使用到的变量标识符。我们可以将文法环境想象成一个对象,该对象包含了两个重要组件,环境记录(Enviroment
Recode),和外部引用(指针)。环境记录包含包含了函数内部声明的局部变量和参数变量,外部引用指向了外部函数对象的上下文执行场景。全局的上下文场景中此引用值为NULL。这样的数据结构就构成了一个单向的链表,每个引用都指向外层的上下文场景。

针对代码片段四,就是我们之前讲过的,this保存是调用环境下的上下文内容,所以会输出全局的text

总结

本文想说明的是以下两点:

  1. 在函数闭包中,不使用this对变量进行访问时,函数会通过文法环境中的外部引用(指针),一级级地往上找(单向链表),直到找到(或者最终找不到)对应的变量。这个结构是在函数定义的时候就决定了的。

  2. 在函数闭包中,使用this对变量进行访问时,和绝大多数语言不同,JavaScript的this保存的是调用环境的上下文,也就是说this中的内容是在调用的时候决定的,所以访问到的是当前环境下的对应变量,并不会像前一种情况一样进行逐级查找。

时间: 2024-08-11 05:30:37

JavaScript闭包和this绑定的相关文章

前端(十三)—— JavaScript高级:回调函数、闭包、循环绑定、面向对象、定时器

回调函数.闭包.循环绑定.面向对象.定时器 一.函数高级 1.函数回调 // 回调函数 function callback(data) {} // 逻辑函数 function func(callback) { // 函数回调,判断回调函数是否存在 if (callback) callback(data); } func(callback); // 函数回调的本质:在一个函数中(调用函数),当满足一定条件,调用参数函数(回调函数) // 回调函数作为调用函数的参数传入,满足一定的条件,调用回调函数

深入理解javascript闭包

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function

JavaScript 闭包究竟是什么

JavaScript 闭包究竟是什么 1.简单的例子 首先从一个经典错误谈起,页面上有若干个div, 我们想给它们绑定一个onclick方法,于是有了下面的代码 <div id="divTest"> <span>0</span> <span>1</span> <span>2</span> <span>3</span> </div> <div id="d

全面理解Javascript闭包和闭包的几种写法及用途

一.什么是闭包和闭包的几种写法和用法                                                       1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点: 1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态. 2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区. 简单的说,Javascript允许使用内部函数---即函数定义和函数表

javascript闭包详解(内容为转载的,觉得不错就分享一下)

一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function f1(){ var n=999; } alert(n); // error 这里有一个地方需要注意,函数

转 全面理解Javascript闭包和闭包的几种写法及用途

转自:http://www.cnblogs.com/yunfeifei/p/4019504.html 好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一些实用的东西,主要将闭包的写法.用法和用途. 一.什么是闭包和闭包的几种写法和用法                                                       1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑

javascript闭包如何实现函数的重载?

本文和大家分享的主要是妙用javascript闭包实现函数重载相关内容,一起来看看吧,希望对大家学习javascript有所帮助. 1.准备知识 1.1 闭包 闭包是一个函数在创建时,允许该自身函数访问并操作该自身函数以外的变量时所创建的作用域.闭包可以让函数访问所有存在于该函数声明时的作用域内的变量和函数. <script>         var outerValue = "ninja";         var later;         function oute

javascript闭包浅析

何为闭包; 闭包跟作用域相关的,ECMAScript 允许使用内部函数,即函数定义和函数表达式位于另一个函数的函数体内.内部函数可以访问它们所在的外部函数中声明的所有局部变量.参数和声明的其他内部函数.当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包. 确实有点晕看个例子吧 <!doctype html><html lang="en"><head> <meta charset="UTF-8"> &

浅谈JavaScript闭包

一.背景知识 在介绍闭包之前,我觉得有必要先简单的介绍一些背景知识,如变量的作用域.嵌套函数.垃圾回收机制等概念. 1.作用域 作用域是程序运行时变量可被访问的范围,定义在函数内的的变量是局部变量,局部变量的作用域只能是函数内部范围内,它不能在函数外引用.定义在模块最外层的的变量是全局变量,它是全局范围内可见的,当然在函数里面也可以读取到全局变量的. var a = 123; //全局变量 function fun(){ var b = 456; //局部变量 } 2.嵌套函数 函数不仅可以定义