主頁 > 企業開發 > JavaScript函式

JavaScript函式

2021-02-15 06:19:23 企業開發

 

1.1 JS continue 陳述句

定義和用法

  • continue 用于跳過回圈中的一個迭代,并繼續執行回圈中的下一個迭代,

  • continuebreak 陳述句的區別是:break 是結束整個回圈體,continue是結束單次回圈,

但是,在執行 continue 陳述句時,表現出了兩種不同型別的回圈:

  1. while 回圈中,會先判斷條件,如果條件為 true,回圈再執行一次,

  2. for回圈中,自增長運算式(如:i++)會先計算,然后再判斷條件是否為true,再決定是否執行迭代,

continue 陳述句可應用于可選的標簽參考,

注意: continue 陳述句(不帶標簽參考),只能用在回圈或 switch 中,

回圈代碼塊,在 i 的值等于 "3" 時跳過當前回圈:

2.1 JS break 陳述句

定義和用法

  1. 回圈代碼塊,break在變數 i 為 "3" 時退出回圈:

  2. break 陳述句用于退出 switch 陳述句或回圈陳述句(for, for ... in, while, do ... while),

  3. 當 break 陳述句用于 switch 陳述句中時,會跳出 switch 代碼塊,終止執行代碼,

  4. 當 break 陳述句用于回圈陳述句時,會終止執行回圈,并執行回圈后代碼(如果有的話),

  5. break 陳述句同樣可用于可選的標簽參考,用于跳出代碼塊,

注意: break 陳述句(不帶標簽參考),只能用在回圈或 switch 中,

3.1 JS arguments 物件

定義和用法

arguments是函式里的 可以通過陣列下標的形參訪問函式實參值
arguments物件 沒有表示引數集合,而是一個偽類陣列
arguments物件是 所有(非箭頭)函式中都可用的區域變數
此物件包含傳遞給函式的每個引數 第一個引數在索引0處,
你可以使用arguments物件在函式中參考函式的引數,


例如,如果一個函式傳遞了三個引數,你可以如下方式參考他們:

  1. arguments[0]

  2. arguments[1]

  3. arguments[2]

求平均值:

function avg() {
  var num = 0, j = 0;
  for (let i = 0; i <= arguments.length; i++) {
    if (typeof arguments[i] != 'number')
             continue;
         num += arguments[i];
             j++;
           }
             num /= 1;
             return num;
         }
 document.write(avg(1, 2, 3, 4)); 

3.1.1 callee回呼函式

       它如果和callee屬性一起使用的話,利用它可以設計函式迭代操作,使用arguments.callee可以獲取匿名函式,最后比較實參和形參的

個數以檢測用戶傳遞的引數是否符合要求,如果不是匿名函式的話,則arguments.callee等價于函式名f())

語法:

 [function.]arguments.callee 
可選項 function 引數是當前正在執行的 Function 物件的名稱,

說明:

callee 屬性的初始值就是正被執行的 Function 物件,

       callee 屬性是 arguments 物件的一個成員,是arguments的屬性,該屬性是一個指標,指向擁有arguments物件的函式,這有利于匿

名函式的遞回或確保函式的封裝性,例如下邊示例的遞回計算1到n的自然數之和,而該屬性僅當相關函式正在執行時才可用,更有需要注意

的是callee擁有length屬性,這個屬性有時候用于驗證還是比較好的,arguments.length是實參度,arguments.callee.length是形參長

度,由此能夠判斷呼叫時形參長度是否和實參長度一致,

function calleeDemo() {
   alert(arguments.callee);
}

3.1.2 throw new Error()方法:在控制臺里拋出錯誤提示,

throw 陳述句允許我們創建自定義錯誤,正確的技術術語是:創建或拋出例外(exception),

       如果把 throwtry catch 一起使用,那么您能夠控制程式流,并生成自定義的錯誤訊息,例外可以是 JavaScript 字串、數字、

邏輯值或物件,

  throw new Error('傳遞的引數不匹配'); 

3.1.3 search() 搜索

search() 方法 用于檢索字串中指定的子字串,或檢索與正則運算式相匹配的子字串
search() 方法 執行正則運算式和 String 物件之間的一個搜索匹配


        當你想要知道字串中是否存在某個模式(pattern)時可使用 search(),類似于正則運算式的 test() 方法,當要了解更多匹配資訊

時,可使用 match()(但會更慢一些),該方法類似于正則運算式的 exec() 方法,

