一、函数
在Javascript中,万物皆对象。
JS中对象大致可以分为两类,即:普通对象Object 和 函数对象Function。
一般而言,通过new Function产生的对象是函数对象,其他对象都是普通对象。
1.1 函数概念
1) 函数是一组执行特定任务的代码块。函数分为构造函数和普通函数。
普通函数用于方法调用。 而构造函数用于创建对象。
2) 使用typeof检查一个函数对象时,会返回function
3) 函数是对象。但并不能说对象是函数,只能说Function的实例对象是函数。
在JS中,函数是Function类型的实例,所以说函数是对象。
但并不能说是对象是函数,只能说是Function的实例对象是函数。
>>>>>> 函数分为构造函数和普通函数。在调用时执行代码
//普通函数
function s(){
alert("123");
}
s(); //普通函数是在调用时执行代码
//构造函数
function Saas(){
this.name=12;
alert("123");
}
var sss=new Saas(); //构造函数是在创建对象时执行代码
>>>>>> 普通函数用于方法调用。 构造函数用于创建对象。
function s(a,b){
var ss=a+b;
return ss;
}
function Stu(a,b){
this.age=a;
this.name=b;
this.say=function(){
alert("123")
}
}
var obj=new Stu(1,2);
>>>>>> 函数是对象。但并不能说对象是函数,只能说Function的实例对象是函数。
//函数是Function的实例,所以说函数是对象
function s(){}
var ss=new Function("return 1");
console.log( s instanceof Function); //true
console.log( ss instanceof Function) //true
//对象不是函数
var c=new Object();
console.log( c instanceof Function) //false
1.2 构造函数与普通函数的区别
构造函数和普通函数创建方式是一样的,在本质上没什么区别。
只是我们根据函数的作用来人为的区划分,以便于理解。
1.函数名称书写不同
构造函数就是普通函数,创建方式一样。不同的是构造函数一般首字母大写。
3.调用方式不同
普通函数直接调用,调用后直接执行代码。
而构造函数需要使用new关键字来调用,调用后直接执行代码。
4.作用不同
普通函数用于方法调用。构造函数用于创建对象。
5.函数中this的指向不同
普通函数中的this,在严格模式下指向undefined,非严格模式下指向window对象。
构造函数的this则是指向它创建的对象实例。
>>>>>> 函数名称书写不同
//普通函数
function book(){
alert("123");
}
//构造函数
function Book(){
alert("123");
}
>>>>>> this指向不同
//普通函数
function book(){
console.log("普通函数:"+this)
}
book(); //普通函数中的this,在严格模式下指向undefined,非严格模式下指向window对象。
//构造函数
function Book(){
this.name="hlp";
this.age=12;
console.log("构造函数:"+this)
}
var s=new Book(); //构造函数的this则是指向它创建的对象实例。
>>>>>> 作用不同
//普通函数
function book(){
alert("123");
}
book(); //方法调用
//构造函数
function Book(){
alert("123");
}
var s=new Book(); //创建对象
>>>>>> 调用方式不同。调用后直接执行代码
普通函数调用
function s(){
console.log("1")
}
s();
构造函数调用,创建对象。调用后直接执行代码
function s(){
console.log("1")
}
var obj=new s();
1.3 JS常见的内置函数
1)JS内置了一些普通函数,比如parseInt、parseFloat等。
2)JS内置了一些构造函数,比如Object、Function、Array、Date、Number ...
>>>>>> JS内置的普通函数
console.log(typeof parseInt); //function
console.log(typeof parseFloat); //function
console.log(typeof alert); //function
>>>>>> JS内置的构造函数
console.log(typeof Number); //function
console.log(typeof Boolean); //function
console.log(typeof Object); //function
console.log(typeof Function); //function
二、创建函数
2.1 创建函数
1)函数声明
function calSum1(num1, num2) {
return num1 + num2;
}
console.log(calSum1(10, 10));
2)函数表达式
函数实际上是一个匿名函数。
函数存储在变量中,不需要函数名称,通常通过变量名来调用。
var calSum2 = function (num1, num2) {
return num1 + num2;
}
console.log(calSum2(10, 20));
3)基于Function构造函数创建一个函数
var calSum3 = new Function('num1', 'num2', 'return num1 + num2');
console.log(calSum3(10, 30));
4)匿名函数
>>>>>> 匿名函数
+++ 创建匿名函数
(function(a,b){
return a+b;
})
+++ 匿名函数调用(也被称为立即执行函数)
(function(a,b){
return a+b;
})(1,2)
>>>>>> 匿名函数作为实参传递
function a(s){
s();
}
a(function(){alert("123")})
5)ES6新增箭头函数
1、ES6新增箭头函数: 箭头函数表达式的语法比普通函数表达式更简洁。
2、箭头函数创建后不会执行。
2、箭头函数相当于匿名函数。创建后必须要使用变量接收。否则无法执行。
ES6箭头函数:
(参数1, 参数2, …, 参数N) => { 函数代码 }
ES6箭头函数简写:
1) 只有一个函数代码时
// 相当于:(参数1, 参数2, …, 参数N) =>{ return 表达式; }
(参数1, 参数2, …, 参数N) => 表达式(单一)
2) 只有一个参数时
//(单一参数) => {函数声明}
单一参数 => {函数声明}
3) 没有参数
() => {函数声明}
>>>>>> 箭头表达式的创建
//箭头函数完整写法
(a,b,c)=>{
var s=a+b+c;
console.log(s)
}
//只有一个参数时(箭头函数简写)
a=>{
console.log(a);
}
//只有一个代码时(箭头函数简写)
(a,b)=> a+b;
>>>>>> 箭头表达式的调用
//箭头函数
var ff=(a,b,c)=>{
var s=a+b+c;
console.log(s)
}
//普通函数
function ff2(a,b,c){
var s=a+b+c;
console.log(s)
}
>>>>>> 箭头函数中的this指向的是window
var x=()=>{
alert(this)
}
x();
2.2 创建函数注意事项
1)函数参数
1. 定义形参时,不能使用var。
2. 调用函数时,解析器不会检查形参的数量。所以传多个参数不会报错。
3. 调用函数时,函数不定义形参,也可以传入参数。
>>>>>> 定义形参时,不能使用var关键字。
<script type="text/javascript">
function add(a,b){
var c=a+b;
document.write(c);
}
add(11,12)
</script>
>>>>>> 调用函数时,参数可以随机传。
function s(){
console.log("1")
}
s();
s(1,2,3);
s(1,2,3,4)
>>>>>> 调用函数时,函数不定义形参也可以出传入参数
function s(){
console.log(arguments[0]);
console.log(arguments[1]);
console.log(arguments[2]);
}
s(1,2,3);
s(1,2,3,4);
2)函数返回值
1.return可以将函数的执行结果返回。并定义个一个变量来接受。
2.return后面的语句不会执行。
3.如果函数中没有return或者return后面没有任何值,就相当于返回一个undefined。
>>>>>> return后面的语句不会执行
function s(){
console.log("1");
return 1;
alert("123"); //不会执行
}
s();
>>>>>> 如果函数中没有return或者return后面没有任何值,就相当于返回一个undefined。
function s1(){
console.log("1");
return ;
}
function s2(){
console.log("1");
}
var a=s1();
var b=s2();
console.log(a);
console.log(b);
3)函数的实参、返回值、属性值可以是任意数据类型。也可以是一个函数。
1. 实参可以是任意数据类型。也可以是一个函数或对象。
2. 返回值可以是任意数据类型,也可以是一个函数或对象。
3. 函数的属性值可以任意数据类型,也可以是一个函数或对象。
>>>>>> 实参可以是任意数据类型。也可以是函数。
function sayHello(){
console.log("我叫hlp")
}
function funA(a){
a();
}
funA(sayHello);
>>>>>> 返回值可以是任意数据类型。也可以是函数。
function a(){
console.log("213");
function s(){
alert("213");
}
return s;
}
var ss=a();
ss();
a()();
>>>>>> 函数的属性值可以是任意数据类型,也可以是函数。
function c(){
this.name='123';
this.hobby=["123","123"];
this.says={"a":123,"b":123,"c":123},
this.sayss=function(){
alert("123");
}
}
var s=new c();
s.sayss();
4)其他注意事项
1. JS没有方法重载的概念,后定义的同名函数会覆盖前面的同名函数。
2. 函数中也可以定义函数。
>>>>>> JS没有方法重载的概念,后定义的同名函数会覆盖前面的同名函数。
<script type="text/javascript">
function add(a,b){
var c=a+b;
return c;
}
function add(a,b,c){
var m=a+b+c;
return m;
}
var b=add(11,12);
document.write("add(a,b):"+b+ "<br/>")
var b2=add(11,12,13);
document.write("add(a,b,c):"+b2)
</script>
>>>>>> 函数中也可以定义函数
var s=function(){
function c(){
alert("123");
}
c();
}
s();
>>>>>> 函数实质上也是由一个变量指定
function s(){
console.log("123")
}
//s变量指向函数
console.log(s);
>>>>>> 函数声明本质上创建函数对象
function ss(){
console.log("123")
}
//等价于
var ss=new Function("...")
三、操作函数
3.1 fun()基础操作
1. 创建的函数最终会被一个变量所引用。这个变量也被称为函数对象。
2. 创建的函数不会执行。而是在调用时才会执行代码。
3. 函数声明创建的函数会被提升。函数可以在函数声明之前调用。
4. 函数本身也是一个对象。所以对象的操作方式也适用于函数。
>>>>>> 创建的函数最终会被一个变量所引用。这个变量也被称为函数对象。
//变量s为函数对象
function s(){
console.log("1")
}
//变量s1为函数对象
var s1=function (){
console.log("1")
}
//变量s2为函数对象
var s2 = new Function('num1', 'num2', 'return num1 + num2');
>>>>>> 创建的函数不会执行,而是在调用时才会执行
//创建函数不会执行
function s(){
console.log("1")
}
s(); //函数调用时执行
var ss=new s(); //使用函数创建对象时执行。
>>>>>> 函数声明创建的函数会被提升。函数调用可以在函数声明前执行。
myFunction(5);
function myFunction(y) {
return y * y;
}
>>>>>> 函数本身也是一个对象。所以对象的操作方式也适用于函数。
function s(){
alert("23");
}
s["123"]=12;
s.sss=13;
console.log(s["123"]);
console.log(s.sss);
delete s.sss;
console.log(s.sss);
3.2 fun()调用
//函数基本调用
function ss(){
console.log("123")
}
ss();
//函数基本调用
var ss=function(){
console.log("123")
}
ss();
//匿名函数基本调用
(function(){
console.log("123")
})();
//函数的特殊调用
var obj={
"a":["1",1,console.log],
"b":function(){
return function(){
console.log("abc")
}
}
}
obj.a[2]("123");//相当于调用 console.log("!23")
obj.b()();
3.3 call()、apply()
fun2.call([obj],[args])
fun2.apply([obj],[arr])
1、这两个方法是函数对象的方法。所以需要通过函数对象来调用。
2、通过函数对象调用这两个方法,就会调用函数执行。
fun2.apply() //相当于fun2();
fun2.call(); //相当于fun2()
3、通过函数对象调用这两个方法,可以传入实参。
- 第一个参数是对象,可选。
该对象会被设置到函数中的this对象中。
如果不传,默认为window。
- 第二个参数是可变参数,可选。
传入函数的参数。
切记:call传入实参和apply传入实参方式不同。
4、这两个方法实质上和JAVA中methods.invoke(obj, args)类似。
>>>>>> 通过函数对象调用这两个方法,就会调用函数执行
function s(){
console.log("!")
}
s.call(); // 相当于 s()
s.apply(); // 相当于 s()
>>>>>> 通过函数对象调用这两个方法,可以传入一个对象设置到this对象中
function s(){
console.log(this.name);
}
var obj={
'name':'hlp'
}
s.call(obj); // 函数s中this指向obj对象
s.apply(obj); // 函数s中this指向obj对象
>>>>>> 通过函数对象调用这两个方法,可以传入实参设置到函数的形参中
function s(a,b){
console.log('this指向:'+this);
console.log(a+b);
}
var obj={'name':'zz'}
s.call(obj,2,10); //call方法传入实参,直接传入即可
s.apply(obj,[2,10]); //apply方法传入实参,需要传入一个数组。
四、回调函数
回调函数是由开发者自己定义的,但是由其他函数自己调用的。这种函数被称为回调函数。
1、DOM事件回调函数
2、定时器回调函数
3、ajax请求回调函数