函數 函數:即方法 函數就是一段預先設置的功能代碼塊,可以反覆調用,根據輸入參數的不同,返回不同的值。 為什麼使用函數: 1.方便調用 2.代碼重用,利於維護 3.便於修改,便於重構 4.簡化邏輯,利於編程 1、聲明函數 聲明函數 Function Declaration 的三種方法 1)funct ...
函數
函數:即方法
函數就是一段預先設置的功能代碼塊,可以反覆調用,根據輸入參數的不同,返回不同的值。
為什麼使用函數:
1.方便調用
2.代碼重用,利於維護
3.便於修改,便於重構
4.簡化邏輯,利於編程
1、聲明函數
聲明函數 Function Declaration 的三種方法
1)function 命令
function print(s) {
document.write(s+"<br/>");
}
2)函數表達式
var printStr =function(str){
document.write(str+"<br/>");
}
這種寫法將一個匿名函數賦值給變數。這時,這個匿名函數又稱函數表達式(Function Expression),因為賦值語句的等號右側只能放表達式。
3)Function 構造函數 : 入門級別用的不多….
var add = new Function('x','y','return (x + y)');
// 等同於
function add(x, y) {
return (x + y);
}
var foo = new Function(
'return "hello world"'
);
// 等同於
function foo() {
return "hello world";
}
註意:不能在條件語句中聲明函數
函數名的提升
JavaScript 引擎將函數名視同變數名,所以採用 function 命令聲明函數時,整個函數會像變數聲明一樣,被提升到代碼頭部。所以,下麵的代碼不會報錯。
f();
function f() {}
錶面上,上面代碼好像在聲明之前就調用了函數 f。但是實際上,由於“變數提升”,函數 f 被提升到了代碼頭部,也就是在調用之前已經聲明瞭。但是,如果採用賦值語句定義函數,JavaScript 就會報錯。
f();
var f = function (){};// TypeError: undefined is not a function
2、函數的調用
函數的調用:圓括弧運算符
函數名([實參]);
存在返回值可以變數接收
print()
printStr("goodgoodstudy");
var result =add(1,2);
3、參數
參數: 形參與實參 函數運行的時候,有時需要提供外部數據,不同的外部數據會得到不同的結果,這種外部數據就叫參數。"種瓜得瓜種豆得豆",使用時實參可以省略。
function square(x) { //x 為形參
return x * x;
}
square(2) // 4 2 為實參
square(3) // 9
function f(a, b) {
return a;
}
//實參可以省略
f(4, 2, 3) // 1
f(10) // 1
f() // undefined
同名參數:取最後的一個
function f(a, a) {
console.log(a);
}
f(1, 2) // 2
預設值:使用 || 或運算
function f(a){
a = a || 1;
return a;
}
f('') // 1
f(0) // 1
//更精確寫法
function f(a){
(a !== undefined && a !== null) ? a = a : a = 1;
return a;
}
值傳遞(passes by value):值的副本
var box= 2;
function f(a) {
a = 3;
}
f(box);
console.log(box) // 2 沒有改變
//思考 對象值的改變
var obj = {p: 1};
function f(o) {
o.p = 2;
}
f(obj);
console.log(obj.p) // 2
//思考
var obj = [1, 2, 3];
function f(o){
o = [2, 3, 4];
}
f(obj);
console.log(obj) // [1, 2, 3]
arguments 對象: 獲取所有的參數,可以看成數組。由於 JavaScript 允許函數有不定數目的參數,所以我們需要一種機制,可以在函數體內部讀取所有參數。這就是 arguments 對象的由來。
var f = function(a) {
for(var i in arguments){
console.log(arguments[i]);
}
}
f(1,2,3);
瞭解: callee
var add =function(){
//獲取調用者
console.log(arguments.callee === add); //是否為自己調用
}
add();
4、 return 語句
是函數的返回值。return 語句不是必需的,如果沒有的話,該函數就不返回任何值,或者說返回 undefined。
5、遞歸( recursion)
函數自己調用自身
函數頭:盡頭 函數體:重覆執行
function print(num){
if(num==10){ //遞歸頭
return ;
}
//遞歸體
console.log(num);
print(num+1);
}
print(1);
6、函數的地位
函數的地位是第一等公民
函數與其他數據類型完全是平等的,所以又稱函數為第一等公民
function add(x, y) {
return x + y;
}
// 將函數賦值給一個變數
var operator = add;
// 將函數作為參數和返回值
function a(op){
return op;
}
a(operator)(1, 1)// 2
7、函數的屬性和方法
name:函數名
length:參數個數
toString(): 返回源碼
8、函數作用域
函數作用域:全局(global variable)和局部(local variable)
var a =1; //全局變數
function display(){
var b=2; //局部變數
c =3; //沒有 var 為全局變數 ,調用完成後 c 就存在了
console.log(a+"-->"+b);
}
display();
//b 不能訪問
console.log(a+"-->"+c);
就近原則:
var v = 1;
function f(){
var v = 2;
console.log(v);
}
f(); // 2
console.log(v); // 1
變數提升
function foo(x) {
if (x > 100) {
var tmp = x - 100;
}
}
//等同於
function foo(x) {
var tmp;
if (x > 100) {
tmp = x - 100;
};
}
函數本身的作用域:函數本身也是一個值,也有自己的作用域。它的作用域綁定其聲明時所在的作用域。
var a = 1;
var x = function (){
console.log(a);
};
function f(){
var a = 2;
x();
}
f() // 1
9、方法的調用
方法的調用: apply call :調用一個對象的一個方法,以另一個對象替換當前對象。二者的區別在於參數是否為數組
function Animal(age){
this.name = "Animal";
this.showName = function(){
alert(this.name);
}
}
function Cat(){
this.name = "Cat";
}
var animal = new Animal();
var cat = new Cat();
//通過 call 或 apply 方法,將原本屬於 Animal 對象的 showName()方法交給對象 cat 來使用了。
//輸入結果為"Cat"
animal.showName.call(cat,"10");
// 等同於apply方法中參數為數組
animal.showName.apply(cat,[10]);
10、 eval
執行字元串,將字元串當作語句執行。
eval('var a = 1;');
alert(a); // 1
瞭解 jsonp 的使用:
var jsonp = 'foo({id:42})';
var f = new Function( "foo", jsonp );
// 相當於定義瞭如下函數
/*
function f(foo) {
foo({id:42});
}*/
//業務處理
var print=function(json){
console.log( json.id ); // 42
}
f(print);
//相當於
function f(print){
json = {id:42};
// print(json);
console.log(json.id);
}
上面代碼中,jsonp 是一個字元串,Function 構造函數將這個字元串,變成了函數體。調用該函數的時候,jsonp 就會執行。這種寫法的實質是將代碼放到函數作用域執行,避免對全局作用域造成影響。(上海尚學堂,原文首發至:公眾號 嗨碼歌)