`
jaesonchen
  • 浏览: 315388 次
  • 来自: ...
社区版块
存档分类
最新评论

javascript scope作用域

 
阅读更多
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>scope.html</title>
	
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">
    <meta name="keywords" content="keyword1,keyword2,keyword3">
    <meta name="description" content="this is my page">
    <meta name="content-type" content="text/html; charset=UTF-8">
    
    <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
	<script type="text/javascript" src="../js/jquery-1.11.3.js"></script>

  </head>
  
  <body>
	<div id="div"></div>
	<script type="text/javascript">
		// <![CDATA[
		//如果你需要在没有硬编码的window标识符下访问全局对象,你可以在任何层级的函数作用域中做如下操作:
		var global = (function () {
			return this;
		})();
		
		function show(str) {
			$("#div").append($("<p></p>").text("" + str));
		}
		
		
		//执行环境和作用域:
		//执行环境(execution context)是javascript中最为重要的一个概念。执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为。
		//每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中。
		//虽然我们编写的代码无法访问这个对象,但是解析器在处理数据时会在后台使用它。 
		
		//全局执行环境是最外围的一个执行环境。根据ECMAScript实现所在的宿主环境不同,表示执行环境的对象也不一样。
		//在Web浏览器中,全局执行环境被认为是window对象,因为所有全局变量和函数都是作为window对象的属性和方法创建的。
		//某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之销毁
		//(全局执行环境直到应用程序退出-例如关闭网页或浏览器时才会被销毁)。 
		
		//局部执行环境,每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。
		//而在函数执行完后,栈将方法的执行环境弹出,把控制权返回给之前的执行环境。ECMASript实现,程序中的执行流正是由这个方便的机制控制着。 
		
		//ECMAScript 只有公用作用域
		//ECMAScript 中的所有对象的所有属性和方法都是公用的。
		//当代码在一个环境中执行时,会创建变量对象(VO)的一个作用域链(scope chain)。
		//作用域链的用途,是保障对执行环境有权访问的所有变量和函数的有序访问。
		//作用域链的前端始终都是在当前执行的代码所在执行环境的变量对象。
		//如果这个执行环境是函数,则将其活动对象(activation object)作为变量对象VO。
		//活动对象在最开始时只包含一个对象,即arguments对象(这个对象在全局环境中是不存在的)。
		//作用域链中的下一个变量对象来自当前执行环境,而再下一个变量对象则来自下一个包含环境,这样,一直延续到全局执行环境。
		//全局执行环境的变量对象始终都是作用域链中的最后一个对象。 
		//标示符解析是沿着作用域链一级一级地搜索标示符的过程。搜索过程始终从作用域链的前端开始,然后逐级地向后回溯,直至找到标示符为止。 
		//作用域链的本质是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。 
		
		//改变函数作用域:
		//每个函数都包含两个非继承而来的方法:apply()和call()。这两个方法的用途就是在特定的作用域中调用函数,实际上等于设置函数体内的this对象的值。 
		//call() 方法可将一个函数的对象上下文this从初始的上下文改变为指定的新对象。如果没有提供新对象参数,那么 Global 对象被用作 this。 
		//apply()和call()在作用上是相同的,但两者在参数上有区别的。
		//apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入。
		
		//functionName.caller属性:返回一个对函数的引用,即调用了当前函数的函数体。 
		//对于函数来说,caller 属性只有在函数执行时才有定义。 如果函数是由 JScript 程序的顶层调用的,那么 caller 为 null 。
		function callLevel() {
			if (callLevel.caller == funCaller)
				show("callLevel was called by another function:\n" + callLevel.caller);
			else 
				show("callLevel was called from the top level:" + "\n" + callLevel.caller);
		}
		function funCaller() {
			callLevel();
		}
		
		callLevel();	//callLevel was called from the top level. null
		funCaller();	//callLevel was called by another function: function funCaller() { callLevel(); }
		
		//arguments.callee属性是 arguments 对象的一个成员,它表示对函数对象本身的引用,这有利于匿名函数的递归或者保证函数的封装性
		//递归计算 
		var sum = function(n) {
			if (n <= 0)
				return 0;
			else
				return n + arguments.callee(n - 1);
		};
		show(sum(100));		//5500
		
		//函数绑定bind:一个日益流行,在很多插件(jquery)中都能见到的一个技巧。函数绑定要创建一个函数,
		//可以在特定的this环境中以指定参数调用另一个函数。它常常和回调函数与事件处理程序一起使用,以便在将函数作为变量传递的同时保留代码执行环境。 
		//ECMAScript5为所有函数定义了一个原生的bind()方法,进一步简单了操作。 
		//在javascript中,函数总是在一个特殊的上下文执行(称为执行上下文),如果你将一个对象的函数赋值给另外一个变量的话,
		//这个函数的执行上下文就变为这个变量的上下文了(this)。
		//如果你希望将一个对象的函数赋值给另外一个变量后,这个函数的执行上下文仍然为这个对象,那么就需要用到bind方法。 
		var name = "the global object";
		function scopeTest() {
			return this.name;
		}
		show(scopeTest());	//the global object
		
		var foo = {
			name: "the foo object!",
			otherScopeTest: function() { return this.name; }
		};
		
		function runFx(f) {
			return f();
		}
		
		show(foo.otherScopeTest());			//the foo object!
		var foo_otherScopeTest = foo.otherScopeTest;
		//执行上下文从foo编程global,即this指向global
		show(foo_otherScopeTest());			//the global object
		show(runFx(foo.otherScopeTest));	//the global object
		
		//使用bind,将function的this绑定为指定参数
		var fx = foo.otherScopeTest.bind(foo);
		show(runFx(fx));	//the foo object!
		
		//没有块级作用域:
		//JavaScript没有块级作用域。
		//If for语句中的变量声明会自动将变量添加到当前的执行环境,for循环执行结束后,也依旧会存在于循环外部的执行环境中。 
		//使用var声明的变量会自动被添加到最接近的执行环境中。如果初始化变量时没有使用var声明,该变量会自动被添加到全局环境中。 
		function varDeclare() {
			var localVar = "local var";
			globalVar = "global var";
		}
		varDeclare();
		try {
			show(localVar);
		} catch(err) {
			show(err);	//ReferenceError: localVar is not defined
		}
		show(global.globalVar);		//global var
		
		//函数声明与函数表达式:
		//函数声明与函数表达式区别在于:解析器向执行环境中加载数据时对它们并非一视同仁。
		//解析器会率先读取函数声明,并使其在执行任何代码之前可以访问,这个重要特征就是函数声明提升。
		//至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解释执行。 
		//函数声明:
		function funcName() { }
		//函数表达式:
		(function () {
			//通过匿名函数可以模拟块级作用域
			var localVar = "local var";
		})();
		//localVar 未定义
		//alert(localVar);
		
		var str = "global";
		function scopeTestVar() {
			//scopeTestVar()调用时的执行环境是global,this指向global
			show(this.str);		//global var
			
			//这里str是局部变量,变量和函数声明提升,在其他代码执行之前解析
			str="aaa";
			show(str);			//aaa
			var str = "local";
			show(str);			//local
		}
		scopeTestVar();
		show(str);				//global var
		
		
		//caller取决于调用语句所在的层次,同一调用语句中的多个函数调用,caller相同
		function multiCall() {
			function currying(){
				return function(){
					var callfrom = arguments.callee.caller;
					return function() {
						show(arguments.callee.caller === callfrom);	//true
						show(callfrom);		//function multiCall() { function currying(){ ... } currying()()(); }
					};
				};
			}
			currying()()();
		}
		multiCall();
	// ]]>
	</script>
  </body>
</html>

 

分享到:
评论

相关推荐

    深入理解JavaScript作用域和作用域链

    JavaScript作用域是编程中至关重要的概念,它规定了变量和函数的可见性及生命周期。JavaScript主要有两种作用域:全局作用域和局部作用域。 全局作用域是指在代码的任何位置都可以访问的变量或函数,这通常包括在最...

    Scope(作用域).md

    ### Scope(作用域) #### 一、什么是作用域 作用域是编程语言中用来定义变量可见性和可访问性的概念。简单来说,作用域决定了变量在何处可以被引用和使用。在JavaScript中,作用域主要分为两种类型:全局作用域和...

    javascript执行环境,作用域理解

    JavaScript 执行环境和作用域的深层次理解 在 JavaScript 中,执行环境和作用域是两个非常重要和基本的概念,理解了这两个概念对于 JavaScript 中很多脚本的运行结果就能明白其中的道理了。执行环境是一个概念,一...

    javascript作用域链(Scope Chain)初探.docx

    ### JavaScript作用域链(Scope Chain)初探 #### 一、引言 JavaScript的作用域链是一个重要的概念,尤其是在深入理解JavaScript执行机制时不可或缺的一部分。本文将通过对几个具体例子的分析来探讨JavaScript作用域...

    Angular.Js之Scope作用域的学习教程

    总的来说,AngularJS的Scope作用域是实现数据绑定和组件通信的关键。理解Scope的层次结构、继承机制以及如何在模板中使用,是掌握AngularJS开发的基础。通过不断实践和深入学习,开发者可以更好地利用Scope来构建...

    关于JavaScript作用域你想知道的一切

    Javacript 中有一系列作用域的概念。对于新的JS的开发人员无法理解... 什么是作用域(scope)? 什么是全局(Global)和局部(Local)作用域? 什么是命名空间和作用域的区别? 什么是this关键字且作用域对其的影响? 什

    深入浅析JavaScript中的作用域和上下文

    **作用域(Scope)** 1. **全局作用域**:在函数外部定义的变量具有全局作用域,可以在整个脚本中访问。全局变量在脚本执行的整个生命周期内都存在。 2. **局部作用域**:在函数内部定义的变量具有局部作用域,仅...

    深入理解变量作用域

    本文将从JavaScript权威指南出发,深入探讨变量作用域的相关知识点,包括全局作用域、局部作用域、以及闭包等高级概念。 #### 二、全局作用域与局部作用域 1. **全局作用域** - 定义:在JavaScript中,如果一个...

    javascript作用域链(Scope Chain)用法实例解析

    JavaScript 作用域链是 JavaScript 语言中一个至关重要的概念,它决定了变量和函数的访问权限。在 JavaScript 中,每个函数都有自己的作用域,也就是变量和函数的可见范围。当一个函数被创建时,它会形成一个作用域...

    AngularJS 0005:作用域

    - `$apply`: 当在AngularJS外部(比如JavaScript事件处理函数)修改了作用域中的数据时,需要调用`$apply`来触发`$digest`循环。例如,`$scope.$apply(function() { $scope.myVariable = newValue; })`。 **作用域...

    详解JavaScript的AngularJS框架中的作用域与数据绑定

    这些作用域形成了一个作用域链(Scope Chain),子作用域可以访问父作用域的属性,但反之则不行。除了使用这些内置指令创建作用域之外,AngularJS还提供了API来手动创建新的作用域实例。 数据绑定是AngularJS的一个...

    JavaScript作用域与作用域链深入解析

    作用域是JavaScript最重要的概念之一,想要学好JavaScript就需要理解JavaScript作用域和作用域链的工作原理。今天这篇文章对JavaScript作用域和作用域链作简单的介绍,希望能帮助大家更好的学习JavaScript。 ...

    scope-chains-closures, Javascript作用域链和闭包 workshop.zip

    scope-chains-closures, Javascript作用域链和闭包 workshop 范围链和闭包 workshop正在启动$ npm install -g scope-chains-closures$ scope-chains-closures # or, shorter: sccjs使用箭头

    javascript函数作用域学习示例(js作用域)

    在学习JavaScript作用域之前,我们需要先了解在其他编程语言中常见的块级作用域(block scope)。在像C语言这样的编程语言中,每个用花括号{}包裹的代码块都有自己的作用域,这意味着在代码块内部声明的变量只能在该...

    What-is-Scope.pdf.zip_javascript

    本资源围绕的主题是“作用域(Scope)”,这是理解JavaScript中的变量、函数以及代码组织方式的关键概念。"What-is-Scope.pdf.zip"是一个压缩包文件,其中包含了一份详细讲解JavaScript作用域的PDF文档——"What is ...

    JavaScript 作用域scope简单汇总

    在JavaScript中,作用域主要分为三种类型:全局作用域、函数作用域和块级作用域。 1. 全局作用域:在函数外部定义的变量拥有全局作用域,可以在整个脚本的任何地方被访问。如果在函数外部没有声明变量,那么默认它...

    跟我学习javascript的作用域与作用域链

    首先,JavaScript中的作用域主要有两种类型:全局作用域(Global Scope)和局部作用域(Local Scope)。 1. 全局作用域: - 在代码的最外层定义的变量或函数拥有全局作用域,可以在整个脚本的任何位置被访问。 - ...

    javascript中的作用域scope介绍

    在讨论JavaScript的作用域之前,我们需要了解什么是作用域。作用域是程序语言中一个变量或函数可见性的范围。这意味着在特定代码块中声明的变量和函数只能在该代码块的内部访问。在不同的编程语言中,作用域的范围...

    为什么JavaScript没有块级作用域

    JavaScript 是一种广泛使用的编程语言,它在早期版本中没有实现块级作用域(block scope),这是它与其他许多编程语言的一个显著区别。在 JavaScript 中,变量的作用域是由函数定义的,即使在块级结构比如循环或条件...

Global site tag (gtag.js) - Google Analytics