函数声明和函数调用

函数声明定义函数特点

  • 和变量的声明会前置一样,函数声明同样会前置,如果我们使用函数表达式那么规则和变量一样
  • 用函数声明的方式,重复定义函数,最后一次定义有效

函数实例化定义函数特点

  • 定义的函数只能访问本地作用域和全局作用域

变量前置

console.log(a)   //undefined
var a = 3    

==>等同于

var a
console.log(a)
a = 3

函数声明

console.log(sum(3,5))

function sum(a,b){
  return a + b
}

==>等同于
  

function sum(a,b){
  return a + b
}

console.log(sum(3,5))

函数表达式声明前置

fn()  //"TypeError: fn is not a function(不是一个函数)

var fn = function(){
  console.log('fn...')
}

==>


var fn
fn()

fn = function(){
  console.log('fn...')
}

立即执行函数

立即执行函数可以形成一个作用域,和全局隔开,不会污染全局,另一方面也是防止命名冲突的影响

(function(){
  console.log('我是立即执行函数')
})()

==>
  
var fn = function(){
  console.log('我是立即执行函数')
}
fn()

命名冲突

当在同一个作用域内定义了名字相同的变量和方法的话,会根据前置顺序产生覆盖

var fn = 3;
function fn(){}

console.log(fn); // 3

==>

var fn
function fn(){}  //覆盖上面的

fn = 3  //重新赋值
console.log(fn)

console.log(fn); // 3

function fn(){}
var fn = 3;

==>
function fn(){}  
var fn  //已经声明的值不会变

console.log(fn)  //fn(){}
fn = 3  

递归

简单来说就是自己调用自己

function factorial(n){
  if(n === 1){
    return 1
  }
  return n * factorial(n-1) 
}
alert(factorial(3))

//缺点:效率低

函数调用

  • 函数调用模式
    • 函数名()
  • 方法调用模式
var myNumber = {
 value: 1,
 add: function(i){
  console.log(this);
  this.value += i;
  }
}
myNumber.add(1);
  • 构造函数调用模式
    • new Function(...)首字母大写
  • apply(call)调用模式
    • apply是function构造函数原型上的构造方法
      • 实现函数借用的功能,把函数借用给对象

函数调用模式的区别-this

  • 函数调用模式
    • this指向window的全局对象
//例子:
function add(i,j){
  console.log(this);  //Window
  // console.log(arguments);
  var sum = i+j;
  console.log(sum);
  (function(){
    console.log(this);  //Window
  })()
  return sum;
}
add(1,2);
  • 方法调用模式
    • this指向调用者
//例子:
var myNumber = {
  value: 1,
  add: function(i){
    console.log(this);  //Object{value: 1, add: ƒ}
    this.value += i;
  }
}
myNumber.add(1);
  • 构造函数调用模式
    • this指向被构造的函数
//例子:
function Car(type,color){
  this.type = type;
  this.color = color;
  this.status = "stop";
  this.light = "off";
  console.log(this);  //打印结果是我们创建的对象
}
Car.prototype.start = function(){
  this.status = "driving";
  this.light = "on";
  console.log(this.type + " is " + this.status);
}
Car.prototype.stop = function(){
  this.status = "stop";
  this.light = "off";
  console.log(this.type + " is " + this.status);
}
var benz = new Car("benz", "black");  //Car {type: "benz", color: "black", status: "stop", light: "off"}
  • apply(call)调用模式
    • this指向第一个参数

函数传参

  • 原始类型按值传递-call by value
var count = 1;
var addOne = function(num) {
    num += 1;
    return num;
}
var ret = addOne(count);
console.log(ret);  //2
console.log(count);  //1结果没有受到影响
  • 对象类型按共享传递-call by sharing
//例子一:
var count = {a:1,b:1};
var addOne = function(obj) {
    obj.a += 1;
    obj.b += 1;
    return obj;
}
var ret = addOne(count);
console.log(ret);  //{a: 2, b: 2}
console.log(count);  //{a: 2, b: 2}

//例子二:
var count = {a:1,b:1};
var addOne = function(obj) {
    obj = {a:2, b:2};
    return obj;
}
var ret = addOne(count);
console.log(ret);  //{a: 2, b: 2} 
console.log(count);  //{a: 1, b: 1}
函数传参
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容