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.pswp.cn/news/395548.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395548.shtml
英文地址,請注明出處:http://en.pswp.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…