php函数嵌套 作用域,javascript 嵌套的函数(作用域链)_javascript技巧

嵌套的函数(作用域链)

当你进行函数的嵌套时,要注意实际上作用域链是发生变化的,这点可能看起来不太直观。你可把下面的代码置入firebug监视值的变化。

var testvar = 'window属性';

var o1 = {testvar:'1', fun:function(){alert('o1: '+this.testvar+'

o1.fun();'1'

o2.fun();'2'

o1.fun.call(o2);'2'

这是本文的首个例子。

var testvar = 'window属性';

var o3 = {

testvar:'3',

testvar2:'3**',

fun:function(){

alert('o3: '+this.testvar);//'obj3'

var inner = function(){

alert('o3-inner: '+this.testvar);//'window属性'

alert('o3-inner: '+this.testvar2);//undefined(未定义)

};

inner();

}

};

o3.fun();

这里我们换了别的函数,这个函数与原先的函数几乎相似但区别是内部函数的写法。要注意的是内部函数运行时所在的作用域,和外部函数的作用域是不一样的。Ext可让你调用函数时指定函数的作用域,避免作用域的问题。

变量的声明

初始化变量时一定要加上“var”关键字,没有的话这就是一个全局变量。譬如,在下面的例子中,会有一个变量写在函数内部,然而你打算仅仅是声明局部的变量,但实际也可能出现覆盖全局变量的值的情形。在FIREBUG "DOM"的标签页中,你可通过检测“window”看到所有的全局变量。如果你发现有“k”或“x”变量那证明你把这个变量分配在一个不合适的作用域里面。见下例:

var i = 4;

var j = 5;

var k = 7;

var fn = function(){

var i = 6;

k = 8;//注意前面没有var 所以这句话的意思的把8赋予到变量k中去!

alert(i);//6

alert(j);//5

alert(k+'-1');//8-1

x = 1;//这句的作用有两种情况,创建全部变量x或覆盖(overwrite)全部变量x

};

fn();

alert(k+'-2');//8-2 (注意不是7-2)

与前面例子变化不大,另外注意的是函数内的k前面是没有var关键字的,所以这里不是声明局部变量,而是将某个值再次分配到k这个全局变量中。另外要注意的是,alert方法执行期间,参数i是当前能找到的局部变量,它的值是6,但参数j在当前作用域找不到,就沿着作用域链(scope chain)向上查找,一直找到全局变量的那个j为止。

在Ext中指定作用域

前面已提及,当调用函数时Ext能灵活处理作用域的问题。部分内容来自dj的帖子。

调用函数时,你可以把this想象为每个函数内的一个特殊(躲起来的)参数。无论什么时候,JavaScript都会把this放到function内部。它是基于一种非常简单的思想:如果函数直接是某个对象的成员,那么this的值就是这个对象。如果函数不是某个对象的成员那么this的值便设为某种全局对象(常见有,浏览器中的window对象)。下面的内部函数可以清晰的看出这种思想。

一个函数,若是分配到某个变量的,即不属于任何对象下的一员,那么this的参数就变为windows对象。下面是一个例子,可直接粘贴到Firebug的console:

var obj = {

toString:function(){ return 'obj的范围内(作用域内)';}, //重写toString函数,方便执行console.log(this)时的输出

func: function(){

// 这里的函数直接从属与对象"object"

console.log(this);

var innerFunc = function(){

//n这里的函数不是特定对象的直接成员,只是另外一个函数的变量而已

console.log(this);

};

innerFunc();

}

};

obj.func();

// 输出 "obj的范围内(作用域内)"

// 输出 "Window的一些相关内容..."

缺省下是这样调用一个参数的-但你也可以人为地改变this参数,只是语法上稍微不同。将最后一行的"obj.func();" 改为:

obj.func.call(window);

// 输出 "Window的一些相关内容..."

// 输出 "Window的一些相关内容..."

从上面的例子中可以发现,call实际上是另外一个函数(方法)。call 属于系统为obj.func内建的方法(根据JavaScript之特点可得知,函数是一种对象。)。

通过这样改变this指向的作用域,我们可以继续用一个例子来修正innerFunc中的this参数,——“不正确”的指向:

var obj = {

toString:function(){ return 'obj的范围内(作用域内)';}, //重写toString函数,方便执行console.log(this)时的输出

func: function(){

// 这里的函数直接从属与对象"object"

console.log(this);

var innerFunc = function(){

//n这里的函数不是特定对象的直接成员,只是另外一个函数的变量而已

console.log(this);

};

innerFunc.call(this);

}

};

obj.func();

// 输出 "obj的范围内(作用域内)"

// 输出 "obj的范围内(作用域内)"

Ext的作用域配置

可以看到,没有分配作用域的函数,它的this"指向的是浏览器的window对象(如事件句柄event handler等等),——除非我们改变this的指针。Ext的很多类中 scope是一个配置项(configuration)能够进行指针的绑定。相关的例子参考Ajax.request。

Ext的createDelegate函数

*除了内建的call/apply方法,Ext还为我们提供-- 辅助方法createDelegate。 该函数的基本功能是绑定this指针但不立刻执行。传入一个参数,createDelegate方法会保证函数是运行在这个参数的作用域中。如:

var obj = {

toString:function(){ return 'obj的范围内(作用域内)';}, //重写toString函数,方便执行console.log(this)时的输出

func: function(){

// 这里的函数直接从属与对象"object"

console.log(this);

var innerFunc = function(){

//n这里的函数不是特定对象的直接成员,只是另外一个函数的变量而已

console.log(this);

};

innerFunc = innerFunc.createDelegate(this); // 这里我们用委托的函数覆盖了原函数。

innerFunc(); // 按照一般的写法调用函数

}

};

obj.func();

// 输出 "obj的范围内(作用域内)"

// 输出 "obj的范围内(作用域内)"

这是一个小小的例子,其原理是非常基本基础的,希望能够好好消化。尽管如此,在现实工作中,我们还是容易感到迷惑,但基本上,如果能按照上面的理论知识去分析来龙去脉,万变还是不离其中的。

另外还有一样东西,看看下面的例子:

varsDs.load({callback: function(records){

col_length = varsDs.getCount();//这里的varDs离开了作用域?

//col_length = this.getCount();//这个this等于store吗?

for (var x = 0; x < col_length; x++)

{

colarray[x] = varsDs.getAt(x).get('hex');

}

}});不过可以写得更清晰:

var obj = {

callback: function(records){

col_length = varsDs.getCount();//这里的varDs离开了作用域?

//col_length = this.getCount();//这个this等于store吗?

// ...

}

};

varsDs.load(obj);现在函数callback直接挂在obj上,因此this指针等于obj。

但是注意: 这样做没用的。为什么?因为你不知obj.callback最终执行时发生什么情形。试想一下Ext.data.Store的load方法(仿造的实现):

...

load : function(config) {

var o = {};

o.callback = config.callback;

//进行加载

o.callback();

}

...

这个仿造的实现中,回调函数的作用域是私有变量“o”。 因为通常你无法得知函数是如何被调用的,如果不声明作用域,你很可能无法在回调函数中使用this参数。

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395548.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C#-枚举】枚举的使用

枚举是用户定义的整数类型。 namespace ConsoleApplication1 {/// <summary>/// 在枚举中使用一个整数值&#xff0c;来表示一天的阶段/// 如&#xff1a;TimeOfDay.Morning返回数字0/// </summary>class EnumExample{public enum TimeOfDay{Morning 0,Afternoon …

Elixir 初尝试 5 -- 遇见Actor

Actor模型的定义 wiki如是说 The actor model in computer science is a mathematical model of concurrent computation that treats "actors" as the universal primitives of concurrent computation. In response to a message that it receives, an actor can: …

创建外部快照_快照事件:现在如何仅通过拍照即可创建日历事件

创建外部快照by Arjun Krishna Babu通过Arjun Krishna Babu 快照事件&#xff1a;现在如何仅通过拍照即可创建日历事件 (Snap Event: How you can now create calendar events just by taking a picture) Google just published my first Android app, Snap Event, in their P…

一个备份sql server文件.bak还原成两个数据库

一直对这个概念很模糊&#xff0c;今天具体一点。 备份文件只要是正常的.bak文件就好。 数据库>还原数据库 直接填写还原之后的文件名就行。 用一份备份文件还原两个一样的库&#xff0c;只是名称不一样。 转载于:https://www.cnblogs.com/Ly426/p/10209825.html

linux服务器防病毒,Linux系统中你不需要防病毒?_服务器评论-中关村在线

误区4&#xff1a;Linux是无病毒。Linux的安全性这么好&#xff0c;这是否意味着Linux是无病毒吗&#xff1f;现实&#xff1a;Linux是非常安全&#xff0c;并不是没有针对Linux方面的病毒。有许多针对Linux的已知病毒。但是几乎所有的已知病毒对于Linux在本质上都是非破坏性的…

外置接口请求

1. 请求接口 /*** 请求接口** param url* param paramsStr* param type Connection.Method.POST* param heads* return*/ public JSONObject sendUpload(String url, String paramsStr, Connection.Method type, Map<String, String> heads) {//发送上传订单请求Str…

python面向对象-1方法、构造函数

类是指&#xff1a;描述一种事物的定义&#xff0c;是个抽象的概念 实例指&#xff1a;该种事物的一个具体的个体&#xff0c;是具体的东西 打个比方&#xff1a; “人”是一个类。“张三”是人类的一个具体例子 在编程时也是同样的道理&#xff0c;你先自己定义一个“类”&am…

bzoj3503: [Cqoi2014]和谐矩阵

高斯消元解异或方程组。学了bitset。对比如下 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define REP(i,s,t) for(int is;i<t;i) #define dwn(i,s,t) for(int is;i>t;i--) #define clr(…

她偏爱雏菊一样的淡黄色_为什么开源项目(非常)偏爱新用户,以及您可以采取什么措施...

她偏爱雏菊一样的淡黄色by Filip Hracek由Filip Hracek 为什么开源项目(非常)偏爱新用户&#xff0c;以及您可以采取什么措施 (Why open source projects (sadly) favor new users, and what you can do about it) Every now and then, all developer products (SDKs, framewo…

linux 脚本 expected,Linux | shell与expect结合使用

在linux操作系统下&#xff0c;使用脚本自动化&#xff0c;一般由两种方案。方案一&#xff1a;telnetftp方案二&#xff1a;sshscpexpect。以下主要使用sshscpexpect为例进行说明使用方式。第一步&#xff1a;安装expect&#xff1a;yum -y install expect第二步&#xff1a;验…

[Swift]LeetCode246.对称数 $ Strobogrammatic Number

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号&#xff1a;山青咏芝&#xff08;shanqingyongzhi&#xff09;➤博客园地址&#xff1a;山青咏芝&#xff08;https://www.cnblogs.com/strengthen/&#xff09;➤GitHub地址&a…

C++中父类的虚函数必需要实现吗?

一、情景 C中父类的虚函数必需要实现吗&#xff1f; class Vir{ public:virtual void tryVirtual(); };class CVir:public Vir{ public:void tryVirtual(){std::cout<<"CVir"<<std::endl;} };二、说明 &#xff08;1&#xff09;在main函数中&#xff0c…

解决新浪微博API调用限制 突破rate_limit_status瓶颈

新浪微博开放平台API的调用和TWITTER接口一样&#xff0c;都是受限的&#xff0c;以小时为单位进行限定。 他有两个限制原则 1.用户不登录基于IP的限制&#xff0c;每小时1000次 2.用户登录了基于用户的限制&#xff0c;每小时1000次 如果应用是用户不登录的那么就是对IP进行限…

chrome前端开发工具_精通Chrome开发人员工具:更高级别的前端开发技术

chrome前端开发工具by Ben Edelstein通过本爱德斯坦 You may already be familiar with the basic features of the Chrome Developer Tools: the DOM inspector, styles panel, and JavaScript console. But there are a number of lesser-known features that can dramatica…

linux给文件夹图标,linux – 如何在GNOME中以编程方式设置自定义文件夹图标?

我终于想出了如何做到这一点&#xff01;这是一个在标准Gnome环境中工作的Python脚本&#xff1a;#!/usr/bin/env pythonimport sysfrom gi.repository import Gioif len(sys.argv) not in (2, 3):print Usage: {} FOLDER [ICON].format(sys.argv[0])print Leave out ICON to u…

jQuery序列化表单为JSON对象

[html] view plaincopy <form id"myform"> <table> <tr> <td>姓名:</td> <td> <input type"text" name"name" /> </td> </tr> …

sys模块

与python解释器交互的模块 sys.argv 命令行参数List&#xff0c;第一个元素是程序本身路径 sys.exit(n) 退出程序&#xff0c;正常退出时exit(0),错误退出sys.exit(1) sys.version 获取Python解释程序的版本信息 sys.path 返回模块的搜索路径…

李开复:年轻人该比谁更拼命吗?

李开复:年轻人该比谁更拼命吗&#xff1f; IT职场 cricode 4个月前 (04-02) 951℃ 0评论 我年轻的时候是最不注重睡眠的&#xff0c;我记得在我读大学的时候每次要考试就因为平时玩耍太多了&#xff0c;每次要考试的时候就会灌咖啡&#xff0c;有时候一个晚上可以喝十杯咖啡不…

linux命令无视错误,llinux 的一些命令和错误

sudo tar -zxvf ./hadoop-2.6.0.tar.gz -C /usr/local # 解压到/usr/local中source ~/.bashrc # 使变量设置生效sudo useradd -m hadoop -s /bin/bash 创建新用户sudo adduser hadoop sudo 可为 hadoop 用户增加管理员权限sudo mv ./hadoop-2.6.0/ ./hadoop # 将文件…

假设检验方差未知_设计云数据库时如何处理未知数并做出假设

假设检验方差未知by Rick Mak麦瑞克(Rick Mak) 设计云数据库时如何处理未知数并做出假设 (How to handle unknowns and make assumptions when designing a cloud database) 场景&#xff1a;鞋盒还是社交应用&#xff1f; (Scenario: Shoebox or social app?) Say you’re a…