一般大家都用这个写法来定义一个函数:


function Name([parameters]){
functionBody
}; //alert(typeof Name) // Function

当我们这么定义函数的时候,函数内容会被编译(但不会立即执行,除非我们去调用它)。而且,也许你不知道,当这个函数创建的时候有一个同名的对象也被创建,javascript实际上在后台为你创建了一个对象。这个对象的名称就是函数名本身。这个对象的类型是function

我们也可以通过指派一个变量名给匿名函数的方式来定义它。


var add = function(a, b) {
return a + b;
}
alert(add(1, 2)); // 结果 3

当我们指派一个这样的函数的时候,我们并不一定要求必须是匿名函数


var add = function theAdd(a, b) {
return a + b;
}
alert(add(1, 2)); // 结果 3
alert(theAdd(1, 2)); // 结果也是 3

使用这种方式来定义函数在面向对象编程中是很有用的,因为我们能像底下这样使一个函数成为一个对象的属性。


var myObject = new Object();
myObject.add = function (a, b) { return a + b };
// myObject 现在有一个叫做“add”的属性(或方法),而且我能够象下面这样使用它
myObject.add(1, 2);

我们也能够通过使用运算符new来定义一个函数。这是一个最少见的定义函数的方式并且并不推荐使用这种方式除非有特殊的理由(可能的理由见下)。语法如下:


varName=new Function([param1Name, param2Name,...paramNName], functionBody); var myfunction = new Function("x", "y", "return (x*y)");
console.log(typeof myfunction) //Function
alert(myfunction(2, 3)); //弹出6

这就告诉javascript,我们将要创建一个类型是Function的对象。还要注意到,参数名和函数体都是作为字符串而被传递。我们可以随心所欲的增加参数,javascript知道函数体会是右括号前的最后一个字符串(如果没 有参数,你能够只写函数体)。


function createMyFunction(myOperator) {
return new Function("a", "b", "return a" + myOperator + "b;");
}
var add = createMyFunction("+"); // 创建函数 "add"
var subtract = createMyFunction("-"); // 创建函数 "subtract"
var multiply = createMyFunction("*"); // 创建函数 "multiply"
alert("加的结果=" + add(10, 2)); // 结果是 12
alert("减的结果=" + subtract(10, 2)); // 结果是 8
alert("乘的结果=" + multiply(10, 2)); // 结果是 20

这个有趣的例子创建了三个不同的function,通过实时传递不同的参数来创建一个新Function。因为编译器没法知道最终代码会是什么样子的,所以new Function(...) 的内容不会被编译。那这有什么好处呢?嗯,举个例子,如果你需要用户能够创建他们自己的函数的时候这个功能也许很有用,比如在游戏里。我们也许需要允许用 户添加“行为”给一个“player”。但是,再说一次,一般情况下,我们应该避免使用这种形式,除非有一个特殊的目的。

我们能够添加给Object添加属性,包括对象function。因为定义一个函数的实质是创建一个对象。我们能够“暗地里”给函数添加属性。


function Ball() {
}
Ball.callname = "皮球";
console.log(Ball.callname); //皮球 //因为function是一个对象,我们能够为一个function分配一个指针
var pointBall = Ball;
console.log(pointBall.callname); //皮球

面向对象,多少对象指向同一个函数



        function sayName(name) {
alert(name);
}
var object1 = new Object(); // 创建三个对象
var object2 = new Object();
var object3 = new Object();
object1.sayMyName = sayName; // 将这个函数指派给所有对象
object2.sayMyName = sayName;
object3.sayMyName = sayName; object1.sayMyName("object1"); // 输出 "object1"
object2.sayMyName("object2"); // 输出 "object2"
object3.sayMyName("object3"); // 输出 "object3"

同时,还能够在一个函数创建之后重新分配它,但是我们需要指向函数对象本身,而不是指向它的指针


function TestFun() {
console.log(1);
}
TestFun = function () {
console.log(2);
}
TestFun(); //2

我们还能够在一个函数中嵌套一个函数,你只能在内部调用嵌套的函数。就是说,你不能这么调用:ParentFun.SonFun(10),因为SonFun只有当外部函数 ParentFun()在运行的时候才会存在,而这个时候,如果外面还有个 function SonFun(){...}函数的话。调用ParentFun函数会先从内部找,即调用是里面的


function ParentFun(a, b, c) {
function SonFun(a) {
return a * a;
}
return SonFun(a) + SonFun(b) + SonFun(c);
}

