JavaScript學習總結(三、函數聲明和表達式、this、閉包和引用、arguments對象、函數間傳遞參數)
一、函數聲明和表達式
函數聲明: function test() {};
test(); //運行正常
function test() {};
函數表達式: var test = function() {};
test; //undefined
test(); //TypeError
var test = function() {};
命名函數的賦值表達式:
var test = function bar() {
test(); //正常運行
};
test(); //ReferenceError
二、this
1. 全局範圍內、函數調用、方法調用、調用構造函數、顯示的設置this;
註:在嚴格模式下,沒有全局變量,即this = undefined,在對象的字面量聲明語法中,this不能用來指向對象本身;
顯示的設置this:
function test(a, b, c) {};
var bar = {};
foo.apply(bar, [1, 2, 3]); //數組將被擴展;
foo.call(bar, 1, 2, 3); //傳遞到test的參數為: a = 1, b = 2,c = 3;
當使用Function.prototype上的call或apply方法時,函數內的this將被顯示設置為函數調用的第一個參數;
2. 常見誤解
1. Foo.method = function() {
function test() {
//this 為全局變量;
};
test();
};
Foo.method = function() {
var that = this;
function test() {
//that指向Foo對象;
};
test();
};
三、閉包和引用
閉包:當前作用域總是能訪問外部作用域中的變量。
例:
function counter(start) {
var count = start;
return {
increment: function() {
count++;
},
get: function() {
return count;
}
};
};
var test = counter(4);
test.increment();
test.get(); //5;
循環中的閉包:
for (var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i); // 10個10;
}, 1000);
};
方法:
1. for (var i = 0; i < 10; i++) {
(function(e) {
setTimeout(function() {
console.log(e); // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
}, 1000);
})(i);
};
2. for (var i = 0; i < 10; i++) {
setTimeout(function(e) {
return function() {
console.log(e); //0, 1, 2, 3, 4, 5, 6, 7, 8, 9
};
}(i), 1000);
};
四、arguments對象
每個函數內都可以訪問一個變量arguments,它維護著所有傳進來的參數列表,不是一個數組,不能用pop()、push()等數組方法,但是能訪問其length;
註:當arguments作為局部變量聲明和形參時,arguments對象不會被創建;
註:強烈建議不要使用arguments.callee;
轉換為數組:Arrary.prototype.slice.call(arguments);但轉化比較慢,不咋推薦;
arguments會創建getter和setter方法,改變形參的值會改變arguments對象的值,反之亦然;
例:
function test(a, b, c) {
arguments[0] = 10;
console.log(a); //10;
b = 20;
console.log(arguments[1]); //20;
var d = c;
d = 9;
console.log(c); //3;
};
test(1, 2, 3);
function test(a) {
‘use strict‘;
a = 10;
console.log(a, arguments[0]); //10, 1
};
test(1);
五、函數間傳遞參數
1. function foo() {
test.apply(null, argument);
};
function(a, b, c) {};
2. 同時使用call和apply:
function Foo() {};
Foo.prototype.method = function(a, b, c) {
console.log(this, a, b, c);
};
Foo.method = function() {
Foo.call.apply(Foo.prototype.method, arguments);
};
或者:
Foo.method = function() {
var args = Array.prototype.slice.call(arguments);
Foo.prototype.method.apply(args[0], args.slice[1]);
};
JavaScript學習總結(三、函數聲明和表達式、this、閉包和引用、arguments對象、函數間傳遞參數)