函數(shù)聲明定義函數(shù)特點(diǎn)
- 和變量的聲明會前置一樣,函數(shù)聲明同樣會前置,如果我們使用函數(shù)表達(dá)式那么規(guī)則和變量一樣
- 用函數(shù)聲明的方式,重復(fù)定義函數(shù),最后一次定義有效
函數(shù)實(shí)例化定義函數(shù)特點(diǎn)
- 定義的函數(shù)只能訪問本地作用域和全局作用域
變量前置
console.log(a) //undefined
var a = 3
==>等同于
var a
console.log(a)
a = 3
函數(shù)聲明
console.log(sum(3,5))
function sum(a,b){
return a + b
}
==>等同于
function sum(a,b){
return a + b
}
console.log(sum(3,5))
函數(shù)表達(dá)式聲明前置
fn() //"TypeError: fn is not a function(不是一個(gè)函數(shù))
var fn = function(){
console.log('fn...')
}
==>
var fn
fn()
fn = function(){
console.log('fn...')
}
立即執(zhí)行函數(shù)
立即執(zhí)行函數(shù)可以形成一個(gè)作用域,和全局隔開,不會污染全局,另一方面也是防止命名沖突的影響
(function(){
console.log('我是立即執(zhí)行函數(shù)')
})()
==>
var fn = function(){
console.log('我是立即執(zhí)行函數(shù)')
}
fn()
命名沖突
當(dāng)在同一個(gè)作用域內(nèi)定義了名字相同的變量和方法的話蛇捌,會根據(jù)前置順序產(chǎn)生覆蓋
var fn = 3;
function fn(){}
console.log(fn); // 3
==>
var fn
function fn(){} //覆蓋上面的
fn = 3 //重新賦值
console.log(fn)
console.log(fn); // 3
function fn(){}
var fn = 3;
==>
function fn(){}
var fn //已經(jīng)聲明的值不會變
console.log(fn) //fn(){}
fn = 3
遞歸
簡單來說就是自己調(diào)用自己
function factorial(n){
if(n === 1){
return 1
}
return n * factorial(n-1)
}
alert(factorial(3))
//缺點(diǎn):效率低
函數(shù)調(diào)用
- 函數(shù)調(diào)用模式
函數(shù)名()
- 方法調(diào)用模式
var myNumber = {
value: 1,
add: function(i){
console.log(this);
this.value += i;
}
}
myNumber.add(1);
- 構(gòu)造函數(shù)調(diào)用模式
-
new Function(...)
首字母大寫
-
-
apply(call)
調(diào)用模式-
apply
是function構(gòu)造函數(shù)原型上的構(gòu)造方法- 實(shí)現(xiàn)函數(shù)借用的功能,把函數(shù)借用給對象
-
函數(shù)調(diào)用模式的區(qū)別-this
- 函數(shù)調(diào)用模式
- this指向window的全局對象
//例子:
function add(i,j){
console.log(this); //Window
// console.log(arguments);
var sum = i+j;
console.log(sum);
(function(){
console.log(this); //Window
})()
return sum;
}
add(1,2);
- 方法調(diào)用模式
- this指向調(diào)用者
//例子:
var myNumber = {
value: 1,
add: function(i){
console.log(this); //Object{value: 1, add: ?}
this.value += i;
}
}
myNumber.add(1);
- 構(gòu)造函數(shù)調(diào)用模式
- this指向被構(gòu)造的函數(shù)
//例子:
function Car(type,color){
this.type = type;
this.color = color;
this.status = "stop";
this.light = "off";
console.log(this); //打印結(jié)果是我們創(chuàng)建的對象
}
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 benz = new Car("benz", "black"); //Car {type: "benz", color: "black", status: "stop", light: "off"}
-
apply(call)
調(diào)用模式- this指向第一個(gè)參數(shù)
函數(shù)傳參
- 原始類型按值傳遞-
call by value
var count = 1;
var addOne = function(num) {
num += 1;
return num;
}
var ret = addOne(count);
console.log(ret); //2
console.log(count); //1結(jié)果沒有受到影響
- 對象類型按共享傳遞-call by sharing
//例子一:
var count = {a:1,b:1};
var addOne = function(obj) {
obj.a += 1;
obj.b += 1;
return obj;
}
var ret = addOne(count);
console.log(ret); //{a: 2, b: 2}
console.log(count); //{a: 2, b: 2}
//例子二:
var count = {a:1,b:1};
var addOne = function(obj) {
obj = {a:2, b:2};
return obj;
}
var ret = addOne(count);
console.log(ret); //{a: 2, b: 2}
console.log(count); //{a: 1, b: 1}