JavaScript 函数四种调用模式

函数有四种形态

-> 函数形态
-> 方法形态
-> 构造器形态
-> 上下文形态(call, apply)


函数的四种调用模式

所有的 this 都是由当前函数决定,最终都是由函数的四种调用模式决定的。
①  函数调用模式,只会执行一段代码,同时函数中的 this 是全局对象 window;返回值由return语句决定,如果没有return语句就表示没有返回值
function f1(){
    console.log(this);
}
f1();//window
function f2(){
    return function(){
        console.log(this);
    }
}
var f2n=f2();
f2n();//this——>window,这也是一次函数调用模式
function f3(){
    f3n();//函数调用模式——————>window
    function f3n(){
        console.log(this);
    }
}
f3();// window

②  方法调用模式,只会执行一段代码,同时方法中的 this 是方法的所有者,即当前的实例对象;返回值由 return 语句决定
//代码1:
var obj={
    age:10,
    say:function(){
        console.log(this.age);
    }
};
obj.say();//方法调用模式
//代码2:
function f1(){
    console.log(this);
}
var obj2={
    s1:f1//将f1函数赋值给obj2.s1属性
};
obj2.s1();//方法调用模式——>this:obj2
//代码3:
var obj3={
    age:10,
    s1:function(){
        console.log(this.age);
    }
};
var obj4={
    age:20,
    s2:obj3.s1//将obj3.s1函数赋值给s2属性
};
obj4.s2();//方法调用模式:this——>obj4

③  构造器调用模式,会用来创建一个对象,还是执行一段代码,this 表示当前对象
返回值:
   a. 没有手动添加返回值,默认返回 this
    b. 返回了一个基本数据类型(number / boolean / string / null / undefined),最终返回 this
   c. 返回了一个复杂数据类型(对象),最终返回该对象
//代码1:
function Person(){
    this.age=20;
    this.name="张三";
    console.log(this);
}
//构造函数调用模式:
var p1=new Person();
//代码2;
function P2(){
    this.age=18;
    return "abc";
}
var p2=new P2();//p2.age=18
//代码3:
function P3(){
    this.age=10;
    return {};
}
var p3=new P3();//p3.age:undefined
console.log("p3.age");
console.log(p3.age);
//代码4:
function P4(){
    this.age=10;
    return [1,3,5];
}
var p4=new P4();//p4.age:undefined
console.log("p4.age");
console.log(p4.age);

④  上下文调用模式,可以用参数来控制 this 的含义
语法:
         函数.call(对象,参数列表
         函数.apply(对象,参数数组
        call 和 apply 除了参数不同,功能完全相同

this :
    a. 传递一个 null / undefined ,this 指向 window
    b. 传递一个 数字 / 字符串 / 布尔值,this 指向 对应的基本包装类型的对象(Number / String / Boolean)
    c. 传递一个 对象:this 指向该对象
返回值:由 return 语句决定

例如调用 函数 func 需要两个参数
func( 1, 2 )
那么使用上下文调用的语法是
func.call(obj, 1, 2);
func.apply(obj, [1, 2]);

apply 方法就是为了处理伪数组

借用函数调用
p.sayHello => p.sayHello.call(p)    p.sayHello.apply(p)
function f1(){
    console.log(this);
}
//上下文模式
f1.call(null);//window
f1.call(undefined);//window
f1.call(1);//Number的实例
f1.call("abc");//String的实例
f1.call(true);//Boolean的实例


var s1="abc";
console.log(s1.length);//3
console.log(s1[0]);//"a"
//代码内部创建了字符串所对应的String构造函数的实例
//{0:"a",1:"b",2:"c",length:3}
//代码执行完毕之后,就会把这个实例给销毁



练习题1:
function f1(){
    this.length=5;
    return function(a,b,c){
        this.length=10;
        return [1,3,5];
    }
}
//构造函数调用模式:
var r1=new f1();//r1是函数
console.log(r1.length);//任何函数都有一个length属性表示形参的个数:3
//函数调用模式
var r2=r1();//r2:[1,3,5]
console.log(r2.length);//3
//构造函数调用模式
var r3=new r1();//r3:[1,3,5]
console.log(r3.length);//3

练习题2:
var length = 10;
function fn() {
    console.log(this.length);
}
var obj = {
    length: 5,
    method: function (f) {
        f();//f变量的值是fn函数,但是这里是函数调用模式--->this:window————>window.length:10
        arguments[0]();//方法调用模式,this:arguments——>arguments.length:2
    }
}
obj.method(fn, 1);
var o1={
    0:function(){
    },
    say:function(){
    }
};
o1[0]();
//o1.0();//错误
o1.say();
o1["say"]();





  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值