JavaScript函數介紹

1、函數定義

一、函數聲明

//函數聲明
function add1(i,j){
	return i+j;
};

二、函數表達式

//函數表達式
var add2 = function(i,j){
	return i+j;
};

三、對象實例化(通常不使用)

//對象實例化(通常不使用)
var add3 = new Function('i','j','return (i+j)');

2、函數聲明與對象實例化、函數表達式的區別

一、函數聲明能夠在函數聲明以前調用。  而對象實例化、函數表達式只能在定義以後才能調用。

add1(1,1);
//函數聲明
function add1(i,j){
	return i+j;
};

//函數表達式
var add2 = function(i,j){
	return i+j;
};

add2(1,2);

//對象實例化(通常不使用)
var add3 = new Function('i','j','return (i+j)');
add2(1,3);

二、對象實例化:函數沒法訪問到父函數變量,經過對象實例化定義的全部函數都在window對象上。

//函數聲明
(function(){
	var i  = 10;
	function add(j){
		console.log(i+j);		//11
		//debugger;
	};
	add(1);
	console.dir(add); //
})();

//函數實例化
//對象實例化:add函數沒法訪問到父函數i變量,經過對象實例化定義的全部函數都在window對象上
(function(){
	var i  = 10;
	var add = new Function('j','console.log(i+j);debugger;'); //報錯
	add(1);
})();

3、構造函數

4、構造函數與普通函數的區別

一、本質上沒有區別。
二、構造函數一般會有this指定實例屬性,原型對象上一般有一些公共方法。
三、構造函數命名一般首字母大寫。javascript

5、函數調用

一、構造函數調用模式

//構造函數
function Car(type,color){
 this.type = type;
 this.color = color;
 this.status = "stop";
 this.light = "off";
}
Car.prototype.start = function(){
 this.status = "driving";
 this.light = "on";
 console.log(this.type + " is " + this.status);
}
Car.prototype.stop = function(){
 this.status = "stop";
 this.light = "off";
  console.log(this.type + " is " + this.status);
} 
var audi = new Car("audi", "silver");//this === audi;
var benz = new Car("benz", "black");//this === benz;
var ferrari = new Car("ferrari", "yellow");;//this === ferrari;

二、方法調用模式(作爲對象屬性的方式調用)

audi.start(); 	//this === audi;

三、函數調用模式(函數內的子函數的this指向window)

function add(i, j){
	return i+j;
};
var myNumber = {
	value: 1,
	double: function(){
		var helper = function(){
			this.value = add(this.value,this.value);  //錯誤
            console.log(this === window); //true

	    }
		helper();
	}
};

//閉包裏保存myNumber(this)對象做用域來解決
var myNumber = {
	value: 1,
	double: function(){
		var that = this;
		var helper = function(){
			that.value = add(that.value,that.value);
	    }
		helper();
	}
};
myNumber.double();

四、apply(call)調用模式

4.一、Function.prototype.apply:函數借用

function Point(x,y){
	this.x = x;
	this.y = y;
};

Point.prototype.move = function(){
	this.x+=x;
	this.y+=y;
};

var p = new Point(0,0);

p.move(2,2);		//p.x = 2;p.y = 2;

var circle = {x:1,y:1,r:1};

//傳入對象引用,參數數組
p.move.apply(circle,[2,3]);	//circle = {x:3,y:4,r:1};
p.move.call(circle,2,3);	//circle = {x:3,y:4,r:1};

4.二、Function.prototype.bind:函數借用,返回引用,用戶自定義調用函數時機。

//對象引用,參數列表
var circlemove = p.move.bind(circle,2,1);
//延遲1秒調用
setTimeout(circlemove,1000);

4.三、爲何JS中須要apply?若是JS中沒有apply須要多作哪些工做呢?

6、函數內部參數:arguments

arguments是函數內部(Array-like)類數組的對象。能夠經過arguments[index]得到傳入的參數,arguments.length來獲取傳入的參數長度。java

//arguemnts轉數組
function add(i,j){
	var args = Array.prototype.slice.apply(arguments);
	args.forEach(function(item){
		console.log(item);
	});
};
add(1,2,3);

一、arguments.callee

指向函數自己。能夠實現匿名函數遞歸調用。數組

//arguments.callee使用
console.log(
 (function(i){
    if (i==0) {
       return 1;
     }
     return i*arguments.callee(i-1);
 })(5) );
// 遞歸
function factorial(i){
  if (i==0) {
    return 1;
  }
  return i*factorial(i-1);
}

7、閉包

一、介紹

函數內部調用一個函數,內部函數引用了父函數的變量,父函數做用域就會放在閉包做用域裏面供內部函數使用。閉包

function(){
	var a = 0;
	function b(){
		a = 1;
		debugger;
	}
	b();
}();

二、應用場景:

1.封裝、屬性隱藏app

2.模塊化異步

3.記憶函數模塊化

三、閉包實現記憶函數(減小函數的計算量)

// 普通遞歸函數跟記憶函數調用次數對比
 var factorial = (function(){
   var count = 0;
   var fac = function(i){
     count++;
     if (i==0) {
       console.log('調用次數:' + count); 
       return 1;
     }
     return i*factorial(i-1);
   }
   return fac;
 })();
 for(var i=0;i<=10;i++){
   console.log(factorial(i)); 
 }

 // 記憶函數
 var factorial = (function(){
   var memo = [1];
   var count = 0;
   var fac = function(i){
     count++;
     var result = memo[i];
     if(typeof result === 'number'){
       console.log('調用次數:' + count); 
       return result;
     } 
     result = i*fac(i-1);
     memo[i] = result;
     return result;
   }
   return fac;
 })();
 for(var i=0;i<=10;i++){
   console.log(factorial(i)); 
 }

8、First-class function 一等公民

一、函數使用方式

1.普通變量保存函數

2.參數傳遞this

3.返回值返回spa

二、利用函數的靈活特性實現函數科裏化

function add(value){
    var helper = function(next){
       value = typeof(value)==="undefined"?next:value+next;
       return helper;
    }
    helper.valueOf = function(){
      return value;
    }
   return helper;
};
add(2)(3)(5).valueOf();//10

三、利用函數的靈活特性實現函數異步回調

相關文章
相關標籤/搜索