js函数的理解和使用(不全)

函数的分类

普通函数

// 声明式创建函数
function f1(){
	console.log("welcome to my blog");
}
// 声明式创建函数的执行
f1(); // welcome to my blog

// 赋值式创建函数
var f2 = function(){
	console.log("thumbs up");
}
// 赋值式创建函数的执行
f2(); // thumbs up

构造函数

  • 一般使用new关键字来调用构造函数
var obj = new Object();

递归函数

钩子函数

箭头函数

尾调函数

匿名函数

  • 在使用匿名函数之前,必须先进行赋值操作,否则将会引起错误。
作为变量的“值”存在
var fn = function(){
	console.log("collection");
}
fn(); // collection

作为“值”存在,fn确实是函数名,但是它的值function(){}确实也是一个无名函数的形式。
作为事件处理函数执行
document.onclick = function(){
	alert("comments"); // 点击页面的时候弹出comments
}

当有绑定的事件类型被触发时,执行这里的代码
作为函数的参数使用(回调函数)
function fn(cb){
	cb(); // 用cb来接收,并且执行,打印 subscribe
}
fn(function(){ // 执行fn的时候传入一个为函数的参数
	console.log("subscribe");
});

当一个函数的参数又是一个函数时,这个作为参数的函数叫回调函数
作为函数的返回值使用
var fn(){
	return function(){
		console.log("thanks for watching");
	}
}
var f = fn(); // 执行fn的时候得到了返回值,这个返回值就是无名函数
f(); // 执行无名函数,打印 thanks for watching

在一个函数内部,嵌套了另一个函数,此时就形成了闭包
作为匿名函数的函数体
;(function (){
	console.log("thumbs up");
})(); // 匿名函数是自动执行的,打印 thumbs up

在匿名函数之前的语句必须加上";",js中不能识别换行

函数的定义

函数声明

  • 结构
function 函数名(形参){
	方法体
	return 返回值
	}
  • 在JS中函数的声明会被提升,即在运行前函数会先被声明,所以可以在代码中可以在函数声明之前调用函数而不会报错。
  • 示例
add(1,2);
function add(a,b){
	var total = a + b;
	return total;
	}
var aaa=new add();

函数表达式

  • 结构
var 函数名 = function(){};
  • 示例
add();
var add = function(a,b){
return a+b
};

函数的真实执行顺序
var add;
add();
add = function(a,b){return a+b};
  • 理解
    var声明的变量会被提升,此时的函数视为赋值给add,所以不会被提升,add这时候的值是undefined,所以执行undefined();会报错。

函数的属性和对象

arguments

  • 有传入函数中所有的参数,相当于可以传递不定长参数,主要用途是保存函数参数
  • 示例
function test(){
    for(i = 0;i < arguments.length;i++){
        console.log(arguments[i]);
    }
}
test("Tom","jerry","asl");//控制台输出:Tom jerry asl
test("Tom","jerry");//控制台输出:Tom jerry

callee

  • 该属性是一个指针,指向拥有这个arguments对象的函数。
  • 示例
function box(num) {
  if (num <= 1) {
    return 1;
  } else {
    return num * box(num-1); //一个简单的的递归
  }
}

对于阶乘函数一般要用到递归算法,所以函数内部一定会调用自身;如果函数名不改变是没有问题的,但一旦改变函数名,内部的自身调用需要逐一修改。

function box(num) {
  if (num <= 1) {
    return 1;
  } else {
    return num * arguments.callee(num-1);//使用callee来执行自身
  }
}

this

  • this引用的是函数据以执行操作的对象,或者说函数调用语句所处的那个作用域;当在全局作用域中调用函数时,this对象引用的就是window。
  • 示例
function add(x,y){
    console.log(this);//window
}    
add();
function add(x,y){
    'use strict';
    console.log(this);//undefined
}    
add();//window

'this’可以用来判断当前是否是严格模式

var strict = (function(){
return !this;
}());
  • 方法可以使用this访问自己所属的对象,所以它能从对象中取值或对对象进行修改。this到对象的绑定发生在调用的时候。通过this可取得它们所属对象的上下文的方法称为公共方法
var o = {
    a: 1,
    m: function(){
        return this;
    },
    n: function(){
        this.a = 2;
    }
};
console.log(o.m().a);//1
o.n();
console.log(o.m().a);//2
  • 因为函数调用模式的函数中的this绑定到全局对象,所以会发生全局属性被重写的现象
var a = 0;
function fn(){
    this.a = 1;
}
fn();
console.log(this,this.a,a);//window 1 1

length

  • length属性表示函数希望接收的命名参数的个数。
  • 示例
function box(name, age) {
  alert(name + age);
}
alert(box.length); //2

prototype(原型)

  • prototype下有两个方法:apply()和call(),每个函数都包含这两个非继承而来的方法。这两个方法的用途都在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。
  • 示例
