整理下Javascript的函数

函数的声明方法

1.函数声明

function f(){}

函数声明优先级大于变量提升

function a(){
   return b;
   b=10;
   function b(){}
   var b=11}

console.log(typeof a())

答案:function
解析:考察[函数提升]优先级>[变量提升]
return后面的不执行

function a(){
  function b(){}
   return b;
   b=10;
   var b=11}

2.函数表达式
创建了一个匿名函数,没有函数提升,但得注意变量提升

var f = function (){}

注意:函数表达式定义的函数,函数名外部无法引用,如下:

  1.  var fn = function f(){};
      console.log(typeof f);  //打印undefined,函数表达式的函数名f在外部是访问不到的
   2. if(function f(){}){
        console.log(typeof f);  //同理,打印undefined,if语句中的函数解析为函数表达式,函数名f在外部是访问不到的
      }

作者:zh2443
链接:https://www.jianshu.com/p/5304f4196d2c
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

3.构造函数

function Person( name){
       this.name =name;
     }
      var Fsskay=new Person('Fss');
      console.log(Fsskay.name) //Fss

构造函数的this指向window

函数的作用域

函数内部可以读取外部变量(作用域链由内往外)[例子f3],外部不能读取函数内的局部变量[例子f1]
函数内部声明var会变量提升[例子f1],函数内部的函数声明会函数提升
函数内部声明变量不用var,会修改外部变量[例子f3]

var v = 1;

function f1(){
	console.log(v,'v1')//undefined,因为内部变量提升var a
  	var v = 2;
  	console.log(v,'v2');//2
}
console.log(v)//1

function f2(){
	console.log(v,'v3') //1 读取的全局变量
}
分割线------------------------------------------------------------------
function f3(){
	v=3
};
f3()  //执行下f3
console.log(v,'全局的那个v')//3

函数本身也是一个值,也有自己的作用域。它的作用域与变量一样,就是其声明时所在的作用域,与其运行时所在的作用域无关。
例子

var a = 1;
var x = function () {
  console.log(a);
};
function f() {
  var a = 2;
  x();
}
f() // 1

考题:

  var a =3;
  var b={
   a:2,
   b:{
     a:1,
     c:function(){ 
           return this.a
        }
      }
    }
var test = b.b.c;

console.log(test())
console.log(b.b.c())
答案://3
     //1
解析:考察浅拷贝与this的指向,考察 函数作用域是在声明时候的作用域
test=b.b.c ,test=f(){ return this.a},test()所在的作用域是全局window,window下的a=3,所以第一个是3
b.b.c()this就是c所在的对象b下的a,所以this.a是a=1

函数的闭包

什么是闭包? 让外部读取函数内部变量
怎么做? 函数1内再给一个函数2,返回这个函数2的结果

 function f1(){
	var n=1
	function f2(){
	console.log(n)
	}
	return  f2()
}

// 1

有什么用?
1.外部函数访问内部函数作用域,减少使用全局变量
2.内部变量不垃圾回收,占内存

立即执行函数(自执行函数)

是什么?函数创建后立即执行,本质上是函数表达式(具名或匿名的)
怎么做?

(function(){})
(function(){})();
!function(){}();
+function(){}();
-function(){}();
~function(){}();

有什么用?
1.封装私有变量,外部读取不到内部函数
2.一种函数的调用方式,调用后垃圾回收,不占内存
3.只有表达式才能被执行,只执行一遍就自动销毁

递归

简单来说就是自己调用自己,递归需要设置结束条件

function f(n){
    if(n === 1){
        return 1
    }
    return n * f(n-1)
}
f(3)  //6

继承

细看可以看https://www.cnblogs.com/humin/p/4556820.html
大概记一下就是原型链继承prototype,构造函数继承,ES6 extends继承.

调用(call,apply,bind)

fn.call(this,参数列表) 立即调用
fn.apply(this.参数数组) 立即调用
fn.bind(this,参数列表) 之后调用
bind 方法返回值是函数以及 bind 接收的参数列表的使用。
bind 方法不会立即执行,而是返回一个改变了上下文 this 后的函数。

参数的使用
function fn(a, b, c){
console.log(a, b, c);
}

var fn1 = fn.bind(null, '123');
fn('A', 'B', 'C');       // A B C
fn1('A', 'B', 'C');     // 123 A B
fn1('B', 'C');           // 123 B C
fn.call(null, '123');   // 123 undefined undefined    call 是把第二个及以后的参数作为 fn 方法的实参传进去,而 fn1 方法的实参则是在 bind 中参数中的基础上再往后排

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