函数


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

sayHi();

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

递归


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

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

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

函数执行的作用域链


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

  先定义了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 -;
} else if (value1 > value2){
return ;
} else {
return ;
}
};
}
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=; i < ; i++){
result[i] = function(){
return i;
};
} return result;
}

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

function createFunctions(){
var result = new Array(); for (var i=; i < ; 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=; 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高级程序设计中文版》

重温Javascript(四)-函数的更多相关文章

  1. Javascript中函数的四种调用方式

    一.Javascript中函数的几个基本知识点: 1.函数的名字只是一个指向函数的指针,所以即使在不同的执行环境,即不同对象调用这个函数,这个函数指向的仍然是同一个函数. 2.函数中有两个特殊的内部属 ...

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

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

  3. 初探JavaScript(四)——作用域链和声明提前

    前言:最近恰逢毕业季,千千万万的学生党开始步入社会,告别象牙塔似的学校生活.往往在人生的各个拐点的时候,情感丰富,感触颇深,各种对过去的美好的总结,对未来的展望.与此同时,也让诸多的老“园”工看完这些 ...

  4. (转)Javascript匿名函数的写法、传参、递归

    (原)http://www.veryhuo.com/a/view/37529.html (转)javascript匿名函数的写法.传参和递归 javascript匿名函数的写法.传参和递归 http: ...

  5. (转)javascript匿名函数的写法、传参和递归

    (原)http://www.veryhuo.com/a/view/37529.html (转)javascript匿名函数的写法.传参和递归 http://www.veryhuo.com 2011-0 ...

  6. javascript oop深入学习笔记(二)--javascript的函数

    一.概述: 函数是进行模块化程序设计的基础, javascript重的的函数不同于其他语言,每个函数都作为一个对象被维护和运行.通过函数对象的性质,可以很方便的将一个函数赋值给一个变量或则讲函数作为参 ...

  7. [转]javascript console 函数详解 js开发调试的利器

    javascript console 函数详解 js开发调试的利器   分步阅读 Console 是用于显示 JS和 DOM 对象信息的单独窗口.并且向 JS 中注入1个 console 对象,使用该 ...

  8. javascript——四种函数调用形式

    此文的目的是分析函数的四种调用形式,弄清楚函数中this的意义,明确构造函对象的过程,学会使用上下文调用函数. 在JavaScript中,函数是一等公民,函数在JavaScript中是一个数据类型,而 ...

  9. JavaScript function函数种类(转)

    转自:http://www.cnblogs.com/polk6/p/3284839.html JavaScript function函数种类 本篇主要介绍普通函数.匿名函数.闭包函数 目录 1. 普通 ...

  10. 从头开始学JavaScript (四)——操作符

    原文:从头开始学JavaScript (四)--操作符 一.一元操作符 1.自增自减操作符:分为前置型和后置型: 前置型:++a;--a; 后置型:a++;a--; 例: <script typ ...

随机推荐

  1. ubuntu ssh-keygen Permission denied

    ubuntu下生成github上的ssh keys,执行: ssh-keygen 直接执行: sudo chown user1:user1 /home/user1/.ssh -R 成功生成.

  2. 定制 cloud-init - 每天5分钟玩转 OpenStack(155)

    这是 OpenStack 实施经验分享系列的第 5 篇. 对于 Linux 镜像,cloud-init 负责 instance 的初始化工作.cloud-init 功能很强大,能做很多事情,而且我们可 ...

  3. 支持向量机(SVM)理论总结系列.线性可分(附带R程序案例:用体重和心脏重量来预测一只猫的性别)

    附注:不要问我为什么写这么快,是16年写的. 1.名词解释 支持向量机中的机:在机器学习领域,常把一些算法看做一个机器,如分类机(也叫作分类器) 2.问题描述 空间中有很多已知类别的点,现在想用一个面 ...

  4. 使用yum安装cmake

    一.搜索yum源中的CMake,查看源中最新的版本是什么,使用命令[root@localhost ~]# yum search cmake ,如果搜索出的结果过多可以配合grep命令来控制搜索结果. ...

  5. Java显式锁学习总结之六:Condition源码分析

    概述 先来回顾一下java中的等待/通知机制 我们有时会遇到这样的场景:线程A执行到某个点的时候,因为某个条件condition不满足,需要线程A暂停:等到线程B修改了条件condition,使con ...

  6. linux下keepalived 安装配置

    keepalived是一个类似于layer3, 4 & 7交换机制的软件,也就是我们平时说的第3层.第4层和第7层交换.Keepalived的作用是检测web服务器的状态,如果有一台web服务 ...

  7. mfc---获取当前时间

    CTime t = CTime::GetCurrentTime(); CString strTime = t.format("%Y/&m%d" %h:%M:%S);

  8. Spring+SpringMVC+MyBatis+easyUI整合基础篇(八)mysql中文查询bug修复

    写在前面的话 在测试搜索时出现的问题,mysql通过中文查询条件搜索不出数据,但是英文和数字可以搜索到记录,中文无返回记录.本文就是写一下发现问题的过程及解决方法.此bug在第一个项目中点这里还存在, ...

  9. (Mac OS平台)升级.NetCore1.0正式版小记

    昨天终于发布了.NetCore1.0正式版.昨晚回去就顺手把手里的一个.NetCore项目升级了一下.还是遇到了一些问题,这里记录下吧. 1.Restore问题 这个问题一直都有,一直放那没去解决.主 ...

  10. 【2017-03-09】SQL Server 数据库基础、四种约束

    一.数据库和内存的区别 数据库:一些存储在硬盘上的数据文件 内存:计算机临时存储的一些数据 二.常用数据库 .Net - SQL Server PHP - MySql Java - Oreacl 三. ...