重点。

1、函数介绍

函数是一块JavaScript代码,被定义一次,但可执行和调用多次。JS中的函数也是对象,所以JS函数可以像其他对象那样操作和传递,所以我们也常叫JS中的函数为函数对象。

javascript 函数和作用域(函数,this)(六)

注意:

返回Return

return语句可以使函数提前返回。

一个函数总会返回一个值,函数的返回值,依赖于return语句。

一般的函数调用:如果没有return语句的话,默认会在所有代码执行完以后返回undefined

如果是作为构造器,外部使用new去调用的话,如果没有return语句,或者return的是基本类型的话,默认会将this作为返回。

反之,如果return的是对象,将这个对象作为new构造器的返回值。

2、函数的属性和方法【20170501】

函数属性

  • length属性
  • prototype属性
  • 自定义属性

函数方法

  • call()
  • apply()

3、函数的相关内容

函数内容较多,重点有:

  • this
  • arguments
  • 作用域
  • 不同调用方式
    • 直接调用foo()
    • 对象方法o.method()
    • 构造器new Foo()
    • call/apply/bind调用 func.call(o)
  • 不同创建方法

二、函数声明和表达式

1、函数声明

function add(a,b){
    a=+a;
    b=+b;
    if(isNaN(a)||isNaN(b)){
        return;
    }
    return a+b;
}

一个完整的语句以function开头,也不加括号,也不加叹号,也不会把它括起来,也不会把它作为赋值语句的右值等待。这样定义的函数就叫函数声明。

2、函数表达式

1、 函数变量

函数表达式赋值给变量。

//函数变量 function variable
var add=function(a,b){
    //do sth
}

2、立即执行函数表达式(IEF)

把一个匿名函数用括号括起来,再去直接调用。

//立即执行函数表达式 IEF(Immediately Executed Function)
(function(){

})();

3、作为返回值的函数表达式

将函数对象作为返回值,函数也是对象。

//first-class function
return function(){
    //do sth
}

4、命名式函数表达式(不常用

同样是赋值给一个变量,但这个函数不是匿名函数,而是有一个名字的函数,

//NFE (Named Function Expression)
var add=function(a,b){
    //do sth
}

3、函数声明和函数表达式的区别

最主要的区别是函数声明会被前置。

函数声明,在声明前调用也可以,因为会前置。

函数表达式在声明前调用会报错:undefined is not a function。

javascript 函数和作用域(函数,this)(六)

函数表达式中

var add=function(a,b){//do sth};

变量的声明会被提前,var add会提前,add被提前后它的值是undefined。

当把一个undefined的变量尝试像函数那样去调用的时候,就会报异常:undefined is not a function。

注意:在《jquery按钮绑定特殊事件》

中第一次点击按钮触发一个事件,第二次点击触发另一个事件。遇到类似的情况,

//不要这样做

if(condition){
    function sayHi(){
        alert("Hi!");
    }
}else{
    function sayHi(){
        alert("Yo!");
    }
}

//可以这样做
var sayHi;
if(condition){
    sayHi=function(){
        alert("Hi!");
    }
}else{
    sayHi=function(){
        alert("Yo!");
    }
}

命名函数表达式(NFE)

函数名字可以被调试器和开发工具识别。

 经典bug

javascript 函数和作用域(函数,this)(六) 

命名函数表达式里的名字nfe在 函数对象创建所在的作用域中 正常情况下是访问不到的。所以会报错:nfe is not defined

老的IE浏览器(IE6~8)仍然可以访问得到,但是nfe和func又不是同一个对象。

命名函数表达式相关规范:

规范规定:命名函数表达式名字(标识符)在函数体的作用域内有效,且不能被覆盖。

b = function c() {
    a = 1, b = 2, c = 3;
    console.log(typeof c); // function
};

命名函数表达式应用

调试

javascript 函数和作用域(函数,this)(六) 

 递归调用自己

//递归调用
var func=function nfe(){/** do sth. **/ nfe();}

5、函数构造器

除了函数声明和函数表达式,还有一种不常见的构造函数的方式—使用函数构造器。

Function()中参数可以有多个,前面的参数表示函数对象里面的形参,最后一个参数表示函数体里面的代码。

函数体里的代码也是字符串,这也是为什么函数构造器不常用的原因。

var func=new Function('a','b','console.log(a+b);');
//创建一个对象,有a,b2个形参,函数体里面是输出a+b
func(1,2);//3

//不管用new还是不用new最后得到的结果都是一样的。
var func=Function('a','b','console.log(a+b);');
func(1,2);//3

Function构造器作用域和其他处理与一般函数声明和函数表达式的差异

1、在Function构造器里面创建的变量仍然是局部变量,

//CASE1
Function('var localVal="local";console.log(localVal);')();//立即执行
console.log(typeof localVal);     //undefined

2、Function函数声明能访问到全局变量,却访问不到它的外函数中定义的变量。

javascript 函数和作用域(函数,this)(六) 

 local不可访问,全局global可以访问。

javascript 函数和作用域(函数,this)(六)

三、this

1、全局的this(浏览器)

全局作用域下的this一般指向全局对象,浏览器汇总的全局对象就是window。

javascript 函数和作用域(函数,this)(六)

 2、一般函数的this(浏览器)【重点】

全局作用域下直接调用f1(),this就仍然指向全局对象,浏览器中就是window,在node.js里面就是global对象。

 javascript 函数和作用域(函数,this)(六)

严格模式下直接调用f2(),this执行是undefined。

javascript 函数和作用域(函数,this)(六)

注意:语言设计上的不足【update 20170306】

调用函数时,this被绑定到全局对象。如下内部函数调用时this也是绑定到全局对象window。

function outer(){
    console.log(this===window);
    function inner(){
        console.log("内部函数:"+(this===window));
    }
    inner();
}
View Code

相关文章:

  • 2022-12-23
  • 2021-10-24
  • 2022-12-23
  • 2020-04-01
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2021-11-23
  • 2022-03-14
  • 2022-12-23
  • 2022-12-23
  • 2021-09-26
相关资源
相似解决方案