成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

javascript-函數(shù)表達式

bingchen / 2716人閱讀

摘要:函數(shù)表達式定義函數(shù)表達式區(qū)別于函數(shù)聲明,也是一種定義函數(shù)的方式,形似與變量賦值,這個值就是函數(shù)體,例如函數(shù)表達式之匿名函數(shù)函數(shù)表達式之具名函數(shù)匿名函數(shù)之立即執(zhí)行函數(shù)目前知道的是這三種形式,希望高人補充特點區(qū)別于函數(shù)聲明,和普通變量一樣使用前

函數(shù)表達式

定義:函數(shù)表達式區(qū)別于函數(shù)聲明,也是一種定義函數(shù)的方式,形似與變量賦值,這個值就是函數(shù)體,例如:

var a = function(){}; // 函數(shù)表達式之匿名函數(shù)
var a = function fn(){}; // 函數(shù)表達式之具名函數(shù)
(function(){})(); // 匿名函數(shù)之立即執(zhí)行函數(shù)
// 目前知道的是這三種形式, 希望高人補充

特點:
1 . 區(qū)別于函數(shù)聲明,和普通變量一樣使用前必須聲明,不聲明在非嚴格模式下被認為是全局的變量,在嚴格模式下報錯

遞歸

定義:在一個函數(shù)中調(diào)用自身,遞歸必須要有結(jié)束條件階乘

// fibonacci數(shù)列
function fibonacci(n){
  if(n == 1 || n == 2){ // 結(jié)束條件
    return 1;
  }else{
    var num = fibonacci(n-1) + fibonacci(n-2); // 遞歸調(diào)用
    return num // 每一層遞歸都返回和
  }
};
console.log(fibonacci(6)); // 8

特點:
1 . 調(diào)用匿名函數(shù)表達式自身,為了便于維護,可以通過arguments.callee(指向當(dāng)前函數(shù)的指針)來調(diào)用當(dāng)前函數(shù),這樣做的好處是當(dāng)遞歸函數(shù)換名稱時不用更換內(nèi)部的函數(shù)名稱

function fibonacci(n){
  if(n == 1){
    return 1;
  }else{
    var num = arguments.callee(n-1) * n ;
    return num
  }
};
let a = fibonacci;
fibonacci = null;
console.log(a(6)); // 函數(shù)內(nèi)在再次調(diào)用fibonacci就會報錯 Uncaught TypeError: fibonacci is not a function

一變

function fibonacci(n){
  if(n == 1){
    return 1;
  }else{
    var num = arguments.callee(n-1) * n ;
    return num
  }
};
let a = fibonacci;
fibonacci = null;
console.log(a(6)); // 720 但是在嚴格模式下回報錯 Uncaught TypeError: "caller", "callee", and "arguments" properties may not be accessed

二變

"use strict";
let a = (function fibonacci(n){
  if(n == 1){
    return 1;
  }else{
    var num = fibonacci(n-1) * n ;
    return num
  }
});
let b = a;
a=null;
console.log(b(4)); // 24 ,這里相當(dāng)于包了一層,如果外邊的變量改變是不會影響函數(shù)內(nèi)部調(diào)用的

:在嚴格模式下arguments.callee會報錯,可以通過命名函數(shù)表達式來實現(xiàn)

閉包

閉包是指有權(quán)訪問另一個作用域中的變量的函數(shù),形式很多,不舉例了,重點在下面

特點:關(guān)于閉包的特點都得先理解執(zhí)行環(huán)境、作用域、活動對象的概念

執(zhí)行環(huán)境: 函數(shù)被調(diào)用時會創(chuàng)建當(dāng)前函數(shù)的執(zhí)行環(huán)境,可以想象成一個對象,對象包含一個屬性,該屬性指向作用域(作用域鏈表)
作用域,也可以看成是作用域鏈表,一個list,list的元素是指向活動對象,包括本作用域內(nèi)的活動對象的指向和對上級的指向,當(dāng)前函數(shù)執(zhí)行完畢作用域就消失了
活動對象,包含當(dāng)前函數(shù)內(nèi)的所有屬性,當(dāng)沒有作用域鏈引用時活動對象被銷毀

