函数


  函数声明提升,在执行代码之前会先读取函数声明

sayHi();function sayHi(){alert("Hi!");
}

递归


  arguments.callee是指向正在执行的函数的指针

  还可以换种方式达成一样的效果

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

函数执行的作用域链


function compare(value1, value2){if (value1 < value2){return -1;} else if (value1 > value2){return 1;} else {return 0;}
}var result = compare(5, 10);

  先定义了compare()函数,又在全局作用域调用它。当调用时,会创建一个包含arguments、value1、value2的活动对象。全局执行环境的变量对象(包含result和compare)在compare()执行环境的作用域中处于第二位

  作用域链本质上是一个指向变量对象的指针列表,只引用但不实际包含变量对象

  

  

闭包


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

function createComparisonFunction(propertyName) {return function(object1, object2){var value1 = object1[propertyName];var value2 = object2[propertyName];if (value1 < value2){return -1;} else if (value1 > value2){return 1;} else {return 0;}};
}

var compare = createComparisonFunction("name");
var result = compare({ name: "Nicholas" }, { name: "Greg" });

  

  在匿名函数从 createComparisonFunction()中被返回后,它的作用域链被初始化为包含createComparisonFunction()函数的活动对象和全局变量对象。这样,匿名函数就可以访问在createComparisonFunction()中定义的所有变量。createComparisonFunction()

函数在执行完毕后,其活动对象也不会被销毁,因为匿名函数的作用域链仍然在引用这个活动对象。换句话说,当createComparisonFunction()函数返回后,其执行环境的作用域链会被销毁,但它的活动对象仍然会留在内存中;直到匿名函数被销毁后,createComparisonFunction()的活动对象才会被销毁

//创建函数
var compareNames = createComparisonFunction("name");//调用函数
var result = compareNames({ name: "Nicholas" }, { name: "Greg" });//解除对匿名函数的引用(以便释放内存)
compareNames = null;

  创建的比较函数被保存在变量compareNames 中。而通过将compareNames 设置为等于null解除该函数的引用,就等于通知垃圾回收例程将其清除。随着匿名函数的作用域链被销毁,其他作用域(除了全局作用域)也都可以安全地销毁了。

  

闭包与变量


function createFunctions(){var result = new Array();for (var i=0; i < 10; i++){result[i] = function(){return i;};}return result;
}

  每个函数都返回10。因为每个函数的作用域链中都保存着createFunctions() 函数的活动对象, 所以它们引用的都是同一个变量i 。

function createFunctions(){var result = new Array();for (var i=0; i < 10; i++){result[i] = function(num){return function(){return num;};}(i);}return result;
}

闭包与this,arguments


  每个函数在被调用时都会自动取得2个特殊变量:this和arguments。内部函数在搜索这2个变量时,只会搜索到其活动对象为止,不能直接访问外部函数中的这2个变量。把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以访问了。arguments也是如此。

var name = "The Window";var object = {name : "My Object",getNameFunc : function(){var that = this;return function(){return that.name;};}
};alert(object.getNameFunc()()); //"My Object"    

模仿块级作用域


function outputNumbers(count){for (var i=0; i < count; i++){alert(i);}alert(i); //计数
}

  通常称为私有作用域  

(function(){//这里是块级作用域
})();

function outputNumbers(count){(function () {for (var i=0; i < count; i++){alert(i);}})();alert(i); //导致一个错误!
}

私有变量


  

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()); //"Nicholas"
person.setName("Greg");
alert(person.getName()); //"Greg"

  

静态私有变量


  

