zoukankan      html  css  js  c++  java
  • 具名函数的四种调用方式(转)

    转自:http://snandy.iteye.com/blog/420000

    1、()小括号运算符   平时最常用的就是()运算符来调用/执行一个函数

    Js代码  
    1. //无参函数fun1   
    2. function fun1() {   
    3.     alert('我被调用了');   
    4. }   
    5. fun1()   
    6.   
    7. //有参函数fun2   
    8. function fun2(param) {   
    9.     alert(param);   
    10. }   
    11. fun2('我被调用了')  

    ECMAScript3后加入给Function加入了call和apply后,就有了下面两种

    2、call

    Js代码  
    1. //无参函数fun1   
    2. function fun1() {   
    3.     alert('我被调用了');   
    4. }   
    5. fun1.call(null);   
    6.   
    7. //有参函数fun2   
    8. function fun2(param) {   
    9.     alert(param);   
    10. }   
    11. fun2.call(null,'我被调用了')  

    3、apply

    Js代码  
    1. //无参函数fun1   
    2. function fun1() {   
    3.     alert('我被调用了');   
    4. }   
    5. fun1.apply(null);   
    6.   
    7. //有参函数fun2   
    8. function fun2(param) {   
    9.     alert(param);   
    10. }   
    11. fun2.apply(null,['我被调用了'])  

    4、new 不推荐使用这种方式哦

    Js代码  
    1. //无参函数fun1   
    2. function fun1() {   
    3.     alert('我被调用了');   
    4. }   
    5. new fun1();   
    6.   
    7.   
    8. //有参函数fun2   
    9. function fun2(param) {   
    10.     alert(param);   
    11. }   
    12. new fun2('我被调用了')  

    ok,从以上调用方式上看四种方式执行结果没有区别。但如果函数有返回值的话,用new方式调用时可能会让你有些失望。

    Js代码  
    1. //有返回值的函数fun   
    2. function fun() {   
    3.     alert('我被调用了');   
    4.     return "jack";   
    5. }   
    6.   
    7. var c = new fun();   
    8. alert(c);//[object Object],为什么不是"jack"?  

    改成这样,

    Js代码  
    1. //有返回值的函数fun   
    2. function fun() {   
    3.     alert('我被调用了');   
    4.     return {name:'jack'};   
    5. }   
    6.   
    7. var c = new fun();   
    8. alert(c.name);//jack,又正常返回了  

    总结如下:

    用new方式调用函数时。如果存在返回值,当返回值是javascript的内置类型(基本类型)如字符串(String),数字(Number),布尔(Boolean)等时,将不会返回该值;

    当返回值是对象,函数,数组等对象类型时,将返回该对象,函数,数组。

    当返回值是内置类型(基本类型)时,new fun()到底返回什么呢?

    ----------------------------------------------------------------------------------------------------------------

    以函数中有无this来讨论。没有this时返回一个空的对象{},有this时返回一个非空对象。

    定义一个没有this的函数

    Js代码  
    1. //返回值是基本类型   
    2. function fun() {   
    3.     return "jack";   
    4. }   
    5.   
    6. var c = new fun();   
    7. for (var atr in c) {   
    8.     alert(atr);   
    9. }    
    10. alert(c);//[object Object]  

    返回值c不是"jack", 从for in执行后没有输出任何属性可以看出 c 是一个空的对象{}。

    再看看有this的函数,函数中有this实际上是在写一个类。但由于js的灵活性,造成了许多诡异的写法。

    Js代码  
    1. //返回值是基本类型   
    2. function fun() {   
    3.     this.name = "tom";   
    4.     return "jack";   
    5. }   
    6.   
    7. var c = new fun();   
    8. for (var atr in c) {   
    9.     alert(atr);//name   
    10. }    
    11. alert(c.name);//tom  

    返回值也不是"jack",for in输出了name属性,最后一句输出了tom,说明返回值 c 是一个非空对象。这里的return "jack"压根没起作用。

    所以当函数返回值是内置类型(基本类型)时,用new方式调用函数将会导致错误的结果

    那么当函数返回值是一个对象,数组,函数呢?

    Js代码  
    1. //不含this,返回值是一个对象   
    2. function fun() {   
    3.     //组装一个对象   
    4.     var obj = {};   
    5.     obj.name = 'andy';   
    6.     obj.age = 20;   
    7.     obj.msg = function(){}   
    8.        
    9.     return obj;   
    10. }   
    11.   
    12. var c = new fun();   
    13. for (var atr in c) {   
    14.     alert(atr);//name,age,msg   
    15. }    
    16. alert(c.name);//andy  
    Js代码  
    1. //含this,返回值是一个对象   
    2. function fun() {   
    3.     this.sex = "man";   
    4.     //组装一个对象   
    5.     var obj = {};   
    6.     obj.name = 'andy';   
    7.     obj.age = 20;   
    8.     obj.msg = function(){}   
    9.        
    10.     return obj;   
    11. }   
    12.   
    13. var c = new fun();   
    14. for (var atr in c) {   
    15.     alert(atr);//name,age,msg   
    16. }    
    17. alert(c.name);//andy  

     两段的输出结果是一样的,c都含有name,age,msg属性而不含sex属性。说明当返回值是对象类型(对象,数组,函数)时,new不会用this去构造对象,而直接返回组装的对象。

    这种方式实际上是工厂方式,在应用中更多的程序员把函数名首字母大写,让它看起来更像一个类。

    这里把函数名首字母大写了,让它符合java类命名规范。

    Js代码  
    1. /**  
    2.  * 定义一个函数Car  
    3.  */  
    4. function Car(color,doors) {   
    5.        
    6.     var car = {};   
    7.     car.color = color;   
    8.     car.doors = doors;   
    9.     car.msg = function(){    
    10.         alert("This is a " + this.color + " car, there are " + this.doors + " doors." );   
    11.     }   
    12.        
    13.     return car;   
    14. }  

     看起来怪怪的,Car明明是一个类啊,怎么也不像之前的函数调用。和文章标题似乎有些不一致了。但我们的确可以用()来调用它。当然也可以用new来调用它。用new方式则让它更像java的创建对象方式。

    Js代码  
    1. //方式1   
    2. var c1 = Car('red',2);   
    3. c1.msg();   
    4.   
    5. //方式2   
    6. var c2 = new Car('black',4);   
    7. c2.msg();  

    这种方式在一些js库中也能见到,如mootools.js中的一个很重要的函数Native,返回值是一个函数(类)。mootools core中的Class类就是Native函数返回的。var Class =  new Native({..});当然也可以不用new而直接采用()调用。

     

  • 相关阅读:
    在Centos7下源代码安装配置Nginx
    mysql5.7.21源码安装
    数据库设计三大范式
    电商项目中使用Redis实现秒杀功能
    PHP和Redis实现在高并发下的抢购及秒杀功能示例详解
    PHP面向对象(抽象类与抽象方法、接口的实现)
    php面向对象 封装继承多态 接口、重载、抽象类、最终类总结
    利用VHD虚拟文件加密自己的个人信息
    Chrome常用快捷键
    stl本子
  • 原文地址:https://www.cnblogs.com/beijia/p/functionInvoke.html
Copyright © 2011-2022 走看看