:指向可以理解為引用,像 a=[], a就指向了內(nèi)存中的一個數(shù)組

{                                              
  scope: scopeList              ----|             
}                                   |
執(zhí)行環(huán)境(context)                  |

[                                   |
  activeObj1: activeObjects1,     --|--|
  activeObj2: activeObjects2,     --|--|--|
  ...                               |  |  |
]                                   |  |  |
作用域鏈(scopeList)           <----|  |  |

{                                      |  |  
  var1: 1,                             |  |
  var2: 1,                             |  |
  var1: [],                            |  |
}                                      |  |
活動對象(activeObjects1)           <--|  |

{                                         |
  _var1: 1,                               |
  _var2: 1,                               |
  _var1: [],                              |
}                                         |
活動對象(activeObjects2)              <--|  

// 可以看出執(zhí)行環(huán)境和作用域鏈?zhǔn)且粚σ坏模?所以當(dāng)執(zhí)行完函數(shù)后執(zhí)行環(huán)境就沒了,作用域沒有被引用了就也沒了,但是活動對象和作用域鏈?zhǔn)嵌鄬Χ嗟模ㄍ局兄徽故玖艘粚Χ啵?,所以就算作用域沒了,當(dāng)前作用域的活動對象也可能被其它作用域引用(例如閉包),所以仍然存在于內(nèi)存中
閉包與變量

特點:閉包對外層活動對象是引用不是復(fù)制(也可以說是復(fù)制了引用),這里寫一個親身經(jīng)歷的筆試題

var nAdd = null;
function f(){
  let n = 99;
  nAdd = () => {
   ++n;
  }
  return () => {
   console.log(n);
  }
};
var f1 = f();
var f2 = f();
nAdd();
f1();
f2();
nAdd();
f1();
f2();

我認為這個題挺有意思。這里不給答案,讀者可以自己先猜一下,然后自己跑一下和自己的猜想對對。
我認為這個題目的關(guān)鍵在nAdd是在f函數(shù)的外層,也就是每次實例化這個f函數(shù)都會對nAdd重新賦值,重新賦值后執(zhí)行環(huán)境中n會不同,多次賦值取最后一個,只要能搞清楚執(zhí)行環(huán)境、作用域、活動對象的關(guān)系其實不難,不會也沒關(guān)系,一開始看到我也懵。

關(guān)于this對象

定義:this是和執(zhí)行環(huán)境綁定的

特點:特點和定義息息相關(guān),this和執(zhí)行環(huán)境綁定,只要執(zhí)行完畢執(zhí)行環(huán)境不存在了就,例如:

var name = "china,hebei";
var province = {
  name: "hebei",
  getName: function(){
    return function(){
     return this.name;
    };
  }
};
console.log(province.getName()()); // china,hebei

從結(jié)果來看this指的是全局的那個this,這個和常規(guī)理解不太一樣,按說getName屬于province這個對象,this指向province才對,想想定義就明白了,province.getName()這個執(zhí)行了getName函數(shù),并返回了一個函數(shù)體,再次執(zhí)行這個函數(shù)體的時候getName()已經(jīng)執(zhí)行完了,執(zhí)行完了執(zhí)行環(huán)境當(dāng)然就不存在了,this就返回給執(zhí)行的環(huán)境(全局環(huán)境),那如何改成指向province呢?

var name = "china,hebei";
var province = {
  name: "hebei",
  getName: function(){
    let that = this;
    return function(){
     return that.name;
    };
  }
};
console.log(province.getName()()); // hebei

很容易理解,that在getName執(zhí)行完畢后并不會消失,因為它所在的活動對象還被最后返回的函數(shù)的作用域鏈引用著,所以最后輸出的就是hebei

塊級作用域

定義:通過創(chuàng)建一個立即執(zhí)行函數(shù)來模仿模塊作用域的效果,普通的{}沒有塊級概念

