函數的聲明和函數的表達式
函數的聲明
function fn(){}
這是函數聲明- 帶有名字的是具名函數 聲明後面不需要加分號
- 函數在聲明的時候並沒有執行,只是把內部作爲一塊 存起來 當調用時候執行 函數的執行:
fn();
採用函數名加() 執行不分場合,可以放在函數聲明之前 可以在函數聲明之後 - 在函數聲明之後不能加() 比如
function fn(){alert(1);}();
是會報錯的 - 匿名函數不能莫名奇妙出現 除非在賦值 傳參 場景下出現
var i=10;
function fn(){
alert(i);
}
i=11;
fn();
結果是11 代碼自上而下執行
var i=10;
fn();
function fn(){
alert(i);
}
i=11;
結果是10
fn();
var i=10;
function fn(){
alert(i);
}
i=11;
結果是undefined 這個關於作用域
函數表達式
var fn = function(){};
把匿名函數作爲值傳遞 是函數表達式 此時需要加括號 因爲這是個語句- 函數想要執行 變量名加()
fn();
var fn =function ab(){
alert(1);
}
ab();
是會報錯的 只是把函數作爲值傳遞 並不是聲明 執行是變量名加(); 一般賦值不取名字
- 函數表達式可以在末尾加()執行
- 把函數聲明 轉換成函數表達式 加括號執行
(function(){
alert(1);
})();
!function(){
alert(1);
}();
+function(){
alert(1);
}();
~function(){
alert(1);
}();
(function(){
alert(1);
}());
在匿名函數外邊加括號轉變爲函數表達式 匿名函數立即執行(iife)
作用1 節省變量 2 私有屬性的問題
函數作用
- 代碼的重複使用
- 獨立的代碼快 不影響其他變量
<body>
<div id="box">1</div>
<div id="wrap">2</div>
<div id="content">3</div>
</body>
<script>
var oBox = document.getElementById("box");
var box2 = document.getElementById("wrap");
var box3 = document.getElementById("content");
oBox.onclick = fn;
box2.onclick = fn;
box3.onclick = fn;
function fn() {
alert(this.innerHTML);
}
</script>
需要注意的是 是點擊之後執行函數 所以不能寫成oBox.onclick = fn();
相當於把函數當作一個值fn傳過去了
function fn() {
var a =123;
console.log(a);
}
fn();
結果是123
var a =123;
function fn() {
console.log(a);
}
fn();
結果是123
var a =123;
function fn() {
var a =346;
console.log(a);
}
fn();
console.log(a);
第一個結果是346 第二個結果是123;如果沒有變量聲明 會去函數外邊找 但是函數外邊不能影響函數內部的變量聲明 函數內部的變量聲明也不去影響外界
形參和實參
function fn() {//小括號裏面可以放東西 我們稱之爲 形參 可以看作var a 沒賦值
console.log(a);
}
function fn(a) {//小括號裏面可以放東西 我們稱之爲 形參
console.log(a);
}
fn(2);//實際上的參數 實參 傳遞數據給形參賦值 a=2; 形參和實參一一對應
function fn(a,b) {
console.log(a+b);
}
fn(2,3,4);
不會報錯 結果是5
function fn(a,b) {//var a,b
console.log(a+b);
}
fn(2);//a=2
結果是NaN
arguments
- arguments 僅僅存在於函數當中 你用與不用 他都在 是個類數組 保留着所有實參
function fn() {
var len = arguments.length;
var sum = 0;
for(var i=0;i<len;i++){
sum += arguments[i];
}
console.log(sum);
}
fn(1,2,3,4,5);
結果是15console.log(arguments.callee)
是函數本身
練習
<script>
document.onclick = fn;
function fn(x) {
alert(x);
}
</script>
如果想把參數2傳入參數 怎麼實現? console.log(fn(2));
結果是undefinde
<script>
document.onclick = function(){
fn(2);
};
function fn(x) {
alert(x);
}
</script>
實參裏面可以放任何數據類型
<script>
function x(y) { //var y;
y();
}
x(function () {//y=function(){alert(1)}
alert(1);
})
</script>
<script>
function x(y) { //var y;
y(2);
}
x(function (a) { //y=function(a){alert(a)}
alert(a);
})
</script>
把函數當作參數傳遞
console.log(a=10);
結果是10 是等號右邊
console.log(x=function () {
alert(1);
});
結果是等號右邊 函數體本身
var x;
(x=function () {
alert(1);
})();
console.log(x);
結果還是函數體本身 x賦值就是函數體本身 第二行代碼是匿名函數自執行 賦值操作的返回值是等號右邊的數據
函數返回值 return
<script>
function fn() {
console.log(1);
}
console.log(fn());
</script>
結果是1 undefined
凡是運算 都有返回值 函數的執行也是一種運算 也應該有返回值
console.log(console.log(1));
結果是1 undefined 默認情況下 函數運算 “執行”的返回值是undefined
即console.log(console.log());
的結果是undefied;那麼 console.log(fn());
結果可以看作是函數執行的值和fn()”執行“的運算
- 改變返回值 用return 函數運行的返回值
<script>
function fn() {
console.log(1);
return 10;
}
console.log(fn());
</script>
結果是1 10
- return除了能夠確定函數的返回值以外 還能阻斷函數的執行
<script>
function fn() {
return 10;
console.log(1);
}
console.log(fn());
</script>
這樣遇到return後 不會執行console.log(1);直接跳出函數 那麼結果是10
for (var i=0;i<100;i++){
if(i==50){
return;
}
}
這樣會報錯 return只能用在函數中 跳出循環用break
- return只能在函數中使用
var i=0;
function fn() {
for (;i<100;i++){
if(i===50){
return;
}
}
}
fn();
console.log(i);
結果是 50
var i=0;
function fn() {
for (;i<100;i++){
if(i===50){
break;
}
}
}
fn();
console.log(i);
結果是50
var i=0;
function fn() {
for (;i<100;i++){
if(i===50){
return;
}
}
i++;
}
fn();
console.log(i);
結果還是50
var i=0;
function fn() {
for (;i<100;i++){
if(i===50){
break;
}
}
i++;
}
fn();
console.log(i);
結果是51
- break 是for循環跳出
練習
document.onclick = fn();
function fn() {
return function () {
alert(1);
}
}
document.onclick = fn()();
function fn() {
return function () {
return function(){
alert(1);
}
}
}
對於點擊事件來說加兩個括號 對於函數執行來說加三個括號
寫個函數 傳入數值 返回一加到該數字的值
function add(x) {
if (x>1){
return x+add(x-1)
} else{
return x;
}
}
add(10);
(function add(x) {
if (x>1){
return x+arguments.callee(x-1);
} else{
return x;
}
})(10);