学习ES6(四):函数进阶(1)

函数进阶

基本概念:一段javascript代码,定义一次,执行或调用任意次。

  • 函数定义会包括形参,这些参数会在函数体中类似于局部变量。
  • 函数调用会为形参提供实参值
  • 函数结构体无return语句,默认undefined
  • 除实参外,每次调用还会拥有this关键字值,即本次调用的上下文。

函数的定义方式有四种:

其中,函数声明语法存在函数提升,类似于变量提升,将函数名提升在最上面。调用的时候会在全局找对应的函数体。但是函数表达式不可以,必须在定义函数后才可以使用。

  • 1,函数声明语法:
function definition(param1,params2){
     
	function body
}
  • 2,函数表达式
let functionName = function(param1,param2){
     
	return xxx
}
  • 3,箭头函数(这是es6的一个语法糖,为了让我们更加方便地定义函数)
let mul = (param1,param2) => param1*param2; // mul(1,2)调用、返回2
let mul = (param1,param2) => {
     
	return param1*param2
}
let f1 = () =>{
     // f1()调用
	console.log("arrow function")
}
let f2 = x => x**2;// f2(2)调用
let xx = ((x) => x**x)(4)//立即执行函数,x的值为4,输出256
  • 4,Function构造函数(不推荐使用,因为这段代码会被执行两次,影响性能)
let sum = new Function(){
     
	"num1",
	"num2",
	"let result+=num1+num2;return result;"
}

函数调用的四种方式

  • 1,作为函数来调用
如:sum(1,2,3+3,getnum())

在一个函数的调用中,每个参数表达式都会计算出一个值,计算的结果作为参数传递给另外一个函数。如果该函数返回是因为解释器到达结尾,那么该函数返回的值就是undefined。如果函数返回是因为函数执行到一条return语句,返回值就是return后面的表达式,如果只有return,没有表达式,那么返回undefined。所以函数有开始就应该有个结束。

  • 2,作为方法来调用
  • 对象的函数称为方法,都是函数,不过是将函数赋予某个特定的对象来执行,这个对象就可以叫做函数调用的上下文,也就是this。
let call = {
     
	calling:function(){
     
		console.log(" I'am iron man ")
	}
}

由于方法是某个特定对象调用的函数,所以一定要在方法调用前加上对象名和符号 ’ . ’ ,这样才能标志这个函数是属于哪个对象的专属方法。如果你不加对象名,它就会报 calling is not defined,私人的东西别人是用不了的,所以报错没有定义。

函数在调用时,由于this没有作用域限制,所以在函数嵌套函数的时候,嵌套的函数不会从调用它的函数中继承上个函数体中的this。举例如下:

let obj = {
     
	x:10,
	fn:function(){
     
		this.x++;
		function ff(){
     
			console.log(this.x)
		}
		ff()
	}
}
obj.fn()

我们在调用的fn函数中,嵌套ff函数,在执行时先执行fn函数,将x的值+1,这个时候可以使用this.x来访问,因为obj是函数fn的直接调用对象,fn函数中的this=>obj,在fn中调用ff,这个时候ffthis就指向的是全局了,因为它没有直接对象来调用它,如果在浏览器中,这个this就是window,如果在node环境中,这个this就是global了。

那么如何处理这个问题呢。我们可以将fn中的this保存为一个变量,利用该中间件,在嵌套函数中使用,操作,也就间接地利用了同一个this

  • 3,作为构造函数来调用
    如果函数或方法在调用之前有关键字new,那么它就是构造函数调用。
    在构造函数中,构造函数调用会创建一个新的空对象,这个对象继承自构造函数的prototype属性。
    构造函数可以使用this关键字来引用这个新创建的对象。
function Car(name) {
     
			console.log(this)//Car{}
            this.name = name;
            return null;
          }
Car("tom") //null
new Car("tom") //object

构造函数在我们生活中是非常常见的,比如Array、Number、String等等。

  • 4,通过它们的call() 和 apply()方法间接调用()
    这个场景是在没有使用ES6的扩展操作符的基础上才使用的。
    比如我们想向函数调用传递多个参数,那么函数形参如何接受呢?
    当我们没有方法可以使用时,我们可以利用别人已有的方法去执行我们想要的过程,这个手段叫做间接调用
    比如以下代码-------obj1拥有一个 add 方法,但是,obj2没有这个方法,但是obj2可以使用call()方法来间接调用。并且在调用期间,这个函数的调用上下文是obj2,因为是借用了obj1的方法,然后将主角换成了自己。
    如果obj1方法需要参数,那么可以在call的实参中加入参数相应赋值。
	let obj1 = {
     
        x:1,
        y:2,
        add:function(m=1,n=1){
     
            return this.x*m+this.y*n
        }
    }
    console.log(obj1.add())// 这是obj1自己调用自己的函数
    let obj2 = {
     
        x:2,
        y:3
    }
    console.log(obj1.add.call(obj2))//这是obj2利用了obj1的方法。返回5
    console.log(obj1.add.call(obj2,100,1))//将100赋值给m,1赋值给n,x,y还是obj2自己的。

你可能感兴趣的:(es6,前端,javascript)