// 通过块级作用域(私有作用域)中定义私有变量或函数,同样可以创建对外公共的特权方法; (function(){ // 创建私有作用域; var age = 100; // 静态私有变量; function run(){ return '运行中...'; }; Box = function(){}; // 使用函数表达式定义构造函数; Box.prototype.go = function(){ // 公有(特权)方法;在原型上定义的; return age+run(); }; })(); var box = new Box(); console.log(box.go()); // 100运行中...; // 上面的对象声明,采用的是Box = function(){}而不是functiong Box(){};并且在声明Box时没有使用var关键字 // 导致:初始化未经声明的变量,总是会创建一个全局变量;因此,Box就成了一个全局变量,能够在私有作用域之外被访问到; // 因为如果用函数声明定义构造函数,那么就变成私有函数了,无法在全局访问到了,所以要使用函数式定义构造方法; (function(){ var user = ""; Person = function(value){ // 此处定义的Person是全局变量; user = value; // 这里的构造函数有权访问私有变量name; }; Person.prototype.getUser = function(){ return user; }; Person.prototype.setUser = function(value){ user = value; } })(); var person = new Person(); person.setUser('Lee'); console.log(person.getUser()); // =>Lee; // 使用了prototype导致方法共享了,而user也就变成静态属性了; // 所谓静态属性:即共享于不同对象中的属性;?
八 模块模式
// 简言之,如果必须创建一个对象并以某些数据对其进行初始化,同时还要公开一些能够访问这些私有数据的方法,那么就可以使用模块模式; // 之前采用的都是构造函数的方式来创建私有变量和特权方法; // 那么对象字面量方式就采用模块模式来创建; var box = { // 字面量对象,也是单例对象:只有一个实例的对象; age:100, // 这是公有属性,将要改成私有; run:function(){ return '运行中...'; }; }; // 模块模式私有化变量和函数: var box = function(){ var age = 100; function run(){ return '运行中...'; } return { // 将一个字面量对象作为函数的值返回; go:function(){ // 返回的对象字面量中只包含可以公开的属性和方法; return age+run(); // 由于这个对象是在匿名函数内部定义的,因此它的公有方法有权访问私有变量和函数; } }; // 从本质上讲,这个对象字面量定义的是单例的公共接口; }(); // 这种模式在需要对单例进行某些初始化,同时又需要维护其私有变量时是非常有用的; // 上面直接返回对象的例子,也可以这么写: var box = function(){ var age = 100; function run(){ return '运行中...'; } var obj = { // 创建字面量对象; go:function(){ return age+run(); } }; return obj; // 返回刚创建的对象; }(); // 字面量的对象声明,其实在设计模式中可以看作是一种单例模式; // 所谓单例模式,就是永远保持对象的只有一个实例; // 增强的模块模式:适合返回自定义对象,也就是构造函数; function Desk(){}; var box = function(){ var age = 100; function run(){ return '运行中...'; }; var desk = new Desk(); desk.go = function(){ return age+run(); }; return desk; }(); console.log(box.go()); // =>100运行中;
九 小结
在JavaScript编程中,函数表达式是一种非常有用的技术;使用函数表达式可以无须对函数命名,从而实现动态编程;
1.函数表达式
函数表达式不同于函数声明;函数声明要求有名字,但函数表达式不需要;
没有名字的函数表达式叫做匿名函数;2.闭包
当在函数内部定义了其他函数时,就创建了闭包.闭包有权访问包含函数内部的所有变量;原理如下:
在后台执行环境中,闭包的作用域链包含着它自己的作用域、包含函数的作用域和全局作用域;
通常,函数的作用域及其所有变量都会在函数执行结束后被销毁;
但是,当函数返回了一个闭包时,这个函数的作用域将会一直在内存中保存到闭包不存在为止;3.块级作用域
使用闭包可以在JavaScript中模仿块级作用域(JavaScript本身没有块级作用域的概念);要点如下:
创建并立即调用一个函数,这样既可以执行其中的代码,又不会在内存中留下对该函数的引用;
结果就是函数内部的所有变量都会被立即销毁--除非将某些变量赋值给了包含作用域(即外部作用域)中的变量;4.私有变量
闭包还可以用于在对象中创建私有变量,要点如下:
即使JavaScript中没有真是的私有对象属性的概念,但是可以使用闭包来实现公有方法,而通过公有方法可以访问包含作用域中定义的变量;
可以使用构造函数模式、原型模式来实现自定义类型的特权方法,也可以使用模块模式来实现单例的特权方法;
您可能感兴趣的文章: