//函數聲明 function add1(i,j){ return i+j; };
//函數表達式 var add2 = function(i,j){ return i+j; };
//對象實例化(通常不使用) var add3 = new Function('i','j','return (i+j)');
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);
//函數聲明 (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); })();
一、本質上沒有區別。
二、構造函數一般會有this指定實例屬性,原型對象上一般有一些公共方法。
三、構造函數命名一般首字母大寫。javascript
//構造函數 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;
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();
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};
//對象引用,參數列表 var circlemove = p.move.bind(circle,2,1); //延遲1秒調用 setTimeout(circlemove,1000);
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使用 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); }
函數內部調用一個函數,內部函數引用了父函數的變量,父函數做用域就會放在閉包做用域裏面供內部函數使用。閉包
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)); }
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