浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序

在Javascript定义一个函数一般有如下三种方式:

函数关键字(function)语句:

function fnMethodName(x){alert(x);}

函数字面量(Function Literals):

var fnMethodName = function(x){alert(x);}

Function()构造函数:

var fnMethodName = new Function(‘x','alert(x);') // 由Function构造函数的参数个数可变。最后一个参数写函数体,前面的参数写入参。

上面三种方法定义了同一个方法函数fnMethodName,第1种就是最常用的方法,后两种都是把一个函数复制给变量fnMethodName,而这个函数是没有名字的,即匿名函数。

函数的执行顺序:

例1.

test1();

function test1() {  //函数声明

  alert("1111");

}

test2();

var test2 = function(){   //函数字面量

  alert("2222");

}

test3();
var test3 = new Function("alert(3333);");  //运行时,初始化函数体

执行结果:弹出1111,但是没有弹出222, 3333

原理:弹出1111 是因为JS函数声明提前

没有弹出2222, 3333,是因为函数字面量不是函数声明,函数字面量表示方法是在运行时解析的,在调用test2()之前,函数字面量的函数体还没有声明。

例2.

function f(){return 1;}
console.log(f());   // 第四个函数把第一个函数覆盖
var f = new Function("return 2;");
console.log(f());   // 第二个函数把第四个函数覆盖
var f = function() {return 3;}
console.log(f());   // 第三个函数把第二个函数覆盖
function f(){return 4;}
console.log(f());   // 第四个函数已经被覆盖
var f = new Function("return 5;");
console.log(f());   // 第五个函数把第三个函数覆盖
var f = function(){return 6;}
console.log(f());   // 第六个函数把第五个函数覆盖

执行结果: 4 2 3 3 5 6

原理: 先找出函数声明,“返回值是4的函数声明”覆盖了“返回值是1的函数声明”。所以第一个f()的结果是4 。

函数作用域:

var k = 4;
 window.onload=function() {

   var k=1;
   function t1() {
     var k = 2;

     function test(){return k;}
     console.info(test()); // 弹出 2

     var test = function(){return k;};
     console.info(test());  // 弹出 2

     var test = new Function("return k;");  // 每次执行的时候,动态的new,顶级作用域,无法获得局部变量
     console.info(test());  // 弹出 4

   }
   t1();
};

二、函数字面量和Function()构造函数的区别

虽然函数字面量是一个匿名函数,但语法允许为其指定任意一个函数名,当写递归函数时可以调用它自己,使用Function()构造函数则不行。

var f = function fact(x) {
    if (x < = 1) return 1;
    else return x*fact(x-1);
};

Function()构造函数允许运行时Javascript代码动态的创建和编译。在这个方式上它类似全局函数eval()。

Function()构造函数每次执行时都解析函数主体,并创建一个新的函数对象。所以当在一个循环或者频繁执行的函数中调用Function()构造函数的效率是非常低的。相反,函数字面量却不是每次遇到都重新编译的。

用Function()构造函数创建一个函数时并不遵循典型的作用域,它一直把它当作是顶级函数来执行。

var y = “global”;

function constructFunction() {

var y = “local”;

return new Function(“return y”); // 无法获取局部变量  }

alert(constructFunction()()); // 输出 “global”

函数直接量:

只要是表达式语法,脚本宿主就认为 function 是一个直接量函数,如果什么都不加,光以 function 开头的话则认为是一个函数声明,把 function 写进一个表达式内部,比如四则运算,宿主也会将其当作是一个直接量,如下:

var a = 10 + function(){
return 5;
}();

夸张一点,如下:

(function(){
alert(1);
} ) ( );
( function(){
alert(2);
} ( ) );
void function(){
alert(3);
}()
0, function(){
alert(4);
}();
-function(){
alert(5);
}();
+function(){
alert(6);
}();
!function(){
alert(7);
}();
~function(){
alert(8);
}();
typeof function(){
alert(9);
}();

js中定义函数的方式有多种,函数直接量就是其中一种。如var fun = function(){}, 这里function如果不赋值给fun那么它就是一个匿名函数。

好,看看匿名函数的如何被调用。

1、执行后得到返回值的函数调用

//方式一,调用函数,得到返回值。强制运算符使函数调用执行
(function(x,y){
alert(x+y);
return x+y;
}(3,4));

//方式二,调用函数,得到返回值。强制函数直接量执行再返回一个引用,引用在去调用执行
(function(x,y){
alert(x+y);
return x+y;
})(3,4);

2、执行后忽略返回值

//方式三,调用函数,忽略返回值
void function(x) {
x = x-1;
alert(x);
}(9);

嗯,最后看看错误的调用方式

//错误的调用方式
function(x,y){
alert(x+y);
return x+y;
}(3,4);

三、应用实例的一些说明

对象直接量创建一个对象:

var obj = {x:[1,2],y:23};

代码跟下面是一样的。

var obj=new Object();
obj.x=new Array(1,2);
obj.y=23;

测试:

for(var i in obj) alert(obj[i]);

函数直接量:它是一个表达式而不是语句。
(function(){})()

如下例:

(function(){
document.write(“some script code”);
})()

var a=(function(s){return s})(“abc”);
alert(a);
var b=function(s){return s};
alert(b(“abc”));

这个如何解释呢

大家应该记得这种写法

var a=function (){}

那么怎么运行a呢,那么就是a()

同样的道理,我们不通过a这个变量来存那么是如何写法,就是

function(){}()

但是你会发现这样是错的

因为解析引擎解析的时候,解析的时候发现}判断到了函数结束了

并没有把那个函数作为块来运行

那么加上()是强制把function那块作为块

JS函数调用的四种方法:方法调用模式,函数调用模式,构造器调用模式,apply,call调用模式

1. 方法调用模式:

先定义一个对象,然后在对象的属性中定义方法,通过myobject.property来执行方法,this即指当前的myobject对象。

var blogInfo={
  blogId:123,
  blogName:"werwr",
  showBlog:function(){alert(this.blogId);}
};

blogInfo.showBlog();

2.函数调用模式

定义一个函数,设置一个变量名保存函数,这时this指向到window对象。

var myfunc = function(a,b){
  return a+b;
}

alert(myfunc(3,4));

3.构造器调用模式

定义一个函数对象,在对象中定义属性,在其原型对象中定义方法。在使用prototype的方法时,必须实例化该对象才能调用其方法。

var myfunc = function(a){
  this.a = a;
};
myfunc.prototype = {
  show:function(){alert(this.a);}
}

var newfunc = new myfunc("123123123");
newfunc.show();

4.apply,call调用模式

var myobject={};
var sum = function(a,b){
  return a+b;
};
var sum2 = sum.call(myobject,10,30); //var sum2 = sum.apply(myobject,[10,30]);
alert(sum2);

以上这篇浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • javascript函数的四种调用模式

    1.介绍 先介绍一下函数的调用模式有哪四种: 函数调用模式, 方法调用模式, 构造函数调用模式, 上下文调用模式: 在这里对于函数的调用模式,主要介绍每种调用模式的this的指向和返回值. 2.代码分析 ①.函数调用模式 下面的调用模式就是大家最熟悉的函数调用模式,而函数调用模式的this指向和返回值是什么呢? function fn1 () { console.log(this); }; fn1(); // 在调用函数fn1时,输出的this的结果是Window 在上述代码中,fn1也就是函数

  • JavaScript函数的4种调用方法详解

    在JavaScript中,函数是一等公民,函数在JavaScript中是一个数据类型,而非像C#或其他描述性语言那样仅仅作为一个模块来使用.函数有四种调用模式,分别是:函数调用形式.方法调用形式.构造器形式.以及apply形式.这里所有的调用模式中,最主要的区别在于关键字 this 的意义,下面分别介绍这个几种调用形式. 本文主要内容: 1.分析函数的四种调用形式2.弄清楚函数中this的意义3.明确构造函对象的过程4.学会使用上下文调用函数 一.函数调用形式 函数调用形式是最常见的形式,也是最

  • js函数调用常用方法详解

    来源 javascript语言精粹.这不是书上的源代码. js的函数调用会免费奉送两个而外的参数就是 this 和 arguments .arguments是参数组,他并不是一个真实的数组,但是可以使用.length方法获得长度. 书上有说4中调用方式: 方法调用模式 函数调用模式 构造器调用模式 apply调用模式 下面我们来看看一些实例更好理解. 1:方法调用模式 请注意this此时指向myobject. 复制代码 代码如下: /*方法调用模式*/ var myobject={ value:

  • js中函数调用的两种常用方法使用介绍

    一个js函数 function test(aa){ window.alert("你输入的是"+aa); } 方法一:直接调用 test("dddd"); 方法二:函数赋值给变量 var abc=test; abc('中国');//用变量来调用函数 注意: 当我们写成这种形式的时候,var abc=test("dddd"); 不能通过变量abc来调用函数. 这种写法当test有返回值的时候会把返回值赋值给abc,当没有返回值的时候abc的值为und

  • Javascript调用函数方法的几种方式介绍

    javascript语法灵活,同一个功能有五六种实现方式并不罕见,然后再加上有些反人类的原型继承和异步特性,就更让人一头雾水了.我经常搞不清楚call,apply之间的区别,今天就记录一下,以免再忘了. 在javascript中,方法可以通过以下几种方式执行: 1.func(),这是最直接最常见的调用方式,也符合一般人的思维逻辑,但是在某些情况下有一些不足,下面会解释. 2.(function(arg){})(window),匿名方法调用,在构造命名空间时比较有用,后面的括号中的参数与匿名方法中

  • js函数调用的方式

    Js函数调用的方式有如下几种情况: (1)具名函数直接调用 复制代码 代码如下: function foo()  {  }  foo(); (2)匿名函数通过引用来调用 复制代码 代码如下: fooRef = function()  {  }fooRef(); (3)没有引用的匿名函数调用1 复制代码 代码如下: (function() {}()); (4)没有引用的匿名函数调用2 复制代码 代码如下: (function() { })(); (5)没有引用的匿名函数调用3  复制代码 代码如下

  • Javascript 函数的四种调用模式

    Javascript 函数的四种调用模式 1  函数模式 最普通的函数调用 // 声明式函数 function fn1 () { console.log(this); } // 函数表达式函数 var fn2 = function() { console.log(this); }; // 调用 函数中this表示全局对象,在浏览器中就是指window fn1(); //window fn2(); //window 2 方法模式 函数依附于一个对象,是对象的一个属性,我们再调用这个函数.这种模式就

  • JS函数的几种定义方式分析

    本文实例讲述了JS函数的几种定义方式.分享给大家供大家参考,具体如下: JS函数的定义方式比较灵活,它不同于其他的语言,每个函数都是作为一个对象被维护和运行的. 先看几种常用的定义方式: function func1([参数]){/*函数体*/} var func2=function([参数]){/*函数体*/}; var func3=function func4([参数]){/*函数体*/}; var func5=new Function(); 上述第一种方式是最常用的方式,不用多说. 第二种

  • JS函数的定义与调用方法推荐

    JS函数调用的四种方法:方法调用模式,函数调用模式,构造器调用模式,apply,call调用模式 1. 方法调用模式: 先定义一个对象,然后在对象的属性中定义方法,通过myobject.property来执行方法,this即指当前的myobject对象. var blogInfo={ blogId:123, blogName:"werwr", showBlog:function(){alert(this.blogId);} }; blogInfo.showBlog(); 2. 函数调用

  • 浅谈js函数三种定义方式 & 四种调用方式 & 调用顺序

    在Javascript定义一个函数一般有如下三种方式: 函数关键字(function)语句: function fnMethodName(x){alert(x);} 函数字面量(Function Literals): var fnMethodName = function(x){alert(x);} Function()构造函数: var fnMethodName = new Function('x','alert(x);') // 由Function构造函数的参数个数可变.最后一个参数写函数体

  • 浅谈js函数的多种定义方法与区别

    定义一个函数一般有如下三种方式: 1.函数关键字(function)语句: function fnMethodName(x){ alert(x); } 2.函数字面量(Function Literals): var fnMethodName = function(x){alert(x);} 3.Function()构造函数: var fnMethodName = new Function('x', 'alert(x);') 上面三种方法定义了同一个方法函数fnMethodName,第1种就是最常

  • 浅谈JS函数定义方式的区别

    关于JS的函数定义方式有以下两种: (1)典型的函数声明 function slide(arguments){ //...code } (2)以函数表达式的形式定义函数 var slide = function(arguments){ //...code } 虽然上面两种方式逻辑上是等价的,但是还是有点小区别: 区别一:例一中的函数会在代码执行以前被加载到作用域中,而例二则是在代码执行到那一行的时候才会有定 义: 区别二:函数声明会给函数指定一个名字,而函数表达式则是创建一个匿名函数,然后将这个

  • 浅谈js对象的创建和对6种继承模式的理解和遐想

    JS中总共有六种继承模式,包括原型链.借用构造函数.组合继承.原型式继承寄生式继承和寄生组合式继承.为了便于理解记忆,我遐想了一个过程,对6中模式进行了简单的阐述. 很长的一个故事,姑且起个名字叫女娲造人吧. 创建对象 女娲一个一个的捏人(创建对象),这样太慢,于是设计了一种机器(函数),想造什么样的,告诉他这个人有哪些特点和功能,机器来制造.这就是工厂模式的(使用同一个接口创建对象,回产生大量重复代码,由此发明了一种函数(模具)). 但是机器造人同样也比较麻烦(挖土.和泥.捏眼睛.捏鼻子...

  • 浅谈js函数中的实例对象、类对象、局部变量(局部函数)

    定义 function Person(national,age) { this.age = age; //实例对象,每个示例不同 Person.national = national; //类对象,所用实例公用 var bb = 0; //局部变量,外面不能访问(类似局部函数) } 调用 var p = new Person("中国", 29); document.writeln("age:" + p.age); document.writeln("obj

  • 浅谈Vue单页面做SEO的四种方案

    目录 1.Nuxt 服务端渲染应用部署 (SSR服务器渲染) 优势: 不足:(开发中遇到的坑) 2.Nuxt 静态应用部署 优势: 不足: 3.预渲染prerender-spa-plugin 优势: 不足: 4.Phantomjs 针对爬虫做处理 优势: 不足: 总结 众所周知,Vue SPA单页面应用对SEO不友好,当然也有相应的解决方案,通过查找资料,大概有以下4种方法.(本人只用过第一,第三种方案) 1.Nuxt 服务端渲染应用部署 (SSR服务器渲染) 关于服务器渲染:Vue官网介绍 ,

  • 浅谈JS中的常用选择器及属性、方法的调用

    选择器.属性及方法调用的配合使用: <style> #a{ width: 200px; height: 100px; background-color: red; } .b{ width: 200px; height: 100px; background-color: green; } .div1{ width: 200px; height: 100px; background-color:aqua; } </style> <body> <div id="

  • 浅谈JS函数节流防抖

    在前端开发中有一部分的用户行为会频繁的触发事件执行,而对于DOM操作.资源加载等耗费性能的处理,很可能导致界面卡顿,甚至浏览器的崩溃.函数节流(throttle)和函数防抖(debounce)就是为了解决类似需求应运而生的. 函数节流(throttle) 函数节流就是预定一个函数只有在大于等于执行周期时才执行,周期内调用不执行.好像水滴攒到一定重量才会落下一样. 场景: 窗口调整(resize) 页面滚动(scroll) 抢购疯狂点击(mousedown) 实现: function thrott

  • 浅谈Java虚拟机对内部锁的四种优化方式

    自Java 6/Java 7开始,Java虚拟机对内部锁的实现进行了一些优化.这些优化主要包括锁消除(Lock Elision).锁粗化(Lock Coarsening).偏向锁(Biased Locking)以及适应性锁(Adaptive Locking).这些优化仅在Java虚拟机server模式下起作用(即运行Java程序时我们可能需要在命令行中指定Java虚拟机参数"-server"以开启这些优化). 1 锁消除 锁消除(Lock Elision)是JIT编译器对内部锁的具体实

  • 浅谈js中的三种继承方式及其优缺点

    第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = 'yellow'; this.view = function(){ return this.hair + ',' + this.eye + ',' + this.skin; } } //子类 function man(){ this.feature = ['beard','strong']; } man.pr

随机推荐