JavaScript函数(二)

目次

1.函数的声明

2.函数的属性和要领

3.函数的作用域

4.闭包知识点

5.小结

关于函数,可以从以下3个方面去明白:
起首,数据类型上看:函数在JavaScript中是一种数据类型,是对象的一种;
其次,从功能上看:函数本质上是一段重复挪用的代码块;
末了,从职位上看:函数在JavaScript中和其他基础数据类型一样,可以作为参数和赋值,是“第一等国民”

1.函数的声明

声明函数的体式格局有三种:

1.声明式
function fn(){
  console.log(1)
}
fn()//1
2.表达式
var fn = function(args){
    console.log(args)
}
fn(a)//a
3.组织函数式
var fn =  new Function("arg1","arg2","return arg1+arg2")
fn(1,2)//3

函数本质上是对象的一种,所以函数名保留的实际上是指向函数对象的指针,第3种组织函数的要领关于明白“函数是对象,函数名是指针”的观点越发直观,然则第3种要领剖析效力较低而且誊写不简约,所以平常不必组织函数要领去声明函数;
当声明式和表达式同时声明同一个函数时,表达式会掩盖声明式,原因是函数作为变量在js剖析阶段举行变量提拔,声明式和表达式都邑提拔至当前作用域头部,然后表达式会从新为fn赋值,从而掩盖声明式定义的函数;

function fn(){
  console.log(1)
}
var fn = function(){
  console.log(2)
}
fn()//2

关于return语句的明白,假如声明的函数没有return语句,则默许return undefined,不然返回定义的值;

var a  = function(){
    console.log(1)
}
var b = function(){
    return 2;
}
a() === undefined//true

《JavaScript函数(二)》

2.函数的属性和要领

函数作为一个对象,一样具有属性和要领,下面主要归结一下比较经常运用和主要的属性和要领:
《JavaScript函数(二)》

  • name属性:返回该函数名的字符串;

  • length属性:返回形参的个数,即预期传入参数的个数;

function fn (a,b){
    console.log(fn.name)
    console.log(fn.length)
}
fn()
//"fn"  
//2
  • arguments对象:是包括传入函数实参的类数组对象,只要在函数实行阶段而且存在参数才会有值,未挪用函数是为null

function fn (a,b){
  console.log(arguments)
}
fn(1,2)
//[1,2]

《JavaScript函数(二)》
arguments对象的length属性代表实参的个数,注重和函数的length属性的区分,函数的length代表形参的个数,arguments的length属性代表实参个数;
arguments对象有一个callee属性,返回arguments对象地点的函数指针
《JavaScript函数(二)》
可以应用callee完成函数的递归,比方累加或阶乘操纵:

function increment(arg){
  if(arg === 1){
    return 1
  }
  return arg+arguments.callee(arg-1)
}
function increMultipler(arg){
  if(arg === 1){
    return 1
  }
  return arg*arguments.callee(arg-1)
}

《JavaScript函数(二)》
这里别的提一个函数的caller属性,该属性保留挪用当前函数的函数的援用,注重的是假如在全局作用域下读取该属性,值为null,由于顶层对象在浏览器中为window不是函数;

function outer(){
  inner();
}
function inner(){
  console.log(arguments.callee.caller)
}
outer();

《JavaScript函数(二)》

  • this对象:代表函数实行时的环境对象,简朴的说就是谁挪用了该函数,this的指向是动态的,只要在函数挪用时this对象才肯定;

//在浏览器全局环境下,即window对象下
var print = function(){
      console.log(this)
 }
print()//this指向Window,由于这是Window对象挪用了print要领
//在特定对象的环境下
var o = {
    print: function(){
      console.log(this)
  }
}
o.print()//this指向o,由于这是o对象挪用print要领

函数供应callapplybind3种要领可以转变this对象;

1.call要领
function fn(){
    return this
}
var o = {}
fn() === this//true,this指向window对象
fn.call(o) === o//true,this指向o对象
//call要领还可以传入参数;
function add(x,y){
  return x+y
}
add.call(null,1,2)
2.apply要领,与call差别的是apply传入的参数为数组
var arr = [1,2]
function add(x,y){
  return x+y
}
add.apply(null,arr)

实际上,apply和call的区分只在于通报参数的差别,它们真正壮大的处所在于可以扩大函数赖以运转的作用域,比方slice函数底本只存在于数组当中,当中经由过程运用call要领,可以完成差别作用域下挪用该要领;

function fn(a,b){
      console.log(Array.prototype.slice.call(arguments))
 }
fn(1,2)//[1,2]

bind要领会建立一个函数实例,并将该函数的this对象绑定到传入该要领的参数;

function fn(){
    return this
}
var o = {}
var newFn =fn.bind(o) 
newFn() === o//true

更多this的相干引见,详见【what’s this???】

3.函数的作用域

作用域指的是变量存在的局限,作用域可分为全局作用域和部分作用域,变量在全局局限可访问到;部分作用域由函数所组织,变量只能在函数内部可访问到;

var a =1//a处于全局作用域

function fn(){
   var a = 2//a处于部分作用域,外部无法访问;
  return a;
}
a//1
fn()//2

值的注重的是,函数实行时地点的作用域是定义时地点的作用域,而不是挪用时地点的作用域;

var a = 1;
function fn(){
  console.log(a)
}
function fn2(){
  var a = 2;
  fn()
}
fn2()//1

4. 闭包知识点

关于闭包的知识点,将会零丁开一章节详谈,详细请看《JavaScript闭包(三)》

5.小结

经由过程《JavaScript函数(二)》,我们大抵相识关于函数的知识点以下:

  • 函数本质上是一段重复挪用的代码块,是对象的一种,在js中作为“第一等国民”,可以赋值和传参;

  • 函数声明的要领有3种:声明式、表达式和组织函数式;个中组织函数是可以直观明白函数的“函数是对象,函数名是指针”的观点;当表达式和声明式同时声明同名函数时,表达式会掩盖声明式,原因是变量提拔的作用;

  • 函数作为对象,一样具有属性和要领;name返回该函数名的字符串,length返回形参的个数;

  • arguments对象是包括传入函数的实参的类数组对象,只要在实行阶段该对象才有值,未挪用函数时为null,arguments.length示意实参的个数,arguments.callee返回arguments对象地点的函数的指针;

  • 函数的caller返回挪用当前函数的函数的指针,在全局作用域下读取该属性为null;

  • this对象代表当前函数实行时的环境对象,this对象只要在函数实行阶段才肯定;

  • 可以运用call、apply和bind转变this的指向;call和apply的区分在于两者通报的参数差别,call为零星的数据,apply为数组,两者最大的用途是扩大函数的作用域;bind要领可以返回一个函数的实例,并绑定this对象至传入bind的参数;

  • 函数可以拓荒一个自力的作用域,这使得js当中典范的闭包得以完成供应可能性;另外,函数实行时地点的作用域是在定义时地点的作用域,而不是挪用时地点的作用域;

参考资料

    原文作者:teren
    原文地址: https://segmentfault.com/a/1190000007879466
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