語法

 stringObject.search(regexp) 

引數

描述

regexp

該引數可以是需要在 stringObject 中檢索的子串,也可以是需要檢索的 RegExp 物件,

注釋:要執行忽略大小寫的檢索,請追加標志 i,

回傳值

stringObject 中第一個與 regexp 相匹配的子串的起始位置,

注釋:如果沒有找到任何匹配的子串,則回傳 -1,

說明

       search() 方法不執行全域匹配,它將忽略標志 g,它同時忽略 regexp lastIndex 屬性,并且總是從字串的開始進行檢索,這

意味著它總是回傳 stringObject 的第一個匹配的位置,

特別說明:

  1. 字串中字符的位置與陣列類似,都是從0開始的,

  2. searchValue不但可以是普通字串,也可以是正則運算式,

function isEmail() {
            if (arguments.length > 1) {
                throw new Error('你只能傳遞一個引數');
            }
            var regexp = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;
            if (arguments[0].search(regexp) != -1) {
                return true;
            } else {
                return false;
            }
        }
        var email = '[email protected]';
        if (isEmail(email)) {
            document.write(email);
        } else {
            document.write('請您重新輸入郵箱地址');
        }

4.1 使用函式物件

4.1.1 獲取函式形參個數

  1. 獲取函式的實參個數:使用arguments物件的length屬性,僅能夠在函式體內使用,

  2. 獲取形參的個數使用函式名.length或者a.callee.length,function物件的length屬性在函式體內外都可以使用.

function check(a) {
if (a.length != a.callee.length) {
throw new Error('引數不一致');
}
}
function f(a, b, c, d) {
check(arguments);
return (a + b + c + d)
}
document.write(f(3, 4))

4.2.1 自定義屬性

  1. 用戶可以通過點語法為函式定義靜態屬性和方法,

  2. 函式屬性可以在函式體內定義,只能在內部呼叫;函式屬性也可以在函式體外定義,在外部呼叫,

  3. 函式方法可以在內部或外部定義,不管在內部或外部定義都可以呼叫此函式方法,

  4. 用戶不妨為函式定義屬性,然后利用函式屬性實作函式每次回傳低增值,

function f() {
return f.x++;
}
f.x = 0;
for (var i = 0; i < 10; i++) {
document.write(f());
}

4.call()和apply()函式

call()apply()是function物件的原型方法,把一個函式當做一個方法系結到指定物件上并進行呼叫,

具體用法如下:

 function.call(thisobj,args...) 

 function.apply(thisobj,args) 

       其中引數thisobj表示指定的物件,引數args表示要傳遞給被呼叫函式的引數,而call()方法只能接受多個引數串列,apply()只能接受一個陣列

或偽陣列,陣列元素將作為引數傳遞給被呼叫的函式,

代碼如下:

function f(x, y) {
return x + y;
}
function o(a, b) {
return a * b;
}
document.write(f.call(o, 3, 4));

使用call()和apply()方法可以把一個函式轉換為指定物件的方法,并在這個物件上臨時系結呼叫該方法,

提示:它們能夠動態改變函式內this指代的物件,這在面向物件編程中是非常有用的,

4.3.1 call()和apply()區別如下:

  1.  call()和apply()傳遞給引數的方式不同,

  2.  apply()是以陣列形式傳遞引數,

  3. call()方法以多個值的形式傳遞引數,

代碼如下:

function r(x) {
return (x);
}
function f(x) {
x[0] = x[0] + '>';
return x;
}
function o() {
var temp = r;
r = function () {
return temp.apply(this, f(arguments));
}
}
function a() {
o();
document.write(r('='));
}
for (var i = 0; i < 10; i++) {
a();
}

4.4 使用bind()

函式function增加了一個原型方法bind(),是指用來把函式系結到指定物件上,

