JavaScript一點通第二節:函數和對象

一、函數

JavaScript中的函數定義分為兩種:聲明式函數和賦值式函數。而且,函數的名稱就是函數的內存地址,和變量一樣,指向函數代碼所在的內存區域。

// 聲明式函數

function fn(name){

var msg = "你好,"+name+",我是一個函數.";

alert(msg);

}

// 賦值式函數

var fn = function(name){

var msg = "你好,"+name+",我是一個函數.";

alert(msg);

}

以上兩種表達式中的fn是一樣的,都是指向一個函數的指針。alert(fn)的運行結果都是:

1

alert(fn)之所以能夠打印函數的聲明語句,是因為toString()方法:

function fn(){

var msg = "你好,"+name+",我是一個函數.";

alert(msg);

}

alert(fn.toString());

運行結果是一樣的。

那么toString()方法是怎樣來的呢?

對于JavaScript來說,函數其實是Function類的對象。比如,我們可以用Function類直接創建上面的fn函數:

var fn = new Function("name","var msg = \"你好,\"+name+\",我是一個函數.\";\nalert(msg);");

alert(fn);

執行結果如下:

2

函數的執行結果也是一樣的:

var fn = new Function("name","var msg = \"你好,\"+name+\",我是一個函數.\";\nalert(msg);");

fn("張三");

3

Function對象有length屬性,可以查看函數的參數,有valueOf()方法和toString()方法,這兩個方法返回的都是函數的源代碼。因此,alert(fn)顯示的就是函數的聲明語句了。

既然函數名是指向函數的變量,那么就可以把函數作為參數傳遞給另一個函數。

function fn(name){

var msg = "你好,"+name+",我是一個函數.";

alert(msg);

}

function call_fn(func,name){

func(name);

}

call_fn(fn,"張三");

4

JavaScript的函數,使用特殊對象arguments封裝了函數的參數,我們無需明確指出參數名,就能訪問它們。通過屬性 arguments.length可以獲得函數的參數個數 。用arguments對象判斷傳遞給函數的參數個數,即可模擬函數重載。下面是官方的一個例子。

function doAdd() {

if(arguments.length == 1) {

alert(arguments[0] + 5);

} else if(arguments.length == 2) {

alert(arguments[0] + arguments[1]);

}

}

doAdd(10); ? ? ? //輸出 "15"

doAdd(40, 20); ? ?//輸出 "60"

JavaScript函數中,變量的作用域,要特別注意的一點是:加var關鍵字的變量是函數內部的局部變量,函數執行完后,變量將銷毀;但沒有加var關鍵字的變量,將成為全局變量,函數外可以訪問。

function fn(){

var x = 10;

y = 20;

alert("函數內部訪問x:"+x+"\n函數內部訪問y:"+y);

}

fn();

alert("函數外部訪問y:"+y);

alert("函數外部訪問x:"+x);

5
6
7

二、對象

JavaScript沒有類的概念,只有對象定義。對象是由 new 運算符加上要實例化的對象的名字創建的。其中,要實例化的對象其實就是函數。那么,函數是怎樣變成對象的呢?

先看下面這段代碼。

function myobj(){

return this;

}

var f = myobj();

var o= new myobj();

alert(f);

alert(o);

我們發現,加了new運算符后,this才指向由myobj創建的對象。

8

而var f = myobj(),這就不是創建對象,其中的this不是指myobj創建的對象,而是代碼當前上下文環境的當前對象,比如是window。

9

也就是說,用new運算符調用函數就創建了對象。this代表實例化之后的對象,可以顯示的return,但并不需要這么做。以下代碼效果是一樣的。

function myobj(){

}

var o = new myobj();

alert(o);

10

JavaScript的Object對象與Java中的Object相似,JavaScript中的所有對象都由這個對象繼承而來,Object對象中的所有屬性和方法都會出現在其他對象中。

Object 對象具有下列屬性:

constructor:創建對象的函數(構造函數)的引用(指針)。

Prototype:對該對象的對象原型的引用。對于所有的對象,它默認返回Object對象的一個實例。

還具有幾個方法:

hasOwnProperty(property) :判斷對象是否有某個特定的屬性。必須用字符串指定該屬性。(例如,o.hasOwnProperty("name"))。

isPrototypeOf(object) :判斷該對象是否為另一個對象的原型。

propertyIsEnumerable :判斷給定的屬性是否可以用 for...in 語句進行枚舉。

