摘要:在中通過關(guān)鍵字方式調(diào)用的函數(shù)都被認為是構(gòu)造函數(shù)。這個新創(chuàng)建的對象的被指向到構(gòu)造函數(shù)的。上的方法不起效果當然你要是這樣的形式指定了返回的內(nèi)容,它自然會原樣返回啦工廠模型為了不使用關(guān)鍵字,構(gòu)造函數(shù)必須顯式的返回一個值。
函數(shù)個人博客原址
函數(shù)基礎(chǔ) 定義函數(shù)的方式函數(shù)式一塊javascript代碼,定義一次,可以被多次調(diào)用與執(zhí)行,JS中的函數(shù)也是對象,所以JS函數(shù)可以像其他對象那樣操作,和傳遞,所以也稱函數(shù)對象
函數(shù)的參數(shù)列表相當于函數(shù)的人口,return相當于函數(shù)的出口,函數(shù)本身就是一種數(shù)據(jù)類型,函數(shù)是可以嵌套定義的。
有三種方式可以定義函數(shù)。并且有著如下區(qū)別:
定義方式: | function 語句(函數(shù)聲明) | Function 構(gòu)造函數(shù) | 函數(shù)表達式 |
---|---|---|---|
解析時機: | 優(yōu)先解析(聲明前置) | 順序解析 | 順序解析(聲明提前,賦值不提前) |
允許匿名: | 有名 | 匿名 | 匿名 |
形式: | 句子 | 表達式 | 表達式 |
性質(zhì): | 靜態(tài) | 動態(tài) | 靜態(tài) |
作用域: | 具有函數(shù)的作用域 | 頂級函數(shù)(頂級作用域) | 具有函數(shù)作用域 |
主要有下面兩個需要注意的地方:
理解Function 構(gòu)造函數(shù)的頂級作用域,直接看代碼就好:很直觀就可以表示出來
var a = 1; function test() { var a = 2; var func = new Function("console.info(a)"); func(); } test();//1;
函數(shù)表達式的多種創(chuàng)建方式:
// 最簡單的形式,將函數(shù)賦值給一個變量 var add = function(a,b){ //do .. } // 立即執(zhí)行匿名函數(shù)表達式IIFE (function() { //do .. })(); // 將函數(shù)當成返回值 return function(){ //do .. } //命名式函數(shù)表達式NFE var add = function foo(a,b){ // do.. // 只在foo函數(shù)內(nèi)部可以使用foo這個名稱(用途如:遞歸調(diào)用)(在新版瀏覽器下可用) // 外部訪問不到foo這個函數(shù)名 }函數(shù)的參數(shù)
在JS中函數(shù)的參數(shù)分為形式參數(shù)和實際參數(shù)兩個概念
function test(a,b,c,d) { console.log(test.length)//4 return a+b+c; } console.info(test(10,20,30))//60 console.log(test.length)//4 console.log(arguments.length);//3,表示實際接受的參數(shù)個數(shù) console.log(arguments[0]);//10,傳進來的第一個參數(shù)===a
在 函數(shù)內(nèi)部 ,JS使用了一個特別的變量arguments的 類數(shù)組對象(以后再來說這個問題),用來接受傳入函數(shù)的實際參數(shù)列表。
function arg(a,b,c){ arguments[0] = 1; console.info(a,b,c) } arg(143,456,6)//1 456 6
普通模式下可以直接對于arguments對象進行更改,上面的代碼就是一個很直觀的例子,我們直接更改了第一個參數(shù)的值,但建議不要去試圖更改arguments對象的屬性,不符合規(guī)范。
注:嚴格模式下arguments對象是實參的一個副本,所以上面的改動不會生效(自行嘗試)
什么是構(gòu)造函數(shù)?
其實構(gòu)造函數(shù)只是普通函數(shù)的一個變種,它可以當成普通的函數(shù)方式調(diào)用,也能通過new關(guān)鍵字來調(diào)用。 在Javascript中通過 new 關(guān)鍵字方式調(diào)用的函數(shù)都被認為是構(gòu)造函數(shù)。
在構(gòu)造函數(shù)內(nèi)部( 也就是被調(diào)用的函數(shù)內(nèi)) this 指向新創(chuàng)建的對象Object。 這個新創(chuàng)建的對象的 prototype 被指向到構(gòu)造函數(shù)的 prototype。
如果被調(diào)用的函數(shù)沒有顯式的 return 表達式,則隱式的會返回 this 對象(也就是新創(chuàng)建的對象)。
這就來看看實際中不同情況下的區(qū)別:
使用new關(guān)鍵字嗎,不指定return語句
function Person() { this.father = "allen"; } Person.prototype.getFatherName = function(){ console.info(this.father); }; var hong = new Person(); console.info( new Person());//Person {father: "allen"} hong.getFatherName();//allen
使用new關(guān)鍵字,并且指定return語句
function Person() { this.father = "allen"; return "1"; } Person.prototype.getFatherName = function(){ console.info(this.father); }; var hong = new Person(); console.info( hong);//Person {father: "allen"} hong.getFatherName();//allen //把return的值換成一個對象: //return "1";----------->return {a:1};或者return new String("12"); var hong = new Person(); console.info( hong);//Object {a: 1} hong.getFatherName();//[腳本錯誤]
不使用new關(guān)鍵字,當成普通函數(shù)直接調(diào)用
function Person() { this.father = "allen"; return function(){ return {} }; } Person.prototype.getFatherName = function(){ console.info(this.father); }; var bai = Person(); console.info(bai);//undefined console.info(father);//allen bai.getFatherName();//[腳本錯誤]
通過這三段不同情況的示例代碼,應該可以發(fā)現(xiàn)一些區(qū)別:
使用new關(guān)鍵字嗎,不指定return語句時,將隱式的會返回 this 對象(返也就是新創(chuàng)建的對象)。
使用new關(guān)鍵字,并且指定return語句時,需分為兩種情況:
返回值為標準類型,顯式的 return 表達式將不會影響返回結(jié)果
返回值為對象,將直接返回你顯式設(shè)置的對象
不使用new關(guān)鍵字,當成普通函數(shù)直接調(diào)用時,this指向全局對象 window,所以內(nèi)部this指定的屬性與方法,全部都暴露到全局,導致全局變量污染。prototype上的方法不起效果(當然你要是這樣的形式指定了return返回的內(nèi)容,它自然會原樣返回啦!)
工廠模型為了不使用new關(guān)鍵字,構(gòu)造函數(shù)必須顯式的返回一個值。
function createPerson(name, age, sex) { var obj = {}; obj.name = name; obj.age = age; var private = 2;//私有外部不可訪問 obj.sayName = function(){ console.info(this.name) } obj.getPrivate = function() { return private; } return obj; } var p1 = createPerson("小紅",21,"女") var p2 = createPerson("小國",22,"男") console.info(p1.name);//小紅 console.info(p2.age);//22 p2.sayName();//小國
這就是一個簡單的工廠模型,使用或者不使用 new 關(guān)鍵字沒有功能性的區(qū)別。這樣的方式比起 new的調(diào)用方式不容易出錯,并且可以充分利用 私有變量帶來的便利, 但是也有下面這樣的問題
占用更多的內(nèi)存,因為新創(chuàng)建的對象不能共享原型上的方法。
為了實現(xiàn)繼承,工廠方法需要從另外一個對象拷貝所有屬性,或者把一個對象作為新創(chuàng)建對象的原型。
這一篇博客最主要是對于函數(shù)學習的筆記,不過用自己的話來描述總描述的還不夠清晰。
有錯誤之處請指出!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/90827.html
摘要:對象有狀態(tài)對象具有狀態(tài),同一對象可能處于不同狀態(tài)之下。中對象獨有的特色對象具有高度的動態(tài)性,這是因為賦予了使用者在運行時為對象添改狀態(tài)和行為的能力。小結(jié)由于的對象設(shè)計跟目前主流基于類的面向?qū)ο蟛町惙浅4螅瑢е掠胁皇敲嫦驅(qū)ο筮@樣的說法。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學習過程的一些...
摘要:對象有狀態(tài)對象具有狀態(tài),同一對象可能處于不同狀態(tài)之下。中對象獨有的特色對象具有高度的動態(tài)性,這是因為賦予了使用者在運行時為對象添改狀態(tài)和行為的能力。小結(jié)由于的對象設(shè)計跟目前主流基于類的面向?qū)ο蟛町惙浅4螅瑢е掠胁皇敲嫦驅(qū)ο筮@樣的說法。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學習過程的一些...
摘要:對象有狀態(tài)對象具有狀態(tài),同一對象可能處于不同狀態(tài)之下。中對象獨有的特色對象具有高度的動態(tài)性,這是因為賦予了使用者在運行時為對象添改狀態(tài)和行為的能力。小結(jié)由于的對象設(shè)計跟目前主流基于類的面向?qū)ο蟛町惙浅4?,導致有不是面向?qū)ο筮@樣的說法。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學習過程的一些...
摘要:方法在中定義的函數(shù)。這種聲明方式會定義一個生成器函數(shù),它返回一個對象。類用定義的類,實際上也是函數(shù)。調(diào)用函數(shù)時使用的引用,決定了函數(shù)執(zhí)行時刻的值。表示當為時,取全局對象,對應了普通函數(shù)。四操作的內(nèi)置函數(shù)和可以指定函數(shù)調(diào)用時傳入的值。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學習過程的一些要...
摘要:方法在中定義的函數(shù)。這種聲明方式會定義一個生成器函數(shù),它返回一個對象。類用定義的類,實際上也是函數(shù)。調(diào)用函數(shù)時使用的引用,決定了函數(shù)執(zhí)行時刻的值。表示當為時,取全局對象,對應了普通函數(shù)。四操作的內(nèi)置函數(shù)和可以指定函數(shù)調(diào)用時傳入的值。 筆記說明 重學前端是程劭非(winter)【前手機淘寶前端負責人】在極客時間開的一個專欄,每天10分鐘,重構(gòu)你的前端知識體系,筆者主要整理學習過程的一些要...
閱讀 857·2023-04-25 23:59
閱讀 3758·2021-10-08 10:04
閱讀 1692·2019-08-30 14:05
閱讀 1027·2019-08-30 13:58
閱讀 500·2019-08-29 18:41
閱讀 1135·2019-08-29 17:15
閱讀 2328·2019-08-29 14:13
閱讀 2753·2019-08-29 13:27