2020-01-20

JavaScript 函數(shù)定義

JavaScript 使用關(guān)鍵字 function 定義函數(shù)坷牛。

函數(shù)可以通過聲明定義亲桥,也可以是一個(gè)表達(dá)式轩娶。

函數(shù)聲明

function functionName(parameters) {

? 執(zhí)行的代碼

}

函數(shù)聲明后不會(huì)立即執(zhí)行魄缚,會(huì)在我們需要的時(shí)候調(diào)用到。

實(shí)例

function myFunction(a, b) {

? ? return a * b;

}

分號是用來分隔可執(zhí)行JavaScript語句喜滨。

由于函數(shù)聲明不是一個(gè)可執(zhí)行語句捉捅,所以不以分號結(jié)束。

函數(shù)表達(dá)式

JavaScript 函數(shù)可以通過一個(gè)表達(dá)式定義虽风。

函數(shù)表達(dá)式可以存儲(chǔ)在變量中:

實(shí)例

var x = function (a, b) {return a * b};

在函數(shù)表達(dá)式存儲(chǔ)在變量后棒口,變量也可作為一個(gè)函數(shù)使用:

實(shí)例

var x = function (a, b) {return a * b};

var z = x(4, 3)

以上函數(shù)實(shí)際上是一個(gè) 匿名函數(shù) (函數(shù)沒有名稱)。

函數(shù)存儲(chǔ)在變量中辜膝,不需要函數(shù)名稱无牵,通常通過變量名來調(diào)用。

上述函數(shù)以分號結(jié)尾厂抖,因?yàn)樗且粋€(gè)執(zhí)行語句茎毁。

Function() 構(gòu)造函數(shù)

在以上實(shí)例中,我們了解到函數(shù)通過關(guān)鍵字 function 定義忱辅。

函數(shù)同樣可以通過內(nèi)置的 JavaScript 函數(shù)構(gòu)造器(Function())定義七蜘。

實(shí)例

var myFunction = new Function("a", "b", "return a * b");

var x = myFunction(4, 3);

實(shí)際上,不必使用構(gòu)造函數(shù)墙懂。上面實(shí)例可以寫成:

實(shí)例

var myFunction = function (a, b) {return a * b};

var x = myFunction(4, 3);

在 JavaScript 中橡卤,很多時(shí)候,需要避免使用 new 關(guān)鍵字损搬。

函數(shù)提升(Hoisting)

提升(Hoisting)是 JavaScript 默認(rèn)將當(dāng)前作用域提升到前面去的的行為碧库。

提升(Hoisting)應(yīng)用在變量的聲明與函數(shù)的聲明。

因此巧勤,函數(shù)可以在聲明之前調(diào)用:

myFunction(5);

function myFunction(y) {

? ? return y * y;

}

使用表達(dá)式定義函數(shù)時(shí)無法提升嵌灰。

自調(diào)用函數(shù)

函數(shù)表達(dá)式可以 "自調(diào)用"。

自調(diào)用表達(dá)式會(huì)自動(dòng)調(diào)用踢关。

如果表達(dá)式后面緊跟 () 伞鲫,則會(huì)自動(dòng)調(diào)用。

不能自調(diào)用聲明的函數(shù)签舞。

通過添加括號秕脓,來說明它是一個(gè)函數(shù)表達(dá)式:

實(shí)例

(function () {

? ? var x = "Hello!!";? ? ? // 我將調(diào)用自己

})();

以上函數(shù)實(shí)際上是一個(gè) 匿名自我調(diào)用的函數(shù) (沒有函數(shù)名)。

函數(shù)可作為一個(gè)值使用

JavaScript 函數(shù)作為一個(gè)值使用:

function myFunction(a, b) {

? ? return a * b;

}

var x = myFunction(4, 3);

JavaScript 函數(shù)可作為表達(dá)式使用:

實(shí)例

function myFunction(a, b) {

? ? return a * b;

}

var x = myFunction(4, 3) * 2;

函數(shù)是對象

在 JavaScript 中使用 typeof 操作符判斷函數(shù)類型將返回 "function" 儒搭。