toString() :返回對象的原始字符串表示。對于 Object 對象,ECMA-262 沒有定義這個值,所以不同的 ECMAScript 實現具有不同的值。

valueOf() :返回最適合該對象的原始值。對于許多對象,該方法返回的值都與 ToString() 的返回值相同。

我們在瀏覽器的開發者工具的控制臺輸入new object()回車,可以查看上面那些Object對象的屬性和方法。

11

Object對象也可以使用對象字面量語法來創建:var o = {};

同樣,我們可以在瀏覽器的開發者工具中進行驗證。

12

javascript支持后綁定,比如這樣:

function obj()

{

}

var o = new obj();

o.fn = function(){

alert("hello");

}

o.fn();

13

所以,可以通過函數創建對象,這叫工廠方法:

function createCar(color,doors,mpg) {

var car = new Object();

car.color = color;

car.doors = doors;

car.mpg = mpg;

car.showColor = function() {

alert(this.color);

};

return car;

}

var car1 = createCar("red",4,23);

var car2 = createCar("blue",3,25);

car1.showColor();

car2.showColor();

14
15

比較正規一點的創建對象的方法,用構造函數法,用this代表當前對象了:

function Car(color,doors,mpg) {

this.color = color;

this.doors = doors;

this.mpg = mpg;

this.showColor = function() {

alert(this.color);

};

}

var car1 = new Car("red",4,23);

var car2 = new Car("blue",3,25);

car1.showColor();

car2.showColor();

16
17

構造函數法的問題是,其中的對象方法,比如例子中的showColor方法,每次new的時候都會創建一次,顯然浪費內存。

可以用原型鏈定義對象的方法。這樣,所有對象共享一個對象方法,既保證了對象屬性的唯一性,也節約了內存:

function Car(color,doors,mpg) {

this.color = color;

this.doors = doors;

this.mpg = mpg;

this.drivers = new Array("Mike","John");

}

Car.prototype.showDrivers = function() {

alert(this.drivers);

};

var car1 = new Car("red",4,23);

var car2 = new Car("blue",3,25);

car1.drivers.push("Bill");

car1.showDrivers();? ? ? ? //輸出 "Mike,John,Bill"

car2.showDrivers();? ? ? ? //輸出 "Mike,John"

18
19

對象方法,只能是new之后的對象可以訪問:

function obj(){

}

obj.prototype.fn = function(){

alert("hello");

}

var o = new obj();

o.fn();

20

但是,如果這樣訪問obj.fn()就會報錯:

function obj(){

}

obj.prototype.fn = function(){

alert("hello");

}

obj.fn();

21

用函數名字直接訪問的方法,我們叫函數方法,或者靜態方法。

function obj(){

}

obj.fn = function(){

alert("hello");

}

obj.fn();

22

但javascript的靜態方法,對象并不能訪問,如果這樣就會報錯:

function obj(){

}

obj.fn = function(){

alert("hello");

}

var o = new obj();

o.fn();

23

還有很重要的一點,原型屬性是所有對象共享,如果屬性是引用類型,那么就會出現,一個對象修改了數值,其他對象相應的屬性數值都會改變的尷尬局面。

function obj(){

}

obj.prototype.names = ["張三","李四"];

var o1 = new obj();

var o2 = new obj();

o1.names.push("o1添加的新的名字");

alert("o1.names:"+o1.names+"\no2.names:"+o2.names);

24

其實,javascript并沒有真正的靜態方法,只是利用javascript靈活的特性模擬實現的。

本文出自 “老惠” 博客,轉載已經過作者同意。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,412評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,514評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,373評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,975評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,743評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,199評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,262評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,414評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,951評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,780評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,527評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,218評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,649評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,889評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,673評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內容

  • 工廠模式類似于現實生活中的工廠可以產生大量相似的商品,去做同樣的事情,實現同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 7,798評論 2 17
  • 面向對象編程 1.創建,使用函數 var CheckObject = {checkName : function(...
    依米花1993閱讀 398評論 0 0
  • ECMAScript關鍵字 delete do else finally function in instance...
    doudou2閱讀 724評論 0 0
  • 單例模式 適用場景:可能會在場景中使用到對象,但只有一個實例,加載時并不主動創建,需要時才創建 最常見的單例模式,...
    Obeing閱讀 2,087評論 1 10
  • @轉自GitHub 介紹js的基本數據類型。Undefined、Null、Boolean、Number、Strin...
    YT_Zou閱讀 1,179評論 0 0