一个函数能够用来作为一个数据类型,这个特性通常被用在面向对象编程中来模拟用户自定义数据类型


function Ball(message){
alert(message);
}
var ball0=new Ball("creating new Ball"); // 创建对象并输出消息
ball0.name="ball-0"; // ball0现在有一个属性:name
alert(ball0.name); // 输出 "ball-0"

function Ball(message){
alert(message);
}
var ball0=new Object();
ball0.construct=Ball;
ball0.construct("creating new ball"); // 执行 ball0.Ball("creating..");

当我们象上面那样使用关键字new创建一个对象的时候,一个新的Object被创建了。我们可以在创建之后给这个对象添加属性


function Ball() {
}
var ball0 = new Ball(); // ball0 现在指向了类型Ball的一个新实例
ball0.name = "ball-0"; // ball0 现在有一个属性"name"
var ball1 = new Ball();
ball1.name = "ball-1";
var ball2 = new Ball();
alert(ball0.name); // 输出 "ball-0"
alert(ball1.name); // 输出 "ball-1"
alert(ball2.name); // 哦,我忘记给ball2添加“name”了! undefined

function Employee(name, salary, mySupervisor) {
this.name = name;
this.salary = salary;
this.supervisor = mySupervisor;
}
var boss = new Employee("John", 200);
var manager = new Employee("Joan", 50, boss);
var teamLeader = new Employee("Rose", 50, boss);
alert(manager.supervisor.name + " is the supervisor of " + manager.name);
alert(manager.name + "\'s supervisor is " + manager.supervisor.name);

对匿名函数的调用其实还有一种做法,也就是我们看到的jQuery片段——使用()将匿名函数括起来, //然后后面再加一对小括号(包含参数列表)


alert((new Function("x", "y", "return x*y;"))(2, 3));// "6"

大家知道小括号的作用吗?小括号能把我们的表达式组合分块,并且每一块,也就是每一对小括号,都有一个返回值。这个返回值实际上也就是小括号中表达式的返回值。所以,当我们用一对小括号把匿名函数括起来的时候,实际上小括号对返回的,就是一个匿名函数的Function对象。因此,小括号对加上匿名函数就如同有名字的函数般被我们取得它的引用位置了。所以如果在这个引用变量后面再加上参数列表,就会实现普通函数的调用形式。比如:


var testF = function (x, y) { return x + y; };

总之,将其(被小括号包含的匿名函数)理解为括号表达式返回的函数对象,然后就可以对这个函数对象作正常的参数列表调用了。

(function(){alert(1)})()应该是与a=function(){alert(1)}()等价,或者是a=(function(){alert(1)})(),即a()的变形,不能连a=都去掉。


(function (a) {
console.log(a);
//firebug输出123,使用()运算符
})(123); (function (a) { console.log(a);
//firebug输出1234,使用()运算符
}(1234)); !function (a) {
console.log(a);
//firebug输出12345,使用!运算符
}(12345); +function (a) {
console.log(a);
//firebug输出123456,使用+运算符
}(123456); -function (a) {
console.log(a);
//firebug输出1234567,使用-运算符
}(1234567); var fn = function (a) {
console.log(a);
//firebug输出12345678,使用=运算符
}(12345678) var fn = (function (a) {
console.log(a);
//firebug输出12345678,使用=运算符
})(12345678)

可以看到输出结果,在function前面加!、+、 -甚至是逗号等到都可以起到函数定义后立即执行的效果,而()、!、+、-、=等运算符,都将函数声明转换成函数表达式,消除了javascript引擎识别函数表达式和函数声明的歧义,告诉javascript引擎这是一个函数表达式,不是函数声明,可以在后面加括号,并立即执行函数的代码。

加括号是最安全的做法,因为!、+、-等运算符还会和函数的返回值进行运算,有时造成不必要的麻烦。

javascript中没用私有作用域的概念,如果在多人开发的项目上,你在全局或局部作用域中声明了一些变量,可能会被其他人不小心用同名的变量给覆盖掉,根据javascript函数作用域链的特性,可以使用这种技术可以模仿一个私有作用域,用匿名函数作为一个“容器”,“容器”内部可以访问外部的变量,而外部环境不能访问“容器”内部的变量,所以( function(){…} )()内部定义的变量不会和外部的变量发生冲突,俗称“匿名包裹器”或“命名空间”。