具體用法如下:

 function.bind(thisArg[,arg1[,arg2[,argN]); 

引數說明如下:

function

必須引數,一個函式物件

thisArg

必須引數,this關鍵字可在新函式中參考的物件

arg1[,arg2[,argN]]

可選引數,要傳遞到新函式的引數的串列,

bind方法將回傳與函式相同的新函式不會立即執行,等需要的時候才會執行該新函式,bind()方法也可以多個或兩個傳遞引數值,

var displayArgs = function (val1, val2, val3, val4) {
document.write(val1 + '<br> ' + val2 + ' <br>' + val3 + '<br> ' + val4 + '<br> ');
}
var emptyObject = {};
var displayArg2 = displayArgs.bind(emptyObject, '姓名:' + '張亮', '年齡:' + 25 + '歲');
displayArg2('身高:' + 180 + 'cm', '民族:' + ' ' + '漢族');

4.4.1 JavaScript trim() 方法

語法

 string.trim() 

定義和用法

trim()

方法用于洗掉字串的頭尾空格,

trim()

方法不會改變原始字串,

實體:

去除字串的頭尾空格:

function myTrim(x) {

return x.replace(/^\s+|\s+$/gm,'');

}
 function myFunction() {
var str = myTrim(" Runoob ");
alert(str);
}

5.1 使用this

this的定義:

this是函式體內自帶的一個物件指標,this指向當前呼叫函式的那個物件,或者指向類的當前實體,

this的特點:

  1. 在function內部被創建

  2. 指向呼叫時所在函式所系結的物件(拗口)

  3. this 不能被賦值,但可以被 call/apply  改變

this的用途:這里把它所有用到的地方列出

  1. this 和構造器
function Tab(nav, content) {
    this.nav = nav
    this.content = content
}
Tab.prototype.getNav = function() {
    return this.nav;
};

      2. this 和物件

var tab = {
    nav: '',
    content: '',
    getNav: function() {
        return this.nav;
    },
    setNav: function(n) {
        this.nav = n;
    }
}

      3. this 和函式

function showMsg() {
    alert(this.message)
}
var m1 = {
    message: '輸入的電話號碼不正確'
}
var m2 = {
    message: '輸入的身份證號不正確'
}
showMsg.call(m1) // '輸入的電話號碼不正確'
showMsg.call(m2) // '輸入的身份證號不正確'

     4. 全域環境的 this

var x = 10;
function func() {
    alert(this.x)
}
var obj = {
    x: 20,
    fn: function() {
        alert(this.x)
    }
}
var fn = obj.fn
func() // 10
fn() // 10

       沒錯,最終輸出的都是全域的10,永遠記住這一點:判斷 this 指向誰,看執行時而非定義時,只要函式(function)沒有系結在物件上呼叫,它的

this就是window,

     5. this 和 DOM/事件

 <div id="nav" onclick="getId()">ddd</div> 

<script>
function getId() {
   alert(this.id)
}
</script>

       點擊 div 后,為什么 id 是 undefined,不說是指向的當前元素 div 嗎?如果記住了前面提到的一句話,就很清楚為啥是 undefined,把這句話再貼出來,判斷 this 指向誰,看執行時而非定義時,只要函式(function)沒有系結在物件上呼叫,它的 this 就是 window,

這里函式getId呼叫時沒有系結在任何物件上,可以理解成這種結構:

div.onclick = function() {
    getId()
}

getId 所處匿名函式里的 this 是 div,但 getId 自身內的 this 則不是了,當然 ES5 嚴格模式下還是有個坑,

6. this 可以被 call/apply/bind 改變

var m1 = {
    message: 'This is A'
}
var m2 = {
    message: 'This is B'
}  
function showMsg() {
    alert(this.message)
}
showMsg() // undefined
showMsg.call(m1) // 'This is A'
showMsg.call(m2) // 'This is B'

7.  me/self/that/_this 暫存 this

       如果采用 OOP 方式寫 JS 代碼,無可避免的會用到 this,方法內會訪問類的內部屬性(欄位),也可能會呼叫類的另一個方法,當類的方法內又有一個 function 時,比如瀏覽器端開發經常遇見的給 DOM 元素添加事件,這時如果事件處理器(handler)中的想呼叫類的一個方法,此時 handler 內的 this 是 dom 元素而非類的當前物件,這個時候,需要把 this 暫存,開發者發揮著自己的聰明才智留下了幾種經典的命名 me, self, that, _this

如:一般會在每個方法的第一句就把 this 暫存下來,

8. ES5 中新增的 bind 和 this

var modal = {
    message: 'This is A'
}
function showMsg() {
    alert(this.message)
}
var otherShowMsg = showMsg.bind(modal)
otherShowMsg() // 'This is A'

bind 只是 call/apply 的高級版,其它沒什么特殊的,

9.  ES6 箭頭函式(arrow function) 和 this

var book = {
    author: 'John Resig',
    init:  function() {
        document.onclick = ev => {
            alert(this.author) ; // 這里的 this 不是 document 了
        }
    }
};
book.init()

       物件 book 里有一個屬性 author, 有一個 init 方法, 給 document 添加了一個點擊事件,如果是傳統的函式,我們知道 this 指向應該是 document,但箭頭函式會指向當前物件 book,

       箭頭函式讓 JS 回歸自然和簡單,函式定義在哪它 this 就指向哪,定義在物件里它指向該物件,定義在類的原型上,就指向該類的實體,望文知意這樣更容易理解,

總結:

       函式的背景關系 this 是 JS 里不太好理解的,在于 JS 函式自身有多種用途,目的是實作各種語言范型(面向物件,函式式,動態),this 本質是和面向物件聯系的,和寫類,物件關聯一起的, 和“函式式”沒有關系的,如果你采用程序式函式式開發,完全不會用到一個 this, 但在瀏覽器端開發時卻無可避免的會用到 this,這是因為瀏覽器物件模型(DOM)本身采用面向物件方式開發,Tag 實作為一個個的類,類的方法自然會參考類的其它方法,參考方式必然是用 this,當你給DOM物件添加事件時,回呼函式里參考該物件就只能用 this 了,

六、使用閉包函式

閉包是Js的重要特性之一,在程式中有至關重要的作用,

Js函式能夠記住自己定義時所處的作用域,即使函式不在此作用域運行,依然可以訪問此作用域中的變數,

6.1認識閉包函式

閉包函式就是嵌套結構的函式,

閉包函式需要滿足下面3個條件:

① 在一個函式(含有私有變數或區域變數)內定義的一個函式,也就是嵌套,

② 內部函式應該訪問外部函式中宣告的私有變數、引數或其他內部函式,

③ 如果在外部函式呼叫這個內部函式,它就成為了閉包函式,

下面是一個經典閉包結構:

function f(x) {
var a = x;
var c=1;
var b = function () {
return a;//形成一個閉包
};
a++;
return b;
}
var c = f(5);
document.write(c());

------------------------

如果沒有閉包函式的作用,這種資料寄存和傳遞無法實施:

function f(x) {
var a = x;
var b = a;
a++;
return b;
}
var c = f(5);
document.write(c);

當該函式時(f())不管是數字幾賦值給c后進行呼叫,該是多少就是多少這個‘數’,不能實時監測這個變數的變化,

注意:一但函式被呼叫執行,則閉包體也會隨之誕生,

閉包函式被再次執行或者通過某種方法進入函式體時,就可以獲取閉包函式內包含的資訊,

       簡單的描述:閉包可以說是函式的資料包、存盤資料,這個資料包在函式執行程序中始終處于激活狀態,只有呼叫函式閉包才能生效,當函式呼叫回傳之后,閉包保存下來與內部函式關聯的變數的動態聯系(幫助監測),

下面是閉包和閉包常用場景

  1.        作用域(受javascript鏈式作用域結構的影響,父級變數中無法訪問到子級變數的值,為了解決這個問題,才使用的閉包,)閉包就是能夠讀取其他函式內部變數的函式,(在JS中,只有函式內部的子函式才能讀取區域變數,因此可以把閉包簡單理解為”定義在一個函式內部的函式”,無論是在事件中,for回圈中,還是在函式自呼叫中,只要return出來,便有閉包的應用),

  2.        閉包會把函式中變數的值保存下來,供其他函式使用,這些變數會一直保存在記憶體當中,這樣占用大量的記憶體,使用不當很可能造成記憶體泄漏,故要及時清除,清楚方法有兩種,一是標記清除,二便是參考計數清除,

  3.  閉包的常用場景有一是函式作為回傳值,二是函式作為引數來傳遞,不適用于回傳閉包的函式是個特別大的函式,很多高級應用都要依靠閉包實作.

  4.  使用閉包的好處是不會污染全域環境,方便進行模塊化開發,減少形參個數,延長了形參的生命周期,壞處就是不恰當使用會造成記憶體泄漏,

6.2 使用閉包

下面通過幾個示例介紹閉包的簡單使用,更直觀的理解什么是閉包以及閉包的函式的作用和用法,

用法1:使用閉包結構能夠跟蹤動態環境中的實時變化,并即時存盤,

function f() {
var a = 1;
Var b = function () {
return a;
}
a++;
Return b;
}
var c=f();
document.write(c());

用法2:閉包不會因為外部函式環境的注銷而消失,而是始終存在,

function f() {
var a = 1;
b = function () {
alert(a);
}
c = function () {
a++;
}
d = function (x) {
a = x;
}
}
<button onclick="f()">按鈕1:(f())</button><br>
<button onclick="b()">按鈕2:(b=function(){alert(a);})()</button><br>
<button onclick="c()">按鈕3:(c=function(){a++;})()</button><br>
<button onclick="d(100)">按鈕4:(d=function(x){a=x;})(100)</button><br>

用法3:如何利用閉包存盤變數所有變化的值,

function f(x) {
var a = [];
for (var i = 0; i < x.length; i++) {
var temp = x[i];
a.push(function () {
document.write(temp + ' ' + x[i])
});
}
return a;
}
function e() {
var a = f(['a', 'b', 'c']);
  for (var i = 0; i < a.length; i++) {
a[i]();
}
}
e();

6.3 定義閉包存盤器

閉包常見的用法就是為要執行的函式提供引數,

比如:

為事件屬性傳遞動作

為定時器函式傳遞行為等

這在web前端中非常常見的一種應用,

用法1:

function f(a, b) {
return function () {
a(b);
}
}
var c = f(alert, '愛前端');
var d = setTimeout(c, 1000);

閉包其實還可以用于創建額外的作用域,通過該作用域就可以設計動態資料管理器,

用法2:下面的例子如何使用閉包作為值來進行傳遞,

function f(a, b) {
return function () {
a(b);
}
}
var c = f(alert, '我在家學習和鍛煉!');
window.onload = c;

用法3:下面通過閉包可以使作為緩沖器的陣列與依賴它的函式關聯起來,實施優雅的打包,

var f = function () {
var a = [1, 3, 5, 7, 9, 2, 4, 6, 8, 10];
return function (a1, a2, a3, a4, a5) {
a[0] = a1;
a[1] = a2;
a[2] = a3;
a[3] = a4;
a[4] = a5;
return a.join(',');
};
}();
var a = f(12, 14, 16, 18, 20);
var b = f(11, 13, 15, 17, 19);
document.write(a + '<br>');
document.write(b + '<br>');

6.4 在事件處理中應用閉包

很多時候我們希望參考一個函式后能暫停執行,因為在復雜的環境中不等到執行的時候是很難知道具體引數的,而先前被參考時更是無法預知所要傳遞的引數,

下面用法:希望為頁面中特定的元素或標簽系結幾個事件,使其能夠在滑鼠經過、滑鼠移開和滑鼠單擊時呈現不同的背景顏色,

<p>p1</p>
<p>p2</p>
<p>p3</p>
<script>
function f(o, m) {
return function (e) {
e = e || window.event;
return o[m](e, this);
}
}
function g(id) {
return function () {
var e = document.getElementsByTagName(id);
if (e) {
for (var i in e) {
e[i].onclick = f(g, 'click');
e[i].onmouseover = f(g, 'over');
e[i].onmouseout = f(g, 'out');
}
}
}
}
g.click = function (event, element) {
element.style.backgroundColor = 'red';
}
g.over = function (event, element) {
element.style.backgroundColor = 'orange';
}
g.out = function (event, element) {
element.style.backgroundColor = 'green';
}
window.onload = g('p');
</script>

七、實戰案例

7.1系結函式

       函式系結就是為了糾正函式的執行背景關系,特別是當函式中帶有this關鍵字的時候,這一點尤其重要,稍微不小心,就會使函式的執行背景關系發生跟預期不同的改變,導致代碼執行上的錯誤,

函式系結具有3個特征:

函式系結要創建一個函式,可以在特定環境中以指定引數呼叫另一個函式,

一個簡單的bind()函式接受一個函式和一個環境,回傳一個在給定環境中呼叫給定函式的函式

并且將所有引數原封不動的傳遞過去,

被系結函式與普通函式相比有更多的開銷,它們需要更多記憶體,同時也因為多重呼叫而稍微

慢一點,所以最好只在必要時使用,

 

var handler = {
messge: '學習js語言',
handlerClick: function (event) {
document.write(this.messge);
}
};
var btn = document.getElementsByTagName('my-btn');
EventUtil.addHandler(btn, 'clck', bind(handler.handlerClick, handler));

7.2 鏈式語法

        因為 jQuery 庫的緣故,(Jquery最大的亮點就是它的鏈式語法)鏈式語法在前端界變得非常流行,實際上這是一種非常容易實作的模式,基本上,你只需要讓每個函式回傳 'this',這樣其他函式就可以立即被呼叫,它也是點語法,

下面用法:

Function.prototype.method = function (name, func) {
if (!this.prototype[name]) {
this.prototype[name] = func;
return this;
}
};
String.method('trom', function () { return this.replace(/^\s+|\s+$/g, ''); }); String.method('writeln', function () { document.write(this); return this; }); String.method('alert', function () { console.log((this)); return this; }); var str = '黃靜遠'; str.trim().writeln().alert();

7.3 函式節流

函式節流的設計思想就是讓某些代碼可以在間斷情況下連續重復執行,實作的方法是使用定時器對函式進行節流,

下面用法:

function throttle(method, context) {
clearTimeout(method.tId);
method.tId = setTimeout(function () {
method.call(context);
}, 100);
}

需要注意的一點:函式的節流是通過減少實際邏輯處理程序的執行來提高事件處理函式運行性能的手段,并沒有實質上減少事件的觸發次數,

7.4 柯里化

柯里化又稱為部分求值,柯里化是把多個引數函式變換成接收一個單一的引數函式,并且回傳一個新函式,而這個函式新函式能夠接收原函式的引數,

下面用法:

function add(a) {
    // 瘋狂的回呼
    return function(b) {
        return function(c) {
            return function(d) {
                   // return a + b + c + d;
                   return [a, b, c, d].reduce(function(v1, v2) {
                       return v1 + v2;
                   });
            }
        }
    }
}
console.log(add(1)(2)(3)(4)); // 10

柯里化有3個常見作用:

  1. 引數復用

  2.  提前回傳

  3.  延遲計算/運行

7.5 遞回

  • 遞回是函式對自身的呼叫,遞回做為一種演算法在程式設計語言中廣泛應用,

  • 一個程序或函式在其定義或說明中有直接或間接呼叫自身的一種方法,它通常把一個大型復雜的問題層層轉化為一個與原問題相似的規模較小的問題來求解,

  • 遞回策略只需少量的程式就可描述出解題程序所需要的多次重復計算,大大地減少了程式的代碼量,

  • 遞回的能力在于用有限的陳述句來定義物件的無限集合,

  • 一般來說,遞回需要有邊界條件、遞回前進段和遞回回傳段,當邊界條件不滿足時,遞回前進;當邊界條件滿足時,遞回回傳,

遞回演算法解決問題的特點:   

  1.  遞回就是方法里呼叫自身,   

  2.    在使用遞增歸策略時,必須有一個明確的遞回結束條件,稱為遞回出口,                 

  3.  遞回演算法解題通常顯得很簡潔,但遞回演算法解題的運行效率較低,所以一般不提倡用遞回演算法設計程式,

  4.  在遞回呼叫的程序當中系統為每一層的回傳點、區域量等開辟了堆疊來存盤,遞回次數過多容易造成堆疊溢位等,所以一般不提倡用遞回演算法設計程式,

任何有意義的遞回總是兩部分組成的:

遞回呼叫

遞回終止條件

7.5.1遞回運算

       遞回運算在無限制的情況下,會無休止地自身呼叫,顯然,程式不應該出現這種無休止的遞回呼叫,而只應出現有限次數的有終止的呼叫,

為此一般在遞回運算中結合if陳述句來進行控制,

遞回演算法的特點:

  1. 在函式程序中呼叫自身,

  2. 在遞回程序中,必須有一個明確的條件判斷遞回的結束,既遞回出口,

  3. 遞回演算法簡潔但效率低,通常不作為推薦演算法,

用法1 :看電影不知道在第幾排,看電影時不清楚自己在第幾排,可以通過問前一排的人來得知,進行加1即可,

function fn = (n) {
    if(n< = 0) return '座位不存在'
    if(n>1) {
    return fn(n-1)+1
    } else {
    return 1
    }
}

用法2 :走格子有多少走法,一共有n格,每步可以走1格或者2格,問一共有多少走法,

       首先分解問題是第n格可以是前面n-1格走的,也可能是n-2格走的,所以fn(n) = f(n-1) + f(n-2)

也要知道終止條件是只有1步,那么只有一步的可能情況是還有1格,也可能是還有2格,

function fn = (n){
  if(n>2){
return fn(n-1) + fn(n-2)
} else if(n==2)   {
return 2
} else {
return 1
}
}

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/259667.html

標籤:其他

上一篇:JavaScript事件處理

下一篇:【原】無腦操作:Centos 7.6 + MariaDB + Rsyslog + LogAnalyzer環境搭建

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more