Function函数
一般大家都用这个写法来定义一个函数:
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函数的更多相关文章
- 关于Function()函数对象的那些小九九
概念:首先,函数是一种特殊类型的数据,函数也是数据类型的一种,实际上函数也是一种对象,函数对象的内建构造器是Function(); 函数的几种创建方式: 函数声明法: function sum(a,b ...
- JavaScript function函数种类(转)
转自:http://www.cnblogs.com/polk6/p/3284839.html JavaScript function函数种类 本篇主要介绍普通函数.匿名函数.闭包函数 目录 1. 普通 ...
- JavaScript function函数种类介绍
JavaScript function函数种类介绍 本篇主要介绍普通函数.匿名函数.闭包函数 1.普通函数介绍 1.1 示例 ? 1 2 3 function ShowName(name) { ...
- 【JS学习笔记】关于function函数
函数的基本格式 function 函数名() { 代码: } 函数的定义和调用 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transit ...
- 2019-2-14SQLserver中function函数和存储过程、触发器、CURSOR
Sqlserver 自定义函数 Function使用介绍 前言: 在SQL server中不仅可以可以使用系统自带的函数(时间函数.聚合函数.字符串函数等等),还可以根据需要自定义函数 ...
- 创建一个Scalar-valued Function函数来实现LastIndexOf
昨天有帮助网友解决的个字符串截取的问题,<截取字符串中最后一个中文词语(MS SQL)>http://www.cnblogs.com/insus/p/7883606.html 虽然实现了, ...
- javascript:function 函数声明和函数表达式 详解
函数声明(缩写为FD)是这样一种函数: 有一个特定的名称 在源码中的位置:要么处于程序级(Program level),要么处于其它函数的主体(FunctionBody)中 在进入上下文阶段创建 影响 ...
- jquery中的 $(function(){ .. }) 函数
2017-04-29 在讲解jquery中的 $(function(){ .. }) 函数之前,我们先简单了解下匿名函数.匿名函数的形式为:(function(){ ... }),又如 functio ...
- javascript学习4、Function函数、伪数组arguments
一.Function函数基础 函数:就是将一些语句进行封装,然后通过调用的形式,执行这些语句. 1.函数的作用: 将大量重复的语句写在函数里,以后需要这些语句的时候,可以直接调用函数,避免重复劳动. ...
- Function函数的声明方式
函数 函数是一段可以反复利用的代码 Function函数的声明方式, +通过变量,把函数存储到变量容器里 var a=function(){ console.log("大瓜皮") ...
随机推荐
- GPUImage ==> 一个基于GPU图像和视频处理的开源iOS框架
Logo 项目介绍: GPUImage是Brad Larson在github托管的开源项目. GPUImage是一个基于GPU图像和视频处理的开源iOS框架,提供各种各样的图像处理滤镜,并且支持照相机 ...
- postman和fiddler的基本使用
本文转自:https://www.cnblogs.com/qq909283/p/6826578.html 写在前面:本文主要的章节规划: 1.什么是接口测试 另外,有的时候会直接调用别的公司的接口,比 ...
- 微服务实战(六):选择微服务部署策略 - DockOne.io
原文:微服务实战(六):选择微服务部署策略 - DockOne.io [编者的话]这篇博客是用微服务建应用的第六篇,第一篇介绍了微服务架构模板,并且讨论了使用微服务的优缺点.随后的文章讨论了微服务不同 ...
- windows apache 跳转 tomcat 代理
需求是这样的 服务器有tomcat和apache两个服务器 t端口号是8080,a端口是80 比如javaweb的域名是 www.XXX.com:8080 phpweb的域名是 a.XXX.com ...
- (转)chrome浏览器收藏夹(书签)的导出与导入
导出chrome浏览器的书签到一个文件中.首先选择chrome浏览器的书签管理器菜单.然后点击“整理”,然后选择“将书签导出到html文件”. 步骤阅读 2 将导出的html文件保存,用于下次导入,这 ...
- 8.2 Android灯光系统_led_class驱动
android-5.0.2\hardware\libhardware\include\hardware\lights.h //系统一些宏定义 android源码只带的灯光驱动在linux内核的dri ...
- iOS8新特性
1. App Extension Programming Guide 2.LocalAuthentication.framework - Touch ID Authentication 3.Local ...
- HDU 3974 Assign the task 并查集
http://acm.hdu.edu.cn/showproblem.php?pid=3974 题目大意: 一个公司有N个员工,对于每个员工,如果他们有下属,那么他们下属的下属也是他的下属. 公司会给员 ...
- 22、DMA驱动程序框架
一.使用DMA的优点及DMA支持的请求源(请求源是启动DMA传输的事件,可以认为是触发.它可以是软件,也可以是中断,或者外部事件) 1.DMA优点是其进行数据传输时不需要CPU的干涉,可以大大提高CP ...
- VS2010制作dll
一.为什么需要dll 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,如ATL.M ...