JS函数(一)

来源:互联网 发布:c语言多进程编程实例 编辑:程序博客网 时间:2024/06/15 18:39

准备发一个系列,今天先说函数

函数

        定义函数方式有两种,一种是函数声明,另一种是函数表达式

函数声明的语法

            function fn(a,b,c){            };

关于函数声明它有一个重要特征就是函数声明提升,意思就是在执行代码之前会先读取函数声明也就是说我们可以把函数声明放在调用他的后面

    sayHello();            function sayHello(){                console.log("Hello");            };

上述例子不会出现错误,因为在代码执行前会先读取函数声明

函数表达式
函数表达式有几种不同的语法形式,下面是最常见的一种形式

            var fnDp=function(a,b,c){                //函数体            };

这种形式好像看起来是常规的变量赋值语句,即创建一个函数并将它赋值给变量fnDp,这种情况下创建的函数叫匿名函数。匿名函数的name属性是空字符串。

函数表达式和其他表达式一样,在使用前必须先赋值,一下代码会导致错误。

sayHello1();    var sayHello1=function (){            console.log("Hello");        };

理解函数提升的关键,就是理解函数声明与函数表达式之间的区别。例如执行一下代码的结果可能会让人意想不到.

    //不要这样做            var condition =false;            if(condition){                function sayHello1(){                    console.log("Hello");                };            }else{                function sayHello1(){                    console.log("Hi");                };            }

表面上看,以上代码表示condition为true时,定义一个弹出hello的sayHello1函数否则就是弹出Hi实际上,在ECMAScript中属于无效语法,javascript引擎会尝试修改错误,将其转化为合理状态,但浏览器尝试修复的方式并不一致,大多说浏览器会返回第二种声明,忽略condition;Firefox会在condition为true时返回第一个声明。因此这种方式是非常危险的,不应该出现在你的代码中,不过,如果使用函数表达式,那就no problem 了

//可以这样做            var sayHello1            if(condition){                sayHello1=function (){                    console.log("Hello");                };            }else{                sayHello1=function(){                    console.log("Hi");                };            }

这个例子不会出现什么意外,不同的函数会根据不同的condition 被复制给sayHello1。

This

var name='world';            var obj={                name:"wdl",                getName:function(){                    return function(){                        return this.name;                    }                }            }            console.log(obj.getName()());//world

以上代码先创建一个全局变量name,又创建了一个包含name的对象。这个对象还包含一个方法getName(),他返回一个匿名函数,而匿名函数又返回this.name.由于getName()返回一个函数,因此调用object.getName()()就会立即调用它返回的函数,结果就是返回一个字符串。然而这个例子返回的字符串是“world”,即全局name变量的值。为什么匿名函数没有取得其包含作用域(或外部作用域)的this对象呢每个函数在被调用时,其活动对象都会自动取得两个特殊变量:this和arguments.函数内部在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量,不过如果把外部作用域中的this对象保存在一个闭包能访问到的变量里,就可以让闭包访问该对象了

var name='world';            var obj={                name:"wdl",                getName:function(){                    var that=this;                    return function(){                        return that.name;                    }                }            }            console.log(obj.getName()());//wdl

与之前代码的不同之处是在定义匿名函数之前,我们把this对象赋值给一个名叫that的变量。而在定义了闭包之后,闭包也可以访问这个变量,即使在函数返回之后,that也仍然引用着object,所以调用obj.getName()()返回“WDl”

如果上述你感觉难理解你也可以这样理解,obj.getName()()会直接调用

function(){
return this.name;
}

    function(){                    return that.name;                }

因为在这两个函数运行时会自动创建this和arguments.函数内部在搜索这两个变量,这里的this就是指当前函数的this,我们知道匿名函数的this是指向window的(严格模式下的this不再是window,而是undefined),所以第一个函数返回“world”,而第二个因为定义了that,所以返回“wdl”

如有不足请指出

原创粉丝点击