做用域和調用函數,訪問變量的能力有關,上下文和this關鍵字有關是調用當前可執行代碼的引用。javascript
分爲局部做用域,全局做用域,處於局部做用域裏面能夠訪問到全局做用域變量,在局部做用域外面,訪問不到局部做用域裏面的變量。html
例一:java
var globalVariable = 'This is global variable'; //全局變量 function globalFunction(){ //全局函數,裏面就是局部做用域 var localVariable = "This is local variable"; console.log('visit global/local variable'); console.log(globalVariable); console.log(localVariable); } globalFunction();
例二:node
var globalVariable = 'This is global variable'; //全局變量 function globalFunction(){ //全局函數,裏面就是局部做用域 var localVariable = "This is local variable"; console.log('visit global/local variable'); console.log(globalVariable); console.log(localVariable); //修改全局變量 globalVariable = 'This is changed variable'; console.log(globalVariable); //局部函數,只能在globalFunction()內部調用 function localFunction(){ //在這個做用域裏能訪問到全局做用域 和 globalFunction() var innerLocalVariable = 'This is inner ocal variable'; console.log('visit global/local/innerLocak variable'); console.log(globalVariable); console.log(localVariable); console.log(innerLocalVariable); } localFunction();//調用內部函數 } globalFunction();
上下文常表明this變量的值,以及他的指向,他決定一個函數怎麼被調用,當一個函數,能夠做爲一個對象的方法被調用時,This指向調用這個方法的對象。數組
例一:瀏覽器
//上下文環境 var pet ={ words: "...", speak: function(){ console.log(this.words); console.log(this === pet);//返回true } } pet.speak();//pet調用speak 這時speak裏面的this指向pet
另外一種狀況app
//另外一種狀況 function pet(words){ this.words = words; console.log(this.words); console.log(this); } pet('...')
這個this指向執行環境最頂層變量,global, 此時調用函數的對象時global 函數
console.log( this ===global) truethis
狀況3:spa
function Pet(words){ this.words = words; this.speak = function(){ console.log(this.words); console.log(this); //cat } } var cat = new Pet('Miao'); cat.speak()
一般把擁有者稱爲執行上下文,this是javaScript語言的一個關鍵字,表明函數運行時的自動生成的一個函數對象,只能在函數內部使用,this指向函數擁有者,在全局運行的上下文中this指向全局對象。在函數內部this取決於函被調用的方式:
call, apply都屬於Function.prototype的一個方法,它是JavaScript引擎內在實現的,由於屬於Function.prototype,因此每一個Function對象實例,也就是每一個方法都有call, apply屬性
相同點:兩個方法產生的做用是徹底同樣的,以某個方法當作被指定對象的方法來執行。
不一樣點:方法傳遞的參數不一樣
foo.call(thisObj, arg1,arg2,arg3) == foo.apply(thisObj, arguments)==this.foo(arg1, arg2, arg3)
foo是一個方法,thisObj是方法執行時上下文相關對象,arg1, arg2, arg3是傳給foo方法的參數.這裏所謂的方法執行時上下文相關對象,就是在類實例化後對象中的this.
在JavaScript中,代碼老是有一個上下文對象,代碼處理該對象以內. 上下文對象是經過this變量來體現的, 這個this變量永遠指向當前代碼所處的對象中.
能夠用來代替另外一個對象調用一個方法。call 方法可將一個函數的對象上下文從初始的上下文改變爲由 thisObj 指定的新對象。若是沒有提供 thisObj 參數,那麼 Global 對象被用做 thisObj。
nodeJS事例1:
var pet = { words :"....", speak: function(say){ console.log(say + ' ' + this.words); } } //pet.speak('Speak'); //this指向pet var dog = { words ='wang' } pet.speak.call(dog,'Speak');
調用的方法是 pet.speak, 理論上this指針指向 pet,但經過call(),改變了執行上下文,將this指向了dog, 'speak'爲傳入的參數,指定dog對象爲上下文
nodeJS事例2 --繼承:
//繼承 function Pet(words){ this.words = words; this.speak = function(){ console.log(this.words); } } function Dog(words){ Pet.call(this,words); //構造函數,此時this指向新創關鍵的實例對象 // 將Pet裏面的this指向當前Dog //Pet.apply(this , arguments);//傳入數組 console.log(this); //Dog { words: 'Wang', speak: [Function] } } var dog = new Dog('Wang'); dog.speak();
例1:
function add(a,b) { alert(a+b); } function sub(a,b) { alert(a-b); } add.call(sub,3,1);
這個例子中的意思就是用 add 來替換 sub,add.call(sub,3,1) == add(3,1) ,因此運行結果爲:alert(4);
例2:
function Class1() { this.name = "class1"; this.showNam = function() { alert(this.name); } } function Class2() { this.name = "class2"; } var c1 = new Class1(); var c2 = new Class2(); c1.showNam.call(c2);
注意,call 的意思是把 c1 的方法放到c2上執行,原來c2是沒有showNam() 方法,如今是把c1 的showNam()方法放到 c2 上來執行,因此this.name 應該是 class2,執行的結果就是:alert("class2");
參考文獻:http://www.cnblogs.com/fighting_cp/archive/2010/09/20/1831844.html