但是JavaScript 函數(shù)描述為一個(gè)對象更加準(zhǔn)確吠架。

JavaScript 函數(shù)有 屬性 和 方法。

arguments.length 屬性返回函數(shù)調(diào)用過程接收到的參數(shù)個(gè)數(shù):

實(shí)例

function myFunction(a, b) {

? ? return arguments.length;

}

toString() 方法將函數(shù)作為一個(gè)字符串返回:

實(shí)例

function myFunction(a, b) {

? ? return a * b;

}

var txt = myFunction.toString();

函數(shù)定義作為對象的屬性搂鲫,稱之為對象方法傍药。

函數(shù)如果用于創(chuàng)建新的對象,稱之為對象的構(gòu)造函數(shù)魂仍。

箭頭函數(shù)

ES6 新增了箭頭函數(shù)拐辽。

箭頭函數(shù)表達(dá)式的語法比普通函數(shù)表達(dá)式更簡潔。

(參數(shù)1, 參數(shù)2, …, 參數(shù)N) => { 函數(shù)聲明 }

(參數(shù)1, 參數(shù)2, …, 參數(shù)N) => 表達(dá)式(單一)

// 相當(dāng)于:(參數(shù)1, 參數(shù)2, …, 參數(shù)N) =>{ return 表達(dá)式; }

當(dāng)只有一個(gè)參數(shù)時(shí)擦酌,圓括號是可選的:

(單一參數(shù)) => {函數(shù)聲明}

單一參數(shù) => {函數(shù)聲明}

沒有參數(shù)的函數(shù)應(yīng)該寫成一對圓括號:

() => {函數(shù)聲明}

實(shí)例

// ES5

var x = function(x, y) {

? ? return x * y;

}

// ES6

const x = (x, y) => x * y;

有的箭頭函數(shù)都沒有自己的 this俱诸。 不適合頂一個(gè) 對象的方法。

當(dāng)我們使用箭頭函數(shù)的時(shí)候赊舶,箭頭函數(shù)會(huì)默認(rèn)幫我們綁定外層 this 的值睁搭,所以在箭頭函數(shù)中 this 的值和外層的 this 是一樣的。

箭頭函數(shù)是不能提升的笼平,所以需要在使用之前定義园骆。

使用 const 比使用 var 更安全,因?yàn)楹瘮?shù)表達(dá)式始終是一個(gè)常量寓调。

如果函數(shù)部分只是一個(gè)語句锌唾,則可以省略 return 關(guān)鍵字和大括號 {},這樣做是一個(gè)比較好的習(xí)慣:

實(shí)例

const x = (x, y) => { return x * y }

this:

首先要知道this的是在代碼執(zhí)行的時(shí)候才能確定的夺英,定義的時(shí)候不能確定鸠珠,因?yàn)閠his是執(zhí)行上下文的一部分,而執(zhí)行上下文是在代執(zhí)行的時(shí)候才能8定的秋麸。實(shí)際上this的最終指向的是那個(gè)調(diào)用它的對象渐排。想理解this先看幾個(gè)例子:

var a = {

name:'A',

fn: funcrion(){

console.log(this.name);

console.log(this);

}

}

a.fn();//this.name === 'A'; this===a

a.fn.call({name:'B'});//this.name===='B'; this==={name:'B'}

var fn1 = a.fn;

fn1();//this.name === undefined; this===window

通過上面的例子可以看出this的執(zhí)行會(huì)有不同,主要集中在以下幾種情況:1.作為構(gòu)造函數(shù)執(zhí)行灸蟆,在構(gòu)造函數(shù)中(上面例子未體現(xiàn))2.作為對象屬性執(zhí)行驯耻,上述代碼中的a.fn();3.作為普通函數(shù)執(zhí)行,上述代碼中fn1();4.用于call炒考,apply可缚,bind,上述代碼中a.fn.call({name:'B'})斋枢;

其中fn1() 的執(zhí)行結(jié)果有些出乎意料帘靡,上文說過‘實(shí)際上this的最終指向的是那個(gè)調(diào)用它的對象’,fn1中this為什么指向了window瓤帚?繼續(xù)來看例子:

function a() {

var user = "例子";

console.log(this.user);//undefined

console.log(this);//window

}

a();

按照我們上面說的this最終指向的是調(diào)用它的對象描姚,這里的函數(shù)a實(shí)際是被Window對象所點(diǎn)出來的涩赢,下面的代碼就可以證明:

function a() {

var user = "例子";

console.log(this.user);//undefined

console.log(this);//window

}

window.a();

繼續(xù)看例子:

var o = {

user: "例子",

fn: function(){

console.log(this.user);//'例子'

console.log(this);// o

}

}

o.fn(); ==>window.o.fn()

o.fn();等價(jià)于window.o.fn(),但是this并沒有指向window轩勘,而是指向O對象筒扒;是不是有些迷惑,繼續(xù)看例子:

var o = {

a = 10;

b : {

a:12;

fn:function(){

console.log(this.a);//12

console.log(this);//b

}

}

}

o.b.fn();

同樣屬性都是對象o調(diào)用出來的绊寻,但同樣this沒有指向O花墩。其實(shí)我們需要知道以下幾點(diǎn):

1.如果一個(gè)函數(shù)中有this,但是沒有被上一級對象調(diào)用澄步,那么this就指向window冰蘑,嚴(yán)格模式下t'his將指向undefined;2.如果一個(gè)函數(shù)中有this村缸,這個(gè)函數(shù)被上一級對象調(diào)用祠肥,那么this指向上一級對象;3.如果函數(shù)中有this王凑,這個(gè)函數(shù)中包含多個(gè)對象搪柑,盡管這個(gè)函數(shù)是被最外層的對象所調(diào)用,this指向的也是其上一級對象索烹。(上面的例子中工碾,將b對象的值注銷既可以驗(yàn)證)

var o = {

a = 10;

b : {

//a:12;

fn:function(){

console.log(this.a);//undefined

console.log(this);//b

}

}

}

o.b.fn();

還有個(gè)特殊的例子:

var o = {

a = 10;

b : {

a:12;

fn:function(){

console.log(this.a);//undefined

console.log(this);//window;

}

}

}

var c = o.b.fn;

c();

this指向的是最后調(diào)用它的對象,也就是看它執(zhí)行的時(shí)候是誰調(diào)用的百姓,這個(gè)例子中雖然函數(shù)fn是被對象b所引用渊额,但是在將fn賦值給變量c的時(shí)候并沒有執(zhí)行所以最終指向的是window。

在構(gòu)造函數(shù)中this指向也會(huì)不同:

function Fn(){

this.user = '例子';

}

var a = new Fn();

console.log(a.user)//'例子'

這里a可以調(diào)用到user的值垒拢,因?yàn)闃?gòu)造函數(shù)new關(guān)鍵字改變了this的指向旬迹,所以將this指向a。

當(dāng)this遇到return時(shí)結(jié)果也會(huì)有差異,如下面的連個(gè)例子:

function Fn(){

this.user = '例子';

return {};

}

var a = new Fn();

console.log(a.user)//undefined

function Fn(){

this.user = '例子';

return 1;

}

var a = new Fn();

console.log(a.user)//'例子'

#####總結(jié): 如果返回值是一個(gè)對象求类,那么this指向返回的這個(gè)對象奔垦,如果返回值不是一個(gè)對象,那么this還是指向函數(shù)的實(shí)例尸疆;null也是一個(gè)對象椿猎,但是null比較特殊,返回值是null寿弱,this還是指向函數(shù)的實(shí)例犯眠。

css實(shí)現(xiàn)兩欄布局的總結(jié):

兩欄布局(左側(cè)寬度固定,右側(cè)自適應(yīng))症革,在學(xué)習(xí)的過程中總結(jié)了幾種方法:

方法一:float+margin-left

HTML部分

<div class="left">

<h1>Left Side</h1>

<p>我是左側(cè)欄</p>

</div>

<div class="right">

<h1>Right Side</h1>

<p>我是右側(cè)欄</p>

</div>

CSS部分

{

/清除默認(rèn)格式/

margin:0;

padding:0筐咧;

}

.left{

width:200px;

background-color:red;

float:left;

}