for(var i=0; i<2; i++){
  console.log(i);
}
console.log(i) // 2

塊級作用域,很簡單,通過函數(shù)作用域封裝一層即可,例如

(function(){
  for(var i=0; i<2; i++){
    console.log(i);
  }
})()
console.log(i) // Uncaught ReferenceError: i is not defined
私有變量

定義:在函數(shù)定義的變量和方法都可以看成是私有變量,可以通過在函數(shù)創(chuàng)建閉包實現(xiàn)在函數(shù)外部訪問私有變量,稱之為共有方法(特權(quán)方法),例如:

function Student(){
  var name = "jiang";
  this.getName = function(){
    return name;
  };
};
var xiaoming = new Student();
console.log(xiaoming.getName()); // jiang   只有這種特權(quán)方法可以訪問到

特點:私有變量只能通過特權(quán)方法在函數(shù)外部被訪問
解決的問題:增強函數(shù)的封裝性,函數(shù)作用域內(nèi)得變量只能通過特權(quán)方法訪問
帶來的問題:每個實例都會重新創(chuàng)建一個特權(quán)方法

靜態(tài)私有變量

定義: 在私有作用域內(nèi)(立即執(zhí)行函數(shù))定義函數(shù)內(nèi)的私有變量和全局的(變量沒有聲明就賦值時)匿名函數(shù),為匿名函數(shù)添加原型方法,原型方法內(nèi)訪問函數(shù)內(nèi)的變量,這樣在函數(shù)外部可以可以通過變量名稱直接訪問全局的匿名函數(shù)上的原型方法,方法內(nèi)部可以訪問函數(shù)私有變量

(function(){
  let name = "jiang";
  student = function(){};
  student.prototype.getName = function(){
    return name;
  };
})()
console.log(student.prototype.getName()); // jiang

解決的問題:解決了每個實例都不共享的私有變量和特權(quán)方法的問題

帶來的問題:解決的問題也變成了它自身的問題,最好的方案是私有變量和靜態(tài)私有變量結(jié)合使用

模塊模式

定義:模塊模式就是把私有變量和單例模式結(jié)合起來,在JS中通過字面對象來創(chuàng)建對象是最簡單的單例模式,而私有變量是函數(shù)作用域被的,方法就是定義一個變量(單例對象),然后創(chuàng)建一個立即執(zhí)行函數(shù)返回一個字面對象,對象內(nèi)部創(chuàng)建公共的特權(quán)方法和屬性,函數(shù)內(nèi)部定義私有變量。

單例模式,例如

var a = {};
var a = {}; // 總是只有一個a對象
var a = (function(){
  var name = "jiang"; // 私有變量
  return{ // 單例模式
    getName: function(){
      return name;
    }
  }
})()
console.log(a.getName());

解決的問題:在單例內(nèi)創(chuàng)建私有變量, 單例模式的應(yīng)用場景是需要重復(fù)使用但不需要同時使用的對象,像錯誤提示彈框

帶來的問題:返回的對象是沒有類型的就是不能通過instanceof確認對象類型

增強版的模塊模式

定義:將函數(shù)內(nèi)返回的對象通過構(gòu)造函數(shù)的方式聲明,然后為其添加特權(quán)方法和屬性,然后將對象返回,這樣的對象就可以通過instanceof確認其類型了

var a = (function(){
  var name = "jiang";
  function Student(){};
  var xiaoming = new Student();
  xiaoming.getName = function(){
    return name;
  };
  return xiaoming;
})()

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/100574.html

