[关闭]
@Dale-Lin 2017-12-26T15:24:47.000000Z 字数 3875 阅读 911

JS Function

JavaScript


什么是函数

函数是一系列语句组成的一个整体,用于执行某一特定任务。
构造函数函数名首字母应该大写,并且使用 new 操作符调用。


声明函数

  1. 使用 function 关键字
  2. 指定函数名称(若未指定函数名字,函数将不能被调用)
  3. 用 {} 来包含执行任务的语句
  1. function sayHellow() {
  2. document.write('Hellow hope!');
  3. }

调用函数

  1. 在函数名的后面带上一对括号()来调用函数
  2. 可以在一个JavaScript文件中调用一个函数无数次
  3. 函数的声明可以在函数的调用之后,因为调用函数时解释器会扫描所有代码,以找到函数的定义
  1. //前面可以声明函数
  2. sayHello();
  3. //后面也可以声明函数

函数的参数

  1. 提供给函数的参数写在函数名后面的括号对()里面
  2. 参数分为形参和实参,形参的行为类似于变量,而实参是有具体值的变量或者本身就是值
  1. function size(width,height){
  2. return width*height;
  3. }
  4. //定义函数size时使用了形参height和width,return返回后面表达式计算的值
  5. var size1 = size(8,10);
  6. //调用函数size时使用了实参8和10,此时size1是80
  7. var WIDTH = 8;
  8. var HEIGHT = 10;
  9. var size2 = size(WIDTH,HEIGHT);
  10. //WIDTH和HEIGHT是储存了实参的变量

return单一值

  1. return关键字将其后面的表达式的值返回给调用函数的代码
  2. 当解释器读到return关键字时,解释器将跳过后面的代码,马上离开函数

从函数中获取多个值

  1. 在函数中使用数组可以返回多个值
  1. function culSize(width,height,depth){
  2. var area = width*height;
  3. var volume = area*depth;
  4. var sizes = [size,volume];
  5. return sizes;
  6. }
  7. //在这个函数中sizes储存了一个数组
  8. var area1 = culSize(6,6,6)[0];
  9. var volume2 = culSize(6,6,6)[1];
  10. //调用时加入了实参,并且调用返回数组中的不同值

使用函数表达式

  1. 函数可以写在原本应该存在表达式的地方,从而被当作表达式来对待
  2. 此法声明的函数一般没有函数名,称为匿名函数,被储存在变量之中
  3. 该变量名可以被当作函数名一样使用,唯一不同是,作为一个变量,必须先声明才能被调用,且变量声明后要以分号;结尾
  1. var area = function (width,height) {
  2. return width*height;
  3. };
  4. var size3 = area(2,3);

立即调用函数表达式(IIFE)

这类函数没有函数名,在解释器经过时执行一次

  1. var area = ( function () {
  2. var width = 2;
  3. var height = 3;
  4. return width*height;
  5. }()
  6. );
  7. //最外层的括号表明这个函数是一个表达式,函数语句块结束后的括号令解释器经过时直接执行此函数

函数内部属性

函数内的arguments对象存在一个叫callee的属性,该属性是一个指针,指向拥有该arguments对象的函数。如下一个典型的阶乘函数:

  1. function factorial(num){
  2. if (num<=1){
  3. return 1;}
  4. else (return num*arguments.callee(num-1);)
  5. }
  6. //使用arguments.callee(num-1)替代factorial(num-1),降低函数名与程序的耦合度

函数内另一个特殊对象是this,引用函数执行的环境对象,在全局作用域下,即为window对象。(严格模式下undefined)

  1. window.color = "red";
  2. var o = {color: "blue",};
  3. function sayColor(){
  4. alert(this.color);
  5. }
  6. sayColor(); //red
  7. o.sayColor = sayColor;
  8. o.sayColor(); //blue

函数属性与方法

在ECMAScript中,函数也是一种对象,因此函数拥有属性和方法。
每个函数都有两个属性:lengthprototype

  1. function sayName(name){
  2. alert(name);
  3. }
  4. function sum(num1,num2){
  5. return num1+num2;
  6. }
  7. function sayHi(){
  8. alert('Hi');
  9. }
  10. console.log(sayName.length); //1
  11. console.log(sum.length); //2
  12. console.log(sayHi,length); //0

每个函数都包含两个原生方法:apply()call() 。这两个方法都用于在特定的作用域中调用某函数:

  1. /* 改变函数作用域 */
  2. window.color = "red";
  3. var o = {color: "blue"};
  4. function logColor(){
  5. console.log(this.color)
  6. }
  7. logColor(); //red
  8. logColor.apply(o, ); //blue
  9. /* 传递参数 */
  10. function sum(num1,num2){
  11. return num1+num2;
  12. }
  13. function callSum1(num1, num2){
  14. return sum.apply(this, arguments); //使用arguments传入callSum1的全局环境和参数
  15. }
  16. function callSum2(num1, num2){
  17. return sum.apply(this, [num1,num2]); //使用Array实例传入callSum1的全局环境和参数
  18. }
  19. console.log(callSum1(5,10)); //15
  20. console.log(callSum2(10,10)); //20
  1. function sum(num1,num2){
  2. return num1+num2;
  3. }
  4. function callSum(num1, num2){
  5. return sum.call(this, num1, num2);
  6. }
  7. console.log(callSum(10,10)); //20

apply()一样,在扩充作用域上的优势在于——对象和方法之间没有任何耦合关系

  1. window.color = "red";
  2. var o = {color: "blue"};
  3. function sayColor(){
  4. console.log(this.color);
  5. }
  6. var objectSayColor = sayColor.bind(o);
  7. console.log(objectSayColor); //blue

eval()

语法
eval(string)
接收以字符串形式表示的一串JS代码,并立刻执行(evaluates)。
解析器发现调用eval()方法时,将传入的参数执行结果插入到原代码位置,因此这段代码与eval()具有相同的作用域。

  1. eval("function sayHi(){ alert('hi');}");
  2. sayHi(); //"hi"

即使是在eval()方法内声明的代码,在eval()代码相同的作用域下也可以被访问。

如果eval()接收的参数不是字符串,eval()会将参数直接插入原位置,而不会执行。

  1. eval(new String("2+2")); //return "2+2"
  2. eval("2+2"); //return 4
  3. var expression = new String("2+2");
  4. eval(expression.toString()); //return 4

如果 间接 地使用eval(),它将在全局作用域下起作用(忽略当前作用域):

  1. function test(){
  2. var x = 2, y = 4;
  3. console.log(eval("x+y")); //直接调用,使用function本地作用域,6
  4. var geval = eval;
  5. console.log(geval("x+y")); //间接调用,使用全局作用域,throws ReferenceError,x、y未定义
  6. }

eval()中创建的任何变量或函数都不会被提升,因为在解析代码时,它们包含在一个字符串中,只有在eval()执行的时候创建。
eval()执行时调用js解析器,因此运行效率比其他替代方案慢。


返回

return 可以使函数提前返回,当 return 执行时,函数立即返回而不再执行余下语句。
一个函数如果没有返回值,则返回 undefined 。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注