function box(num1, num2) {
  return num1 + num2; //原函数
}
function sayBox(num1, num2) {
  return box.apply(this, [num1, num2]); //this表示作用域,这里是window
} //[]表示box所需要的参数
function sayBox2(num1, num2) {
  return box.apply(this, arguments); //arguments对象表示box所需要的参数
}
 
alert(sayBox(10,10)); //20
alert(sayBox2(10,10)); //20
  • call()方法于apply()方法相同,他们的区别仅仅在于接收参数的方式不同。对于call()方法而言,第一个参数是作用域,没有变化,变化只是其余的参数都是直接传递给函数的。
function box(num1, num2) {
  return num1 + num2;
}
function callBox(num1, num2) {
  return box.call(this, num1, num2); //和apply区别在于后面的传参
}
alert(callBox(10,10));

传递参数并不是apply()和call()方法真正的用武之地;它们经常使用的地方是能够扩展函数赖以运行的作用域。

var color = '红色的'; //或者window.color = '红色的';也行
var box = {
  color : '蓝色的'
};
function sayColor() {
  alert(this.color);
}
sayColor(); //作用域在window
sayColor.call(this); //作用域在window
sayColor.call(window); //作用域在window
sayColor.call(box); //作用域在box,对象冒充

使用call()或者apply()来扩充作用域的最大好处,就是对象不需要与方法发生任何耦合关系(耦合,就是互相关联的意思,扩展和维护会发生连锁反应)。也就是说,box对象和sayColor()方法之间不会有多余的关联操作,比如 box.sayColor = sayColor;

函数的调用

函数调用

  1. 普通的函数调用来说,函数的返回值就是调用表达式的值
  • 当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用的
function add(x,y){
    return x+y;
}
var sum = add(3,4);
console.log(sum)//7
  1. 非严格模式下,this被绑定到全局对象;在严格模式下,this是undefined

  2. this绑定到全局对象,所以会发生全局属性被重写的现象

方法调用

  1. 当一个函数被保存为对象的一个属性时,我们称它为一个方法。当一个方法被调用时,this被绑定到该对象。如果调用表达式包含一个提取属性的动作,那么它就是被当做一个方法来调用
var o = {
    m: function(){
        console.log(1);
    }
};
o.m();//1
  1. 方法可以使用this访问自己所属的对象,所以它能从对象中取值或对对象进行修改。this到对象的绑定发生在调用的时候。通过this可取得它们所属对象的上下文的方法称为公共方法
var o = {
    a: 1,
    m: function(){
        return this;
    },
    n: function(){
        this.a = 2;
    }
};
console.log(o.m().a);//1
o.n();
console.log(o.m().a);//2
  1. 如果想访问这个外部函数的this值,需要将this的值保存在一个变量里,这个变量和内部函数都同在一个作用域内。通常使用变量self或that来保存this
var o = {
    m: function(){
        var self = this;
        console.log(this === o);//true
         function n(){
             console.log(this === o);//false
             console.log(self === o);//true
             return self;
         }
         return n();
    }
}
console.log(o.m() === o);//true

构造器调用

  1. 如果函数或者方法调用之前带有关键字new,它就构成构造函数调用
function fn(){
    this.a = 1;
};
var obj = new fn();
console.log(obj.a);//1
  1. 如果构造函数调用在圆括号内包含一组实参列表,先计算这些实参表达式,然后传入函数内
  2. 如果构造函数没有形参,javascript构造函数调用的语法是允许省略实参列表和圆括号的。凡是没有形参的构造函数调用都可以省略圆括号
  3. [注意]尽管构造函数看起来像一个方法调用,它依然会使用这个新对象作为调用上下文。也就是说,在表达式new o.m()中,调用上下文并不是o
  4. 构造函数通常不使用return关键字,它们通常初始化新对象,当构造函数的函数体执行完毕时,它会显式返回。在这种情况下,构造函数调用表达式的计算结果就是这个新对象的值
  5. 如果构造函数使用return语句但没有指定返回值,或者返回一个原始值,那么这时将忽略返回值,同时使用这个新对象作为调用结果
  6. 如果构造函数显式地使用return语句返回一个对象,那么调用表达式的值就是这个对象

间接调用

函数的注意点

1、函数是一种封装,要使用它需要调用,本身不会自动执行;
2、函数的定义顺序和调用顺序无关,函数优先于所有代码执行;
3、函数可以有参数也可以没有。函数的参数分为形参(函数定义时的参数)、实参(函数调用时的参数);函数的参数理论上有无限个,每个参数之间用逗号隔开,参数的类型不限。
4、函数可以有返回值也可以没有;函数的返回值可以用 (return +返回值;)返回;例如要返回变量a,可以:return a; 返回a变量;return语句不仅有返回结果的作用,还有结束函数的作用;注意,一个函数的返回值只有一个;finally语句除外
5、在JavaScript中没有重载函数。也就是说函数如果重名会被覆盖。
6、函数不能作比较。
7、函数可以作为参数、返回值。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值