重温Javascript(四)-函数
函數(shù)
?
函數(shù)聲明提升,在執(zhí)行代碼之前會(huì)先讀取函數(shù)聲明
sayHi();function sayHi(){alert("Hi!"); }?
遞歸
?
arguments.callee是指向正在執(zhí)行的函數(shù)的指針
還可以換種方式達(dá)成一樣的效果
var factorial = (function f(num){if (num <= 1){return 1;} else {return num * f(num-1);} });?
?
函數(shù)執(zhí)行的作用域鏈
?
function compare(value1, value2){if (value1 < value2){return -1;} else if (value1 > value2){return 1;} else {return 0;} }var result = compare(5, 10);先定義了compare()函數(shù),又在全局作用域調(diào)用它。當(dāng)調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)包含arguments、value1、value2的活動(dòng)對(duì)象。全局執(zhí)行環(huán)境的變量對(duì)象(包含result和compare)在compare()執(zhí)行環(huán)境的作用域中處于第二位
作用域鏈本質(zhì)上是一個(gè)指向變量對(duì)象的指針列表,只引用但不實(shí)際包含變量對(duì)象
閉包
?
閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量的函數(shù),創(chuàng)建閉包的常見方式,在一個(gè)函數(shù)內(nèi)部創(chuàng)建另一個(gè)函數(shù)
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" });
在匿名函數(shù)從 createComparisonFunction()中被返回后,它的作用域鏈被初始化為包含createComparisonFunction()函數(shù)的活動(dòng)對(duì)象和全局變量對(duì)象。這樣,匿名函數(shù)就可以訪問在createComparisonFunction()中定義的所有變量。createComparisonFunction()
函數(shù)在執(zhí)行完畢后,其活動(dòng)對(duì)象也不會(huì)被銷毀,因?yàn)槟涿瘮?shù)的作用域鏈仍然在引用這個(gè)活動(dòng)對(duì)象。換句話說(shuō),當(dāng)createComparisonFunction()函數(shù)返回后,其執(zhí)行環(huán)境的作用域鏈會(huì)被銷毀,但它的活動(dòng)對(duì)象仍然會(huì)留在內(nèi)存中;直到匿名函數(shù)被銷毀后,createComparisonFunction()的活動(dòng)對(duì)象才會(huì)被銷毀
//創(chuàng)建函數(shù) var compareNames = createComparisonFunction("name");//調(diào)用函數(shù) var result = compareNames({ name: "Nicholas" }, { name: "Greg" });//解除對(duì)匿名函數(shù)的引用(以便釋放內(nèi)存) compareNames = null;創(chuàng)建的比較函數(shù)被保存在變量compareNames 中。而通過將compareNames 設(shè)置為等于null解除該函數(shù)的引用,就等于通知垃圾回收例程將其清除。隨著匿名函數(shù)的作用域鏈被銷毀,其他作用域(除了全局作用域)也都可以安全地銷毀了。
閉包與變量
?
function createFunctions(){var result = new Array();for (var i=0; i < 10; i++){result[i] = function(){return i;};}return result; }每個(gè)函數(shù)都返回10。因?yàn)槊總€(gè)函數(shù)的作用域鏈中都保存著createFunctions() 函數(shù)的活動(dòng)對(duì)象, 所以它們引用的都是同一個(gè)變量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
?
每個(gè)函數(shù)在被調(diào)用時(shí)都會(huì)自動(dòng)取得2個(gè)特殊變量:this和arguments。內(nèi)部函數(shù)在搜索這2個(gè)變量時(shí),只會(huì)搜索到其活動(dòng)對(duì)象為止,不能直接訪問外部函數(shù)中的這2個(gè)變量。把外部作用域中的this對(duì)象保存在一個(gè)閉包能夠訪問到的變量里,就可以訪問了。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"?
模仿塊級(jí)作用域
?
function outputNumbers(count){for (var i=0; i < count; i++){alert(i);}alert(i); //計(jì)數(shù) }通常稱為私有作用域
(function(){//這里是塊級(jí)作用域 })(); function outputNumbers(count){(function () {for (var i=0; i < count; i++){alert(i);}})();alert(i); //導(dǎo)致一個(gè)錯(cuò)誤! }?
私有變量
function MyObject(){//私有變量和私有函數(shù)var privateVariable = 10;function privateFunction(){return false;}//特權(quán)方法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"
靜態(tài)私有變量
?
(function(){//私有變量和私有函數(shù)var privateVariable = 10;function privateFunction(){return false;}//構(gòu)造函數(shù)MyObject = function(){};//公有/特權(quán)方法MyObject.prototype.publicMethod = function(){privateVariable++;return privateFunction();};})();
未經(jīng)聲明的變量,會(huì)創(chuàng)建一個(gè)全局變量
但使用prototype的問題時(shí)實(shí)例變量需要自己定義
(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"
?
模塊模式
單例對(duì)象
var singleton = {name : value,method : function () {//這里是方法的代碼 } };模塊模式通過為單例添加私有變量和特權(quán)方法使其得到增強(qiáng)
var singleton = function(){//私有變量和私有函數(shù)var privateVariable = 10;function privateFunction(){return false;}//特權(quán)/公有方法和屬性return {publicProperty: true,publicMethod : function(){privateVariable++;return privateFunction();}}; }();以這種模式創(chuàng)建的每個(gè)單例都是Object的實(shí)例,因?yàn)樽罱K要通過一個(gè)對(duì)象字面量來(lái)表示它。單例通常作為全局對(duì)象存在,不會(huì)將它傳遞給一個(gè)函數(shù),不會(huì)使用instanceOf來(lái)檢查其對(duì)象類型
?
增強(qiáng)的模塊模式
?
在返回對(duì)象之前加入對(duì)其增強(qiáng)的代碼。適合的場(chǎng)景是單例必須是某種類型的實(shí)例,還必須添加某些屬性或方法對(duì)其增強(qiáng)。
var singleton = function(){//私有變量和私有函數(shù)var privateVariable = 10;function privateFunction(){return false;}//創(chuàng)建對(duì)象var object = new CustomType();//添加特權(quán)/公有屬性和方法object.publicProperty = true;object.publicMethod = function(){privateVariable++;return privateFunction();};//返回這個(gè)對(duì)象return object; }();?
引用:
《JavaScript高級(jí)程序設(shè)計(jì)中文版》
轉(zhuǎn)載于:https://www.cnblogs.com/dopeter/p/6661945.html
總結(jié)
以上是生活随笔為你收集整理的重温Javascript(四)-函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【C++】智能指针简述(五):解决循环引
- 下一篇: AutoMapper之投影