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("大瓜皮") ...
随机推荐
- C#使用wkhtmltopdf.exe,HTML页面转化为PDF文档
此文用来记录使用wkhtmltopdf.exe在C#代码中将html转换为PDF的过程: 1,在http://wkhtmltopdf.org/downloads.html 下载wkhtmltopdf. ...
- UVA 11859 - Division Game
看题传送门 题目大意 有一个n * m的矩阵,每个元素均为2~10000之间的正整数,两个游戏者轮流操作.每次可选一行中的1个或者多个大于1的整数把它们中的每个数都变成它的某个真因子,比如12可以变成 ...
- swift学习第十四天:属性监听器
监听属性的改变 在OC中我们可以重写set方法来监听属性的改变 Swift中可以通过属性观察者来监听和响应属性值的变化 通常是监听存储属性和类属性的改变.(对于计算属性,我们不需要定义属性观察者,因为 ...
- strace跟踪线程调用
方法一:strace -fp pid , 可以跟踪所有线程, 进程的系统调用. [root@xxxx]strace -p 24091 Process xxx attached - interrupt ...
- Java程序猿必知的10个调试技巧
在本文中,作者将使用大家经常使用的的开发工具Eclipse来调试Java应用程序.但这里介绍的调试方法基本都是通用的,也适用于NetBeans IDE,我们会把重点放在运行时上面. 在開始之前,推荐大 ...
- 关于serialVersionUID的说明 分类: B1_JAVA 2014-05-24 11:02 1334人阅读 评论(0) 收藏
1.为什么要使用serialVersionUID (1)对于实现了Serializable接口的类,可以将其序列化输出至磁盘文件中,同时会将其serialVersionUID输出到文件中. (2)然后 ...
- ios开发之多线程---GCD
一:基本概念 1:进程:正在运行的程序为进程. 2:线程:每个进程要想执行任务必须得有线程,进程中任务的执行都是在线程中. 3:线程的串行:一条线程里任务的执行都是串行的,假如有一个进程开辟了一条线程 ...
- ChangeWindowMessageFilterEx 概述(用于取消低权限程序向高权限程序发送消息不成功的限制,分6个等级)
ChangeWindowMessageFilterEx 函数,为指定窗口修改用户界面特权隔离 (UIPI) 消息过滤器. 函数原型: BOOL WINAPI ChangeWindowMessageFi ...
- 博客搬家啦! -----> http://ronghaopger.github.io/
新地方: http://ronghaopger.github.io/ 以后这里就不更新了,感谢博客园!
- [Angular] Adding keyboard events to our control value accessor component
One of the most important thing when building custom form component is adding accessbility support. ...