【JavaScript】-- 函数介绍

函数是什么?

 

函数用于封装多条代码语句以实现所需功能,便于维护和服用。

我们需要知道立即执行函数,回调函数,匿名函数。

函数声明

函数声明有三种方式,前两种是常用的需要掌握。

用function关键字声明

  如果没有返回的内容,则在写代码的时候不关注返回值
  没有return:代码执行到大括号

用函数表达式声明

与常规的变量赋值相似,我们需要先创建一个匿名函数,然后赋值给变量函数名。我们知道在JS中如果要想使用一个变量,必须先给这个变量赋值,所以函数表达式也不例外,在调用之前,必须先给它赋值。否则会报错。

使用构造函数声明

 变量提升

与var变量相似,会进行提升。

 函数内部属性

只有在函数内部才能访问的属性。但this也可以在函数外部进行使用。

arguments

arguments是一个类数组对象,包含着传入函数中的所有参数。arguments主要用途是保存函数参数,但是这个对象还有一个名为callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。

作用:常用于实现实参个数不固定的函数。

下图实例中,只往函数中传入了两个形参,但是调用时却传入了七个实参,这些参数都保存在arguments中,因此不会报错。

callee

callee 属性是 arguments 对象的一个成员,仅当相关函数正在执行时才可用。

callee 属性的初始值就是正被执行的 Function 对象。

作用:callee可以保证外部名称的变化,不会引起内部代码的修改, 降低代码的耦合度 。

// 实现匿名的递归函数
var sum = function (n) {
  if (n == 1) {
      return 1;
  } else {
      return n + arguments.callee(n - 1);
  }
}
console.log(sum(6));//输出结果:21

*** this ***

this是根随着执行环境变化而变化的,它的指向取决于上下文环境 被谁调用就指向谁 没有明确指出被谁调用就是指向全局global

  • 在方法中,this 表示该方法所属的对象。

  • 如果单独使用,this 表示全局对象。

  • 在函数中,this 表示全局对象。

  • 在事件中,this 表示接收事件的元素。

  • 在显式函数绑定时,我们可以自己决定this的指向

  • 1.对象方法中的this

this指向调用它的对象:

this表示person对象,sayName方法所属对象就是person,所以

this.name指向的是person对象里的name属性。

// 谁调用了这个方法 this就指向谁
var person = {
    name:"zzy",
    age:17,
    sayName:function(){
        console.log("my name is",this.name);
    }
}
person.sayName();

  •  2.单独使用this

单独使用 this,则它指向全局对象。

在浏览器中,window 就是该全局对象为 [object Window]:

在node中,指向的是一个{}

var x = this;  

  • 3.函数中使用this  

在函数中,函数的所属者默认绑定到 this 上,属于全局性调用

在浏览器中,window 就是该全局对象为 [object Window]:

在node中,指向的就是global对象

function myFunction() {  return this; }
  • 事件中的 this

在 HTML 事件句柄中,this 指向了接收事件的 HTML 元素:

<button onclick="this.style.display='none'"> 点我后我就消失了 </button>

显示数据绑定:修改this指向对象

在 JavaScript 中函数也是对象,对象则有方法,apply 和 call 就是函数对象的方法。这两个方法异常强大,他们允许切换函数执行的上下文环境(context),即 this 绑定的对象。

  • call
  • apply

(详细见函数调用)

函数调用

  • 函数名(实参列表);

  • 函数名.call(执行环境对象,实参列表);

  • 函数名.apply(执行环境对象,实参列表数组);

  • 函数名.bind(执行环境对象)(实参列表);

 案例:

var obj = {
  name: 'taylor',
  sayName: function () {
    console.log(this.name);
  }
}
var b = obj.sayName;
b(); //undefined
obj.sayName(); // taylor

我们无法直接让b() 指向obj中的方法,那么可以使用以下的方法:

1.call(执行环境对象,实参列表);

调用call方法时,第一个参数是要把b添加到的环境,简单来说,就是this要指向的那个对象。

var obj = {
  name: 'taylor',
  sayName: function () {
    console.log(this.name);
  }
}
var b = obj.sayName;
b.call(obj); // taylor

在call方法中也可以传递多个参数

var obj = {
  name: 'taylor',
  sayName: function (a, b) {
    console.log(this.name);
    console.log(a, b);  // 1, 2
  }
}
var b = obj.sayName;
b.call(obj, 1, 2); // taylor

2.apply(执行环境对象,实参列表); 

与call的用法相似,都可以改变this指向。

不同的是,如果要传递多个参数,则第二个参数必须为一个数组。

用例就不再赘述。

call与apply的总结:

这两个方法中的第一个参数若为null,则this在node环境下指向的是global对象,在HTML中指向的是window对象。

3.bind(执行环境对象)(实参列表);

案例:

可以看到代码没有被打印,这就是bind和call、apply方法的不同,因为实际上bind方法返回的是一个修改过后的函数

我们需要新建一个变量来接收bind修改过后的函数 

同样bind也可以有多个参数,并且参数可以执行的时候再次添加,但是要注意的是,参数是按照形参的顺序进行的。

 

总结:call和apply都是改变上下文中的this并立即执行这个函数,bind方法可以让对应的函数想什么时候调就什么时候调用,并且可以将参数在执行的时候添加,这是它们的区别,根据自己的实际情况来选择使用。

 函数应用

*回调函数

作用:回调函数一般都用在耗时操作上面:因为主函数不用等待回调函数执行完,可以接着执行自己的代码。比如ajax请求,比如处理文件等。

 回调地狱

常见于异步操作网络请求,如果出现多个网络请求必须同时执行的场景,代码就会变得特别复杂。

回调地狱就是在一个回调函数里面不断触发下一个,下下一个……

解决方法:可以使用promise对象来解决回调地狱的问题(ES6提供的对象)

* 作为返回值

var a = 10
function fn() {
  var b = 20
  function bar() {
    console.log(a + b) //30
  }
  return bar
}
var x = fn(), // 执行fn() 返回的是bar
b = 200  // 实际上不起作用
x() //执行x,就是执行bar函数

上例中形成闭包。之后再详细介绍

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值