相關(guān)文章

  • 深入理解javascript中的立即執(zhí)行函數(shù)(function(){…})()

    摘要:要理解立即執(zhí)行函數(shù),需要先理解一些函數(shù)的基本概念。函數(shù)表達式使用關(guān)鍵字聲明一個函數(shù),但未給函數(shù)命名,最后將匿名函數(shù)賦予一個變量,叫函數(shù)表達式,這是最常見的函數(shù)表達式語法形式。 javascript和其他編程語言相比比較隨意,所以javascript代碼中充滿各種奇葩的寫法,有時霧里看花,當(dāng)然,能理解各型各色的寫法也是對javascript語言特性更進一步的深入理解。 ( functio...

    melody_lql 評論0 收藏0
  • JavaScript-立即調(diào)用函數(shù)達式(IIFE)

    摘要:將匿名函數(shù)賦予一個變量,叫函數(shù)表達式,這是最常見的函數(shù)表達式語法形式。組成這是一個被稱為自執(zhí)行匿名函數(shù)的設(shè)計模式,主要包含兩部分。 一、函數(shù)聲明&函數(shù)表達式 1.1 函數(shù)聲明 (函數(shù)語句) showImg(https://segmentfault.com/img/bVbbqvT?w=278&h=166); (1)使用 function 關(guān)鍵字聲明一個函數(shù),再指定一個函數(shù)名,叫函數(shù)聲明。...

    XUI 評論0 收藏0
  • JavaScript 闖關(guān)記

    摘要:對象數(shù)組初始化表達式,闖關(guān)記之上文檔對象模型是針對和文檔的一個。闖關(guān)記之?dāng)?shù)組數(shù)組是值的有序集合。數(shù)組是動態(tài)的,根闖關(guān)記之語法的語法大量借鑒了及其他類語言如和的語法。 《JavaScript 闖關(guān)記》之 DOM(下) Element 類型 除了 Document 類型之外,Element 類型就要算是 Web 編程中最常用的類型了。Element 類型用于表現(xiàn) XML 或 HTML 元素...

    mj 評論0 收藏0
  • 細說 Javascript 函數(shù)篇(一) : 函數(shù)聲明和函數(shù)達式

    摘要:函數(shù)表達式對于函數(shù)聲明,函數(shù)的名稱是必須的,而對于函數(shù)表達式而言則是可選的,因此,就出現(xiàn)了匿名函數(shù)表達式和命名函數(shù)表達式。這是因為對命名函數(shù)處理的機制,函數(shù)的名稱永遠在函數(shù)內(nèi)部的作用域中有效。 function 是 Javascript 中的第一類對象,這就意味著函數(shù)可以像其他值一樣被傳遞。一個最常見的用法就是將一個匿名函數(shù)作為回調(diào)函數(shù)傳遞到另外一個異步函數(shù)中。 函數(shù)聲明 func...

    hizengzeng 評論0 收藏0
  • js中(function(){…})()立即執(zhí)行函數(shù)寫法理解

    摘要:和是兩種立即執(zhí)行函數(shù)的常見寫法,最初我以為是一個括號包裹匿名函數(shù),再在后面加個括號調(diào)用函數(shù),最后達到函數(shù)定義后立即執(zhí)行的目的,后來發(fā)現(xiàn)加括號的原因并非如此。 javascript和其他編程語言相比比較隨意,所以javascript代碼中充滿各種奇葩的寫法,有時霧里看花,當(dāng)然,能理解各型各色的寫法也是對javascript語言特性更進一步的深入理解。 ( function(){…} )...

    YJNldm 評論0 收藏0
  • JavaScript 面向?qū)ο箝_發(fā)知識總結(jié)基礎(chǔ)篇

    摘要:字面形式允許你在不需要使用操作符和構(gòu)造函數(shù)顯式創(chuàng)建對象的情況下生成引用值。操作符以一個對象和一個構(gòu)造函數(shù)作為參數(shù)鑒別數(shù)組有前一小結(jié)可以知道鑒別數(shù)組類型可以使用。屬性是函數(shù)獨有的,表明該對象可以被執(zhí)行。這種函數(shù)被稱為匿名函數(shù)。 引子: 1.JavaScript 中的變量類型和類型檢測 1.1原始類型 1.2引用類型 1.3內(nèi)建類型的實例化 1.4函數(shù)的字面形式 1.5正則表達式的字...

    Kross 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<