重温Javascript(四)-函数
函数
函数声明提升,在执行代码之前会先读取函数声明
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(四)-函数的更多相关文章
- Javascript中函数的四种调用方式
一.Javascript中函数的几个基本知识点: 1.函数的名字只是一个指向函数的指针,所以即使在不同的执行环境,即不同对象调用这个函数,这个函数指向的仍然是同一个函数. 2.函数中有两个特殊的内部属 ...
- 【JavaScript】重温Javascript继承机制
上段时间,团队内部有过好几次给力的分享,这里对西风师傅分享的继承机制稍作整理一下,适当加了些口语化的描述,留作备案. 一.讲个故事吧 澄清在先,Java和Javascript是雷锋和雷峰塔的关系.Ja ...
- 初探JavaScript(四)——作用域链和声明提前
前言:最近恰逢毕业季,千千万万的学生党开始步入社会,告别象牙塔似的学校生活.往往在人生的各个拐点的时候,情感丰富,感触颇深,各种对过去的美好的总结,对未来的展望.与此同时,也让诸多的老“园”工看完这些 ...
- (转)Javascript匿名函数的写法、传参、递归
(原)http://www.veryhuo.com/a/view/37529.html (转)javascript匿名函数的写法.传参和递归 javascript匿名函数的写法.传参和递归 http: ...
- (转)javascript匿名函数的写法、传参和递归
(原)http://www.veryhuo.com/a/view/37529.html (转)javascript匿名函数的写法.传参和递归 http://www.veryhuo.com 2011-0 ...
- javascript oop深入学习笔记(二)--javascript的函数
一.概述: 函数是进行模块化程序设计的基础, javascript重的的函数不同于其他语言,每个函数都作为一个对象被维护和运行.通过函数对象的性质,可以很方便的将一个函数赋值给一个变量或则讲函数作为参 ...
- [转]javascript console 函数详解 js开发调试的利器
javascript console 函数详解 js开发调试的利器 分步阅读 Console 是用于显示 JS和 DOM 对象信息的单独窗口.并且向 JS 中注入1个 console 对象,使用该 ...
- javascript——四种函数调用形式
此文的目的是分析函数的四种调用形式,弄清楚函数中this的意义,明确构造函对象的过程,学会使用上下文调用函数. 在JavaScript中,函数是一等公民,函数在JavaScript中是一个数据类型,而 ...
- JavaScript function函数种类(转)
转自:http://www.cnblogs.com/polk6/p/3284839.html JavaScript function函数种类 本篇主要介绍普通函数.匿名函数.闭包函数 目录 1. 普通 ...
- 从头开始学JavaScript (四)——操作符
原文:从头开始学JavaScript (四)--操作符 一.一元操作符 1.自增自减操作符:分为前置型和后置型: 前置型:++a;--a; 后置型:a++;a--; 例: <script typ ...
随机推荐
- Webpack学习系列(一)
一:全局安装: npm install webpack -g (-g全局安装) npm init -y (初始化参数) npm install webpack --save-dev (安装在当前 ...
- JS事件流理解
事件是用户或浏览器自身执行的某种动作,如click,load和mouseover都是事件的名字. 事件是javaScript和DOM之间的桥梁. 你若触发,我便执行--事件发生,调用它的处理函数执行相 ...
- 编写一个飞行棋项目(C#)遇到几个问题:
在写程序中遇到如下问题:如果有人知道,请您一定要指点迷津.小白. 1.在运行暂停功能时,这个暂停功能可以实现,但是无法显示提示信息. case 3: Console.Clear(); Program. ...
- 令人费解的java泛型
对于我们java中的泛型,可能很多人知道怎么使用并且使用的还不错,但是我认为想要恰到好处的使用泛型,还是需要深入的了解一下它的各种概念和内部原理.本文将尽可能的囊括java泛型中的重要的概念 ...
- 【转】Java通过IText导出word和pdf
原帖地址:http://blog.csdn.net/zwx19921215/article/details/34439851 最近做的项目中需要用到把Highcharts图表导出word和pdf的功能 ...
- Java代理(静态/动态 JDK,cglib)
Java的代理模式是应用非常广泛的设计模式之一,也叫作委托模式,其目的就是为其他的对象提供一个代理以控制对某个对象的访问和使用,代理类负责为委托类预处理消息,过滤消息并转发消息,以及对消息执行后续处理 ...
- 【2017-03-05】函数基础、函数四种结构、ref和out参数、递归
一.函数基础 1.函数/方法:非常抽象独立完成某项功能的一个个体 2.函数的作用: 提高代码的重用性提高功能开发的效率提高程序代码的可维护性 3.分类 固定功能函数高度抽象函数 4.函数四要素:输入, ...
- appium desktop 版本发布
Appium Desktop is an open source app for Mac, Windows, and Linux which gives you the power of the Ap ...
- 使用Spring构建RMI服务器和客户端
上一篇文章我们实用JDK原生API构造了简单RMI应用,本篇将实用Spring框架来构造RMI的应用,实用Spring你会体验到简单,不需要那么多的条条框框,因为Spring给你做了很多封装. 项目构 ...
- Oracle Jdbc驱动下载及安装本地maven仓库
由于二进制许可 binary license的限制,oracle jdbc驱动不能通过共有仓库来获取,所以你可以下载下来添加到自己的本地仓库或私有仓库中. 添加到本地仓库步骤如下: 下载Oracle ...