js之重载
在面向?qū)ο笳Z言中,?重載就是一組具有相同名字、不同參數(shù)列表的函數(shù),但在js中,重載的實現(xiàn)不能像js一樣那么簡單,因為js名字相同的函數(shù)會相互覆蓋,這樣只能輸出最后一個同名函數(shù),哪怕參數(shù)不一樣,那我們怎樣才能做到重載呢,
首先我們可以利用js的函數(shù)中一個參數(shù),arguments,該參數(shù)有個屬性,length, 根據(jù)參數(shù)組的長度不同,我們可以做出相應(yīng)的動作,從而達到重載的目的
function add(){var len = arguments.length; var a = arguments[0];var b = arguments[1];var c = arguments[2];switch(len){case 1:console.log(a);break;case 2:console.log(a+b);break;case 3:console.log(a+b+c);break; default:break;}}add(1); //1add(1,2); //3add(1,2,3); // 6如上面的代碼,如果我們將add 函數(shù)傳進來的參數(shù)進行判斷,如果與條件相符,我們就做出相應(yīng)的動作,這種方法通俗易懂,如果以后面試問道重載可以回答一下,但這樣代碼的利用性太低,多個函數(shù)需要重復(fù)多次,我們下面講一個JQuery之父John Resig寫的重載
function addMethod(object, name, fn) {var old = object[name]; object[name] = function() {console.log(arguments);console.log(fn.length);if(fn.length === arguments.length) {return fn.apply(this, arguments);} else if(typeof old === "function") {return old.apply(this, arguments);}}console.log(object[name]);}這是一個關(guān)鍵的方法,他有三個參數(shù),第一個是指定的對象,第二個是指定對象要重載的方法,第三個是實際重載方法中要執(zhí)行的方法,這樣說有點繞口,下面來看代碼
var people = {values: ["Dean Edwards", "Alex Russell", "Dean Tom"]};addMethod(people, "find", function() {return this.values;});// 這里進行第一次函數(shù)綁定,對people這個對象進行綁定find函數(shù),我們根據(jù)上面的代碼可知,此時的old 為undefined
此時的people.find()被構(gòu)造成一下函數(shù)
function() { console.log(arguments);console.log(fn.length);if(fn.length === arguments.length) {return fn.apply(this, arguments);} else if(typeof old === "function") {return old.apply(this, arguments); } }
?然后我們進行第二次綁定
addMethod(people, "find", function(firstName) {var ret = [];for(var i = 0; i < this.values.length; i++) {if(this.values[i].indexOf(firstName) === 0) {ret.push(this.values[i]);}}return ret;});此時進行綁定時,old 變量這時候就變?yōu)榱说谝粋€people.find();函數(shù),那么下次被調(diào)用時,第一個addMethod所綁定的people.find()函數(shù)就會存在內(nèi)存中,這里巧妙的利用了閉包,將三個find函數(shù)保存在不同的內(nèi)存空間中,其中的old變量會指向上一個的people.find函數(shù)
從而,一直往上訪問,知道訪問到第一個的old ,下面是完整的代碼。
function addMethod(object, name, fn) {var old = object[name]; object[name] = function() {console.log(arguments);console.log(fn.length);if(fn.length === arguments.length) {return fn.apply(this, arguments);} else if(typeof old === "function") {return old.apply(this, arguments);}}console.log(object[name]);}var people = {values: ["Dean Edwards", "Alex Russell", "Dean Tom"]};/* 下面開始通過addMethod來實現(xiàn)對people.find方法的重載 */// 不傳參數(shù)時,返回peopld.values里面的所有元素addMethod(people, "find", function() {return this.values;});// 傳一個參數(shù)時,按first-name的匹配進行返回addMethod(people, "find", function(firstName) {var ret = [];for(var i = 0; i < this.values.length; i++) {if(this.values[i].indexOf(firstName) === 0) {ret.push(this.values[i]);}}return ret;});// 傳兩個參數(shù)時,返回first-name和last-name都匹配的元素addMethod(people, "find", function(firstName, lastName) {var ret = [];for(var i = 0; i < this.values.length; i++) {if(this.values[i] === (firstName + " " + lastName)) {ret.push(this.values[i]);}}return ret;});// 測試:console.log(people.find()); //["Dean Edwards", "Alex Russell", "Dean Tom"]console.log(people.find("Dean")); //["Dean Edwards", "Dean Tom"]console.log(people.find("Dean","Edwards")); //["Dean Edwards"]*/當(dāng)我們調(diào)用people.find();時會首先在addMethod所綁定的第三個people.find()中尋找,此時,fn.length就是期望函數(shù)的參數(shù),而arguments.length是我們調(diào)用函數(shù)的參數(shù),第一個調(diào)用函數(shù)的參數(shù)為0;而第三個所綁定的find函數(shù)參數(shù)為2個,所以不相等,我們就會向上找
old的所指向的第二個綁定函數(shù),以此類推,直到找到與之相匹配的,然后就用apply函數(shù)改變調(diào)用函數(shù)的上下文,并且傳入相關(guān)參數(shù)進行輸出。
轉(zhuǎn)載于:https://www.cnblogs.com/maoxiaodun/p/10021609.html
總結(jié)
- 上一篇: Qt Creator快捷键
- 下一篇: 一个文章表的 MySQL 索引怎么建立合