(function(){//私有变量和私有函数var privateVariable = 10;function privateFunction(){return false;}//构造函数MyObject = function(){};//公有/特权方法MyObject.prototype.publicMethod = function(){privateVariable++;return privateFunction();};})();

  未经声明的变量,会创建一个全局变量

  但使用prototype的问题时实例变量需要自己定义

  

(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(person1.getName()); //"Michael"
alert(person2.getName()); //"Michael"

模块模式


  单例对象  

var singleton = {name : value,method : function () {//这里是方法的代码
    }
};

  模块模式通过为单例添加私有变量和特权方法使其得到增强

var singleton = function(){//私有变量和私有函数var privateVariable = 10;function privateFunction(){return false;}//特权/公有方法和属性return {publicProperty: true,publicMethod : function(){privateVariable++;return privateFunction();}};
}();

  以这种模式创建的每个单例都是Object的实例,因为最终要通过一个对象字面量来表示它。单例通常作为全局对象存在,不会将它传递给一个函数,不会使用instanceOf来检查其对象类型

增强的模块模式


  在返回对象之前加入对其增强的代码。适合的场景是单例必须是某种类型的实例,还必须添加某些属性或方法对其增强。

var singleton = function(){//私有变量和私有函数var privateVariable = 10;function privateFunction(){return false;}//创建对象var object = new CustomType();//添加特权/公有属性和方法object.publicProperty = true;object.publicMethod = function(){privateVariable++;return privateFunction();};//返回这个对象return object;
}();

引用:

《JavaScript高级程序设计中文版》

转载于:https://www.cnblogs.com/dopeter/p/6661945.html

重温Javascript(四)-函数相关推荐

  1. 【JavaScript】重温Javascript继承机制

    上段时间,团队内部有过好几次给力的分享,这里对西风师傅分享的继承机制稍作整理一下,适当加了些口语化的描述,留作备案. 一.讲个故事吧 澄清在先,Java和Javascript是雷锋和雷峰塔的关系.Ja ...

  2. 重温Javascript继承机制

    上段时间,团队内部有过好几次给力的分享,这里对西风师傅分享的继承机制稍作整理一下,适当加了些口语化的描述,留作备案. 一.讲个故事吧 澄清在先,Java和Javascript是雷锋和雷峰塔的关系.Ja ...

  3. 【译】JavaScript 工厂函数 vs 构造函数

    译者:前端小智 原文:medium.com/@chamikakas- 当谈到JavaScript语言与其他编程语言相比时,你可能会听到一些令人困惑东西,其中之一是工厂函数和构造函数. 想优质文章请猛戳 ...

  4. html字符串长度函数,最常用的20个javascript方法函数

    最常用的20个javascript方法函数 常用的`javascript方法函数有哪些?下面YJBYS小编为你盘点,废话不说,直接放码! 1字符串长度截取 function cutstr(str, l ...

  5. javascript匿名函数的各种执行形式

    近期在研究Pomelo源码,这个框架基于Node.js,所以非要频繁地与JavaScript脚本打交道不可.因此,本文中我们来总结 javascript语言中匿名函数的主要目的及各种存在形式.其实,匿 ...

  6. JavaScript的函数详解

    JavaScript的函数详解 一.什么是函数 二.函数的使用 1.函数的声明 2.函数的调用 3.函数的参数:参入运算的数据 (1)形参(形式参数) (2)实参(实在参数): (3)参数之间的数据传 ...

  7. JavaScript 时间函数

    一.  JavaScript setTimeout() 函数 setTimeout -- 暂停指定的毫秒数后执行指定的代码 setTimeout ,中文"设置超时"的意思 引用网址 ...

  8. linux 运行函数名,JavaScript匿名函数的各种执行形式

    近期在研究Pomelo源码,这个框架基于Node.js,所以非要频繁地与JavaScript脚本打交道不可.因此,本文中我们来总结 JavaScript语言中匿名函数的主要目的及各种存在形式.其实,匿 ...

  9. javascript 常用函数大全

    javascript函数一共可分为五类: •常规函数 •数组函数 •日期函数 •数学函数 •字符串函数 1.常规函数 javascript常规函数包括以下9个函数: (1)alert函数:显示一个警告 ...

  10. matlab 迭代 混沌与分形实验报告,实验四 函数的迭代混沌与分形.doc

    实验四 函数的迭代混沌与分形.doc 实验四函数的迭代.混沌与分形实验目的1认识函数的迭代:2了解混沌和分形迭代在数值计算中占有很重要的地位,了解和掌握它是很有必要的本实验将讨论用NEWTON迭代求方 ...

最新文章

  1. Spring-依赖注入
  2. 第18章 Linux集群架构
  3. jzoj2137-(GDKOI2004)城市统计【二维前缀和,bfs】
  4. CPU和MMU(内存管理单元)
  5. maven工程启动时报“Cannot resolve XXX:XXX:xx.xx.xx”错误的问题
  6. POJ2955Brackets——dp
  7. 20181027_任务
  8. 埃及分数怎么计算java_贪心算法之埃及分数问题(附c++源代码)
  9. 初一数学教材人教版_【期中试卷+知识点总结】初中初一初二初三年级各科期中试卷+知识点总结...
  10. 不可能解开的谜题 (程序员修炼之道,评注者序)
  11. 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 如果,我们将这两个数相加起来,则会返回一个新的链表来表示,,,
  12. 在UI设计中用什么样的字体?
  13. 修改typora主题的字体
  14. 怎么才可以使用 IPX 协议???
  15. 微信 分享领券 php,微信卡券货架显示已领取
  16. 磁力开源项目和自己服务器,Github新项目:自己本地搭建磁力搜索系统
  17. MES系统生产制造流程分析
  18. 管理和维护数据完整性
  19. sublime用星号多行注释的快捷键
  20. 智能信访一体机开启全天候零距离无接触信访服务

热门文章

  1. [VsCode] 开发所使用的VsCode的插件
  2. Intellij IDEA + Maven + Cucumber 项目 (三):简单解释RunCukesTest.java
  3. UVa OJ 120
  4. Ext4核心组件Grid的变化及学习(3):可编辑的grid
  5. .NET代码编写规范 整理
  6. BeanUtils.copyProperties 需要getset方法支持
  7. SpringData 简单的条件查询
  8. Java学习之模拟纸牌游戏,List的ArrayList,Map的HashMap,重写Collections类的sort方法对指定类进行通过特定属性排序,输入异常处理等的学习...
  9. linux运维相关操作(centos/Ubuntu)
  10. Bw树:新硬件平台的B树(内存数据库中的b树索引)