.right{

background-color:green;

margin-left:200px;//等于左邊欄的寬度

}


方法二:absolute+margin-leftCSS部分

{

margin:0;

padding:0;

}

.left{

width:100px;

background-color:red;

position:absolute;

}

.right{

background-color:green;

margin-left:100px;

}

方法三:float+BFC為左側(cè)元素設(shè)置浮動(dòng)后,左側(cè)元素會(huì)因?yàn)楦?dòng)蓋在右側(cè)元素上,因此要將右側(cè)元素變成BFC量蕊,BFC是一個(gè)獨(dú)立的區(qū)域铺罢,不會(huì)讓BFC外的元素對其內(nèi)部造成干擾。當(dāng)右側(cè)元素變成一個(gè)BFC時(shí)它的元素邊界會(huì)發(fā)生變化危融,會(huì)緊緊貼合左側(cè)的元素畏铆。常見的右側(cè)元素設(shè)置----overflow:hidden雷袋;

方法四:flex布局HTML部分

<div class="box">

<div class="left">

<h1>Left Side</h1>

<p>我是左側(cè)欄</p>

</div>

<div class="right">

<h1>Right Side</h1>

<p>我是右側(cè)欄</p>

</div>

</div>

CSS設(shè)置:

{

/清除默認(rèn)格式/

margin:0;

padding:0;

}

.box{

display:flex;

}

.box1{

}

.box2{

flex:1;

}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吉殃,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子楷怒,更是在濱河造成了極大的恐慌蛋勺,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸠删,死亡現(xiàn)場離奇詭異抱完,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)刃泡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門巧娱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人烘贴,你說我怎么就攤上這事禁添。” “怎么了桨踪?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵老翘,是天一觀的道長。 經(jīng)常有香客問我锻离,道長铺峭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任汽纠,我火速辦了婚禮卫键,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘虱朵。我一直安慰自己莉炉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布卧秘。 她就那樣靜靜地躺著呢袱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪翅敌。 梳的紋絲不亂的頭發(fā)上羞福,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天,我揣著相機(jī)與錄音蚯涮,去河邊找鬼治专。 笑死卖陵,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的张峰。 我是一名探鬼主播泪蔫,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼喘批!你這毒婦竟也來了撩荣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤饶深,失蹤者是張志新(化名)和其女友劉穎餐曹,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體敌厘,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡台猴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了俱两。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片饱狂。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宪彩,靈堂內(nèi)的尸體忽然破棺而出休讳,到底是詐尸還是另有隱情,我是刑警寧澤毯焕,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布衍腥,位于F島的核電站,受9級特大地震影響纳猫,放射性物質(zhì)發(fā)生泄漏婆咸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一芜辕、第九天 我趴在偏房一處隱蔽的房頂上張望尚骄。 院中可真熱鬧,春花似錦侵续、人聲如沸倔丈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽需五。三九已至,卻和暖如春轧坎,著一層夾襖步出監(jiān)牢的瞬間宏邮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蜜氨,地道東北人械筛。 一個(gè)月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像飒炎,于是被迫代替她去往敵國和親埋哟。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 單例模式 適用場景:可能會(huì)在場景中使用到對象郎汪,但只有一個(gè)實(shí)例赤赊,加載時(shí)并不主動(dòng)創(chuàng)建,需要時(shí)才創(chuàng)建 最常見的單例模式怒竿,...
    Obeing閱讀 2,067評論 1 10
  • "use strict";function _classCallCheck(e,t){if(!(e instanc...
    久些閱讀 2,030評論 0 2
  • 一砍鸠、你不知道的JavaScript 1扩氢、作用域 作用域 LHS RHS RHS查詢與簡單地查找某個(gè)變量的值別無二...
    頂兒響叮當(dāng)閱讀 346評論 0 0
  • 1耕驰、使用typeof bar ===“object”來確定bar是否是一個(gè)對象時(shí)有什么潛在的缺陷?這個(gè)陷阱如何避免...
    深海鯽魚堡閱讀 661評論 1 1
  • https://www.zcfy.cc/article/37-essential-javascript-inter...
    小明yz閱讀 423評論 0 2