Function函数的更多相关文章

  1. 关于Function()函数对象的那些小九九

    概念:首先,函数是一种特殊类型的数据,函数也是数据类型的一种,实际上函数也是一种对象,函数对象的内建构造器是Function(); 函数的几种创建方式: 函数声明法: function sum(a,b ...

  2. JavaScript function函数种类(转)

    转自:http://www.cnblogs.com/polk6/p/3284839.html JavaScript function函数种类 本篇主要介绍普通函数.匿名函数.闭包函数 目录 1. 普通 ...

  3. JavaScript function函数种类介绍

    JavaScript function函数种类介绍 本篇主要介绍普通函数.匿名函数.闭包函数 1.普通函数介绍 1.1 示例 ? 1 2 3 function ShowName(name) {     ...

  4. 【JS学习笔记】关于function函数

    函数的基本格式 function 函数名() { 代码: } 函数的定义和调用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transit ...

  5. 2019-2-14SQLserver中function函数和存储过程、触发器、CURSOR

    Sqlserver 自定义函数 Function使用介绍 前言:         在SQL server中不仅可以可以使用系统自带的函数(时间函数.聚合函数.字符串函数等等),还可以根据需要自定义函数 ...

  6. 创建一个Scalar-valued Function函数来实现LastIndexOf

    昨天有帮助网友解决的个字符串截取的问题,<截取字符串中最后一个中文词语(MS SQL)>http://www.cnblogs.com/insus/p/7883606.html 虽然实现了, ...

  7. javascript:function 函数声明和函数表达式 详解

    函数声明(缩写为FD)是这样一种函数: 有一个特定的名称 在源码中的位置:要么处于程序级(Program level),要么处于其它函数的主体(FunctionBody)中 在进入上下文阶段创建 影响 ...

  8. jquery中的 $(function(){ .. }) 函数

    2017-04-29 在讲解jquery中的 $(function(){ .. }) 函数之前,我们先简单了解下匿名函数.匿名函数的形式为:(function(){ ... }),又如 functio ...

  9. javascript学习4、Function函数、伪数组arguments

    一.Function函数基础 函数:就是将一些语句进行封装,然后通过调用的形式,执行这些语句. 1.函数的作用: 将大量重复的语句写在函数里,以后需要这些语句的时候,可以直接调用函数,避免重复劳动. ...

  10. Function函数的声明方式

    函数 函数是一段可以反复利用的代码 Function函数的声明方式, +通过变量,把函数存储到变量容器里 var a=function(){ console.log("大瓜皮") ...

随机推荐

  1. vue2.0 踩坑记录之组件

    - did you register the component correctly? For recursive components, make sure to provide the " ...

  2. 【习题 5-10 UVA-1597】Searching the Web

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 用map < string,vector < int > >mmap[100];来记录每一个数据段某个字符串 ...

  3. [RxJS] RefCount: automatically starting and stopping an execution

    With the connect() method on a ConnectableObservable, the programmer is responsible for avoiding lea ...

  4. bootstrap课程3 bootstrap中常用的排版样式有哪些

    bootstrap课程3 bootstrap中常用的排版样式有哪些 一.总结 一句话总结:bootstrap里面对常用表情比如p.h1.code等html中的常用表情都修改了样式,照着手册用就好,样式 ...

  5. get_mysql_conn_info.py

    #!/usr/bin/env python#-*- encoding: utf8 -*- import xlrd """此模块作用:从excel文件获取数据库连接信息,第 ...

  6. 【p092】分数线划定

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 世博会志愿者的选拔工作正在A市如火如荼地进行.为了选拔最合适的人才,A市对所有报名的选手进行了笔试,笔 ...

  7. jquery-12 jquery的ajax如何使用

    jquery-12 jquery的ajax如何使用 一.总结 一句话总结:就是$.get()和$.post()方法的使用,看参考手册就好,与php的交互. 1.删除元素的时候如何设置删除特效? ani ...

  8. Android开发之SpannableString具体解释

    在实际的应用开发过程中常常会遇到.在文本的不同部分显示一些不同的字体风格的信息如:文本的字体.大小.颜色.样式.以及超级链接等. 普通情况下,TextView中的文本都是一个样式.对于类似的情况.能够 ...

  9. Notepad++打开xml文件显示crlf的问题

    如图所示,显示CRLF,  CRLF其实是换行符. 所以在下图所示设置下显示行尾符不显示即可.

  10. 访问Ext.ComponentMgr中的组件对象

    Ext.Component是所有Ext组件的基类,所有组件被注册在布局管理器中Ext.ComponentManager, 这样就可以通过Ext.getCmp随时被引用,每种组件都有特定的类型,是Ext ...