函數和作用域

function  sum() {
console.log('hello')
console.log('饑人谷')
}
這是聲明函數,調用就直接:
sum()

另一種聲明方式:
var sum = function() {
console.log('hello')
console.log('饑人谷')
};
sum()

參數:
 function sum( a , b) {
console.log( a + b)
return a + b
};
sum( 3 ,4)
得到7。

 function sum( a , b ,c) {
console.log( a + b +c)
return a + b
};
sum( 3 ,4)
輸出NaN,因為c是undefined。而且聲明下,在控制臺的輸出的是console.log的執行的功能后展示的內容。
這里順便聯想了一下,console.log語句或表達式輸出的內容是這個語句在控制臺的一種功能作用的結果,它相當于控制臺的一個工具,而這個表達式或語句本身的值是undefined。
而return的才是給讀者的反饋。同時,return必須放到函數內部,只有在內部,才可以使參數有意義的。

function say( name,age) {
console.log( name + 'says: I am' +age +'years old')
}
say( '小哥',6)
’小哥says: I am  6 years old'

function say( name,age) {
console.log( name + 'says: I am' +age +'years old')
}
says( 6)
'6 says: I am  undefined years old'
6是name的值,剩下的undefined。

var result =sum( 4 ,6)
function sum(a ,b)  {
console.log(a + b)
}
console.log(result)
輸出10,這里是console.log到調試里的顯示結果,返回值是return的值。sum沒有返回值,默認為undefined值。console.log(a)是運行顯示了a,但是這句話本身的結果是undefined。

遇到return,后面就完全停了。
function fn( score){
if(score < 0){ 
return
}
console.log(score)
}
fn( -3 )
return 后面沒有賦值,就是返回undefined的意思。
調用時,fn( -3 )
返回undefined,后面不執行了。
這個等同于——
function fn(score) {
if(score <0)  {

}else {
console.log(score)
}
}
fn(-3)

參數相關和arguments:
function printName () {
var name = arguments[0]
console.log(name)
}
printName('Byron')

還有一種寫法——
function printName(name){
    console.log(name);
}
printName('Byron');
第二種是最直接的命名然后就可以用了,邏輯很簡單的,第一種是把參數name值通過arguments傳遞了過來,如果這時候沒有賦值,arguments值為undefined輸出為undefined。


聲明提前——
js文件都是順序執行的哦。
變量的:
console.log(a)
console.log(b)
var a=3
執行的結果是a輸出undefined不報錯,b輸出undefined報錯了。
為什么?var a =3等同于——
var a   //這是聲明,規則是放到所在區塊的前端,然后再執行。
a = 3

也就是在瀏覽器邏輯解析下,就是這個樣子執行:
var a
console.log(a)
console.log(b)
 a=3
這樣就明白了吧,a現在已經聲明了,但是執行console.log時,3的值還沒生效,為undefined,當然把執行語句放到a=3后面執行,就可以了。
b又沒聲明,又沒值。

函數的:

sum(3,5)
function sum(a ,b){
console.log( a + b)
}
這時候運行起來,得到8。甚至在sum和函數中間加點語句也會顯示。這里要說,函數聲明跟變量聲明類似,在執行之前,把所有的變量聲明和函數聲明拿到執行語句的前面。
表達式的聲明:
fn()
var  fn = function(){
console.log('haha')
}
運行報錯了。為什么?
函數表達式的角度看,上面的代碼等同于:
var  fn
fn()
fn = function(){
console.log('haha')
}
按順序來,fn現在只是聲明了,是undefined,而fn()是把fn當成函數了,所以報錯了。

立刻執行的函數表達式——
(function(){
console.log('haha')
})()
輸出"haha",小括號的優先級高,被認為是個值,一個值加(),被認為是函數。
相當于:
var fn = function(){
console.log('haha')
}
fn ()

命名沖突——

var fn = 3
function fn(){  }
console.log(fn)
等同于
var fn  //聲明,fn is undefined
function fn(){ }  // fn賦予了函數聲明,覆蓋了undefined狀態
fn = 3  //  3的值賦予到a,這個操作才是最終的結果
console.log(fn)  // 3

function fn(){  }
console.log(fn)
var fn = 3
等同于:
function fn(){  } //聲明,fn不僅有了var fn的意義,更進一步添加了函數的內在身份
var fn   //聲明 ,無所謂影響了,最
console.log(fn)   // function fn(){  }
 fn = 3  // 賦值

function fn(fn ){
console.log( fn )
var fn = 3
console.log( fn )
}
fn(10)
如果出現了參數與函數命名重復了怎么辦?假設一個arguments[0]。
變成如此:
function fn( ){
var fn = arguments[0] //這時候把10賦予過來了
console.log( fn )  // 輸出10
var fn = 3  //3覆蓋掉10的值
console.log( fn )  //輸出3
}
fn(10)  //10,3

這里就有些類似于我高考的數學變形題目了,fn(fn)跟fn(10)的關系就是得到了現在fn=10,回歸到函數內部,就還有一個語句運行環境的觀念,千萬不要想當然,整個函數運行起來,fn=10適用于所有語句了。能說它嵌套嗎?也不算。

遞歸函數——
function fn(n ){
if (n ==1){
return 1
}     // 限制n為1時的0或者出現負數
return n*fn(n-1)  //這是表達式
}
fn (4) //24,就是1*2*3*4
效率低,需要計算1,2,3,4,的,算4次,就是邏輯清晰簡單而已。

作用域——————
{
var a = 3
}
console.log(a) //1,也沒報錯,直接寫大括號沒作用域

js里沒有塊級作用域。
循環:
for(var i =0; i<10; i++){
var a = 3
}
console.log(a) //3,這里的意思就是循環語句里的變量作用于全局的,也就是沒有作用域,包括里面的i。當然循環語句會聲明前置到代碼頂部。
這里很容易混淆,因為重點就是講函數的作用域的。
function fn(){
var a =1
if (a>2){
var b =3
}
console.log(b)
}
fn()//1<2,直接運行后面的console.log(b),b沒聲明,undefined
console.log(a)// 報錯了,因為函數作用域,a是函數內部變量,全局里沒有它。

這里的意思就是變量都是有作用區域的,聲明區域多大,它的意義就發揮在多大空間,跟數學函數的自變量的范圍差不多。函數內的變量只能有意義在這個函數內部,那全局變量對函數本身內部呢?

function fn(){
a = 2
}
fn()
console.log(a)//2,不寫var去聲明變量,就是全局的性質,外部可以用它了。所有以后聲明變量一定要邏輯清晰,慎重。在最外層寫全局的,能寫var就寫上。













最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容