JavaScript函数声明和函数表达式

函数声明和函数表达式

JavaScript创建函数的两种方式

函数声明:

function functionName(arg0, arg1, arg2) {
    //函数体
}
alert(functionName.name);
//函数声明提升 感觉类似c语言中的函数声明 但是功能不同,js可以执行 c只是个声明
//下面代码不会报错,在代码执行之前会先读取函数声明
sayHi();
function sayHi(){
    alert("Hi!");
}

函数表达式:

var functionName =  function(arg0, arg1, arg2) {
    //函数体
};
alert(functionName.name);
// 报错:函数还不存在
sayHi();
var sayHi = function(){
    alert("Hi!");
};

创建一个函数并将它赋值给变量functionName这种情况下创建的函数叫做匿名函数。

递归

function factorial(num) {
    if (num < 1) {
        return 1;
    } else {
        return num * factorial(num - 1);
    }
}

var anotherFactorial = factorial;
factorial = null;
alert(anotherFactorial(4));//报错

使用arguments.callee可以解决这个问题,arguments.callee是一个指向正在执行的函数的指针

function factorial(num){
    if (num < 1) {
        return 1;
    } else {
        return num * arguments.callee(num - 1);
    }
}

闭包

这块还是要多看看

比如需要解除对匿名函数的调用,设置为null

闭包是指有权访问另一个函数作用域中变量的函数。创建闭包的常见方式是,在一个函数内部创建另一个函数。

作用域链的机制,导致闭包只能取得包含函数中任何变量的最后一个值。闭包保存的是整个变量对象,不是 某个特殊的变量。

立即执行函数

立即执行函数(IIFE,Immediately-Invoked Function Expression),是一种在定义后就会立即执行的函数,其实质是一种语法。

//该匿名函数会立即执行
(function() {
  console.log('立即执行函数是基于匿名函数创建的');
}());

参考 “https://www.cnblogs.com/uakora/p/12695429.html” "JavaScript中的匿名函数、立即执行函数和闭包"

私有变量

严格来讲,JavaScript中没有私有成员的概念,所有对象属性都是公共的。

//特权方法的基本模式如下
function MyObject() {
    var privateVariable = 10;

    function privateFunction() {
        return false;
    }

    //特权方法
    this.publicMethod = function () {
        privateVariable++;
        return privateFunction();
    };
}

function Person(name) {
    this.getName = function () {
        return name
    };
    this.setName = function (value) {
        name = value;
    };
}
var person = new Person("Nicholas");
alert(person.getName());
person.setName("Yatoro");
alert(person.getName());

静态私有变量

通过在私有作用域中定义私有变量或函数,同样可以创建特权方法,基本模式如下

(function () {
    //私有变量和私有函数
    var privateVariable = 10;
    function privateFunction(){
        return false;
    }
    //构造函数
    //这里并没有使用函数声明,而是使用使用了函数表达式,函数声明只能创建局部函数
    //同样,在声明MyObject时也没有使用var关键字。初始化未经生命的变量。总会创建一个全局变量,因此MyObject就变成了一个全局变量,能够在私有作用域之外被访问到。
    MyObject = function (){};

    //共有/特权方法
    MyObject.prototype.publicMethod = function (){
        privateVariable++;
        return privateFunction();
    };
})();

这个模式与构造函数中定义特权方法的主要区别,就在于私有变量和函数是由实例共享的,由于特权方法是在原型上定义的,因此所有实例使用同一个函数。

(function (){
    var name  = "";
    Person = function (value){
        name = value;
    };
    Person.prototype.getName = function (){
        return name;
    };
    Person.prototype.setName = function (value){
        name = value;
    };
})();

var person1 = new Person("Nicholas");
alert(person1.getName());//Nicholas
person1.setName("Greg");
alert(person1.getName());//Greg

var person2 = new Person("Michael");
alert(person2.getName());//Michael
alert(person1.getName());//Michael

这个例子中的额Person构造函数与getName( )和setName( )方法一样,都有权访问私有变量name。在这种模式下,变量name就变成了一个静态的,由所有实例共享的属性。

模块模式

模块模式是为单例创建私有变量和特权方法。所谓单例,指的就是只有一个实例的对象。

JavaScript是以字面量的方式创建单例对象的。

var singleton = {
	name : value;
	method : function () {
		//function code
	}
}

模块模式通过为单例添加私有变量和特权方法能够使其得到增强,其语法如下:

var singleton = function() {
	//私有变量和私有函数
	var privateVariable  = 10;
	function privateFunction() {
		retrun false;
	}
  //共有/特权方法
  retrun {
    publicProperty: ture,
    publicMethode: function() {
      privateVariable++;
      return privateFunction();
    }
  };
}();

例如:

var application = function() {
	var components = new Array();
	componets.push(new BaseComponent());
	return {
		getComponentCount : function() {
			return components.length;
		},
		registerComponent : function(component) {
			if(typeof component = "object") {
				components.push(component);
			}
		}
	};
}();

增强的模块模式

var singleton  = function() {
 var privateVariable = 10;
 function privateFunction() {
    return false;
 }
 var object = new CustomType();
 //添加特权/共有方法
 object.publicProperty = true;
 object.publicMethod = function(){
    privateVariable++;
    retrun privateFunction();
 };
 return object;
}();
posted @ 2021-10-18 17:57  _Salvatore  阅读(122)  评论(0)    收藏  举报