函數
1) 做用 -- 函數也是對象,是一個引用數據類型node
1. 利用函數能夠封裝一些具備特殊功能的代碼,以後調用便可實現相應的效果 arr.sort(); // 排序 arr.reverse(); // 反轉 jQuery(); ajax(); // http請求 2. 利用函數封裝對象【api本質/構造函數】高級面向對象
2) 函數建立方式 --函數建立完畢後通常不會自動執行,須要調用es6
函數聲明ajax
function 函數名(形參列表){ // 函數體 } function sayMsg(name,age,gender){ console.log('name:',name); console.log('age:',age); console.log('gender:',gender); } sayMsg('zhangsan',13,'male'); 實參的順序與形參的順序是一一對應的 形參能夠是對象,訪問時obj.屬性
函數表達式 -- 匿名函數賦值給變量api
var 函數名 = function(形參列表){ // 函數體 }; var fun = function(name,age){ console.log(name); console.log(age); } fun.call(this,'tom',20,'male'); fun.apply(this,['larry',18,'female']);
3) 調用方式數組
調用時解析器不會檢查實參類型,數量 多餘的實參不會被賦值,實參不足,沒有對應實參的形參是undefined 函數體return後的語句不會執行 return 後無值,無return --- 返回undefined 函數名(實參列表); 函數名.call(this,實參列表); 函數名.apply(this,實參數組); sayMsg('zhangsan',13,'male'); fun.call(this,'tom',20,'male'); fun.apply(this,['larry',18,'female']);
4) 提高瀏覽器
代碼從它們在代碼中出現的位置被移動到當前做用域最上方進行執行【解析器操做的】,這個過程叫作提高
變量的提高 -> 用var聲明的變量會在全部代碼執行前被聲明(可是不會被賦值)
1>閉包
a = 1; var a; console.log(a); ==>等價於 var a; a = 1; console.log(a); // 1
2>app
console.log(a); var a = 1; ==>等價於 var a; console.log(a); // undefined --a未被賦值 a = 1;
函數聲明的提高 ->用函數聲明方式建立的函數(function a(){}),會在全部代碼執行前被建立函數
1> test(); function test(){ console.log(1); } ==>等價於 function test(){ console.log(1); } test(); // 1 2> fun(); var fun = function(){ //函數表達式建立 console.log(1); } ==>等價於 var fun; fun(); // fun is not a function fun = function(){ console.log(1); }
函數聲明與函數表達式的提高 -> 函數聲明的提高優先於函數表達式this
var fun = function(){ console.log(2); } fun(); function fun(){ console.log(1); } ==>等價於 function fun(){ console.log(1); } var fun = function(){ console.log(2); } fun();
5) 引用數據類型的比較
同一個指針不能夠同時指向多個堆內存中的區域 可是同一個堆內存中的區域能夠同時被多個指針所指向 var obj1 = { name:'tom', age:13, gender:'male' } var obj2 = { name:'tom', age:13, gender:'male' } var obj3 = obj1; console.log(obj1 == obj2); // false console.log(obj1 === obj2); // false console.log(obj1 == obj3); // true console.log(obj1 === obj3); // true
6) 函數的內部屬性 -> 只有在函數內部能夠訪問到的屬性
arguments【類數組對象】
當前函數接受的全部參數所存儲的地方
{ '0': 'tom', '1': '13', '2': 'male', length:3 // 只有在瀏覽器打印時才顯示 } callee 指向當前的函數 將類數組對象轉換爲數組
*3. this
當前函數執行時所依賴的環境 nodejs -> global對象 瀏覽器 -> window對象 this的指向性問題 能夠根據函數的調用方式來判斷 函數名(實參列表); 函數名.call(this,實參列表); 函數名.apply(this,實參數組); 一、以()方式調用函數 若是函數名的左邊沒有對象,則this指向全局 function test(){ console.log(this); } test(); //函數方式調用 nodejs -> global對象 瀏覽器 -> window對象 =window.test() 若是函數名的左邊有對象,則this指向該對象 var obj1 = { name:'tom', sayName:function(){ console.log(this.name); } } var obj2 = { name:'terry', sayName:function(){ console.log(this.name); } } //以方法方式調用 obj1.sayName(); // this指向了obj1對象 tom obj2.sayName(); // this指向了obj2對象 terry 二、以call和apply的方式調用 更改this的指向 var obj1 = { money:'有錢', pay:function(){ console.log(this.money); } } var obj2 = { money:'沒錢' } obj1.pay(); // 有錢 obj1.pay.call(obj2); // 經過call()將this指向obj2 沒錢 obj1.pay.apply(obj2); // 經過apply()將this指向obj2 沒錢 三、箭頭函數的this指向外部函數的this function(){} es5 ()=>{} es6
7) 閉包
函數內部的函數 function test(){ function a(){ } } function test(){ var name = 'tom'; function a(){ return name; } return a(); } var res = test(); console.log(res); // tom function test(){ var name = 'tom'; console.log(age,'-----'); //age--undefined function a(){ var age = 13; return name; } return a(); } var res = test(); console.log(res); 內部函數能夠訪問外部函數中的屬性,可是外部函數不能訪問內部函數的屬性
8) 匿名函數和自執行函數
匿名函數:沒有名字的函數 function(){} 自執行函數:會自動執行的函數---只執行一次 ( function(){} ) () 函數對象 (function(){ console.log(1); })(); // 1 (function(name,age){ console.log(name); console.log(age); })('zhangsan',13); // zhangsan 13
9) 方法
函數做爲對象的屬性,將該函數叫作對象的方法 var obj = new Object(); obj.name="jerry"; obj.sayName = function(){ //方法 console.log(obj.name); }; obj.sayName(); //調用對象的方法
10)做用域
1.全局做用域
- 頁面打開時建立,頁面關閉時銷燬 - 有一個全局對象window--表明瀏覽器窗口,由瀏覽器建立,能夠直接使用 - 全局中建立的變量都會做爲window對象的屬性保存 全局中建立的函數都會做爲window對象的方法保存 - 域中變量都爲全局變量,頁面任意部分都可訪問 var a=1; console.log(window.a); function fun(){} window.fun();
2.函數做用域
-調用函數時建立,函數執行結束則銷燬 -每調用一次函數就會建立一個新的做用域 -函數做用域中能夠訪問全局變量 -在函數做用域中建立變量,會先在自身做用域尋找,無則在上一級做用域尋找,直到全局做用域,若依舊無,則會報錯ReferenceError -函數做用域中想訪問全局變量 -- window.a -有變量提高 -- var聲明變量會提早, 有函數提高 -函數內變量未用var 聲明,則是全局變量 -定義形參至關於在函數做用域中聲明瞭變量
eg:
1> var a = 10; function fun(){ var a = 20; function func2(){ console.log(a); //a = 20 console.log(window.a) //a = 10 } fun2(); } fun(); 2> var c =10; function fun(){ console.log(c); c=20; d=100; } fun(); //c=10 --找全局 console.log(c); //c=20 --函數內c未用var 聲明,是全局變量 console.log(d); //d = 100 -- 可訪問,由於d是全局 3> var e = 10; function fun(e){ //var e; 定義形參即聲明變量 console.log(e); } fun(); //underfined
一、構造函數和普通函數的區別
1) 首字母 2) 調用方式 構造函數經過new關鍵字調用 var obj = new Object(); new Vue(); 普通函數直接調用 function sayName(){ xxx } sayName();
二、函數使用()和不使用()的區別
使用(),表示調用當前函數,並返回函數的返回值 不使用(),表示一個指向當前函數的指針 如何將一個函數賦值給一個變量,再將變量放入到對象中? 錯誤代碼: function test(){ console.log(1); return 'hello world'; } var a = test(); var obj = { name:a } console.log(obj); // 1 {name:'hello world'} 正確代碼: function test(){ console.log(1); return 'hello world'; } var a = test; var obj = { name:a } console.log(obj); // {name:[Function: test]}
三、return與console.log()的區別
函數使用return以後纔會有返回值 函數使用console.log是沒有返回值的 function test(){ console.log(1); } function fun(){ return 2; } var a = test(); var b = fun(); console.log(a); // 1 undefined console.log(b); // 2