亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

關于js函數解釋(包括內嵌,對象等)

2019-11-19 18:55:10
字體:
來源:轉載
供稿:網友

常用寫法:

function add(a,b){   return  a + b;}alert(add(1,2));    // 結果 3

當我們這么定義函數的時候,函數內容會被編譯(但不會立即執行,除非我們去調用它)。而且,也許你不知道,當這個函數創建的時候有一個同名的對象也被創建。就我們的例子來說,我們現在有一個對象叫做“add”(要更深入了解,看底下函數:對象節。)

匿名函數:

我們也可以通過指派一個變量名給匿名函數的方式來定義它。

var add = function(a,b){   return  a + b;}alert(add(1,2));    // 結果 3

這個代碼和前一個例子做了同樣的事情。也許語法看起來比較奇怪,但它應該更能讓你感覺到函數是一個對象,而且我們只是為這個對象指派了一個名稱??梢园阉醋龊?var myVar=[1,2,3]一樣的語句。以這種方式聲明的函數內容也一樣會被編譯。

當我們指派一個這樣的函數的時候,我們并不一定要求必須是匿名函數。在這里,我作了和以上一樣的事情,但我加了函數名“theAdd”,而且我可以通過調用函數名或者是那個變量來引用函數。

var add = function theAdd(a,b){   return a + b;}alert(add(1,2));      // 結果 3 alert(theAdd(1,2));    // 結果也是 3

使用這種方式來定義函數在面向對象編程中是很有用的,因為我們能像底下這樣使一個函數成為一個對象的屬性。

var myObject = new Object();myObject.add = function(a,b){return a+b};// myObject 現在有一個叫做“add”的屬性(或方法)”// 而且我能夠象下面這樣使用它myObject.add(1, 2);

函數:對象

函數是javascript中的一種特殊形式的對象。它是第一個[b〕類數據類型(classdata type)。這意味著我們能夠給它增加屬性。這里有一些需要注意的有趣觀點

對象的創建

就像剛才提及的,當我們定義一個函數時,javascript實際上在后臺為你創建了一個對象。這個對象的名稱就是函數名本身。這個對象的類型是function。在下面的例子,我們也許不會意識到這一點,但我們實際上已經創建了一個對象:它叫做Ball。

function ball()   // 也許看起來有點奇怪,但是這個聲明{             // 創建了一個叫做Ball的對象   i = 1;}alert(typeof ball);   // 結果 "function"

我們甚至能將這個對象的內容打印出來而且它會輸出這個函數的實際代碼

alert(ball);  //結果為://function ball()//{//   i = 1;//}

屬性的添加

我們能夠給Object添加屬性,包括對象function。因為定義一個函數的實質是創建一個對象。我們能夠“暗地里”給函數添加屬性。比如,我們這里定義了函數Ball,并添加屬性callsign。

function Ball()   // 也許看起來有點奇怪,但是這個聲明創建了一個叫做Ball的對象,而且你能夠引用它或者象下面那樣給它增加屬性 {          } ball.callsign="The ball"; // 給Ball增加屬性 alert(ball.callsign); // 輸出 "The ball"

指針

因為function是一個對象,我們能夠為一個function分配一個指針。如下例,變量ptr指向了對象myFunction。

function myFunction(message) { alert(message); } var ptr=myFunction; // ptr指向了myFunction ptr("hello");     // 這句會執行myFunction:輸出"hello"

我們能夠運行這個函數,就好像這個函數名已經被指針名代替了一樣。所以在上面,這行ptr("hello"); 和myFunction("hello");的意義是一樣的。

指向函數的指針在面向對象編程中相當有用。例如:當我們有多個對象指向同一個函數的時候(如下):

function sayName(name) { alert(name); }var object1=new Object();   // 創建三個對象 var object2=new Object(); var object3=new Object();object1.sayMyName=sayName;    // 將這個函數指派給所有對象 object2.sayMyName=sayName; object3.sayMyName=sayName;object1.sayMyName("object1");  // 輸出 "object1" object2.sayMyName("object2");  // 輸出 "object2" object3.sayMyName("object3");  // 輸出 "object3"

因為只有指針被保存(而不是函數本身),當我們改變函數對象自身的時候,所有指向那個函數的指針都會發生變化。我們能夠在底下看到:

function myFunction() { alert(myFunction.message); } myFunction.message="old"; var ptr1=myFunction;         // ptr1 指向 myFunction var ptr2=myFunction;         // ptr2 也指向 myFunction ptr1();           // 輸出 "old" ptr2();               // 輸出 "old" myFunction.message="new"; ptr1();           // 輸出 "new" ptr2(); 

指針的指向

我們能夠在一個函數創建之后重新分配它,但是我們需要指向函數對象本身,而不是指向它的指針。在下例中,我將改變myfunction()的內容。

function myFunction() { alert("Old"); } myFunction(); // 輸出 "Old" myFunction=function() { alert("New"); }; myFunction(); // 輸出 "New" 

舊函數哪里去了??被拋棄了。

如果我們需要保留它,我們可以在改變它之前給它分配一個指針。

function myFunction() { alert("Old"); } var savedFuncion=myFunction; myFunction=function() { alert("New"); }; myFunction();  // 輸出 "New" savedFuncion(); // 輸出 "Old"

內嵌函數

function get(a,b,c){   function cal(n)   {      return n/2;   }   var result = “”;   result+=cal(a)+” ”;    result+=cal(b)+” ”;    result+=cal(c); }var resultString = get(10,20,30);alert(resultString);   // 輸出 "5 10 15"

你只能在內部調用嵌套的函數。就是說,你不能這么調用:

getHalfOf.calculate(10),因為calculate只有當外部函數(getHalfOf())在運行的時候才會存在。這和我們前面的討論一致(函數會被編譯,但只有當你去調用它的時候才會執行)。

調用哪個函數?

你也許正在想命名沖突的問題。比如,下面哪一個叫做calculate的函數會被調用?

function calculate(number) {     return number/3; } function getHalfOf(num1, num2, num3)   {     function calculate(number)     {        return number/2;     }     var result="";     result+=calculate(num1)+" ";     result+=calculate(num2)+" ";     result+=calculate(num3); }     var resultString=getHalfOf(10,20,30); alert(resultString);     // 輸出 "5 10 15"

在這個例子中,編譯器會首先搜索局部內存地址,所以它會使用內嵌的calculate函數。如果我們刪除了這個內嵌(局部)的calculate函數,這個代碼會使用全局的calculate函數。

函數:數據類型及構造函數

讓我們來看看函數的另一個特殊功能--這讓它和其它對象類型截然不同。一個函數能夠用來作為一個數據類型的藍圖。這個特性通常被用在面向對象編程中來模擬用戶自定義數據類型(user defined data type)。使用用戶自定義數據類型創建的對象通常被成為用戶自定義對象(user defined object)。

數據類型

在定義了一個函數之后,我們也同時創建了一個新的數據類型。這個數據類型能夠用來創建一個新對象。下例,我創建了一個叫做Ball的新數據類型。

function Ball() { } var ball0=new Ball(); // ball0 現在指向一個新對象 alert(ball0);     // 輸出 "Object",因為 ball0 現在是一個對象

這樣看來,ball0=new Ball()作了什么?new關鍵字創建了一個類型是Object的新對象(叫做ball0)。然后它會執行Ball(),并將這個引用傳給ball0(用于調用對象)。下面,你會看到這條消息:“creating new Ball”,如果Ball()實際上被運行的話。

function Ball(message) { alert(message); } var ball0=new Ball("creating new Ball"); // 創建對象并輸出消息 ball0.name="ball-0";           // ball0現在有一個屬性:name alert(ball0.name);            // 輸出 "ball-0"

我們可以把上面這段代碼的第6行看做是底下的代碼6-8行的一個簡寫:

function Ball(message) { alert(message); } var ball0=new Object(); ball0.construct=Ball; ball0.construct("creating new ball"); // 執行 ball0.Ball ("creating.."); ball0.name="ball-0";           alert(ball0.name); 

這行代碼ball0.construct=Ball和以上中的ptr=myFunction語法一致。

添加屬性

當我們象上面那樣使用關鍵字new創建一個對象的時候,一個新的Object被創建了。我們可以在創建之后給這個對象添加屬性(就好像我在上面那樣添加屬性name。而接下來的問題就是如果我們創建了這個對象的另外一個實例,我們得象下面那樣再次給這個新對象添加這個屬性。)

function Ball() { } var ball0=new Ball(); // ball0 現在指向了類型Ball的一個新實例 ball0.name="ball-0"; // ball0 現在有一個屬性"name" var ball1=new Ball(); ball1.name="ball-1"; var ball2=new Ball(); alert(ball0.name);  // 輸出 "ball-0" alert(ball1.name);  // 輸出 "ball-1" alert(ball2.name);  // 哦,我忘記給ball2添加“name”了!

我忘記給ball2添加屬性name了,如果在正式的程序中這也許會引發問題。有什么好辦法可以自動增加屬性呢?嗯,有一個:使用this關鍵字。this這個詞在function中有特別的意義。它指向了調用函數的那個對象。讓我們看看下面的另一個示例,這時候我們在構造函數中添加上這些屬性:

function Ball(message, specifiedName) { alert(message); this.name=specifiedName;        } var ball0=new Ball("creating new Ball", "Soccer Ball"); alert(ball0.name);          // prints "Soccer Ball"

請記住:是new關鍵字最終使得構造函數被執行。在這個例子中,它將會運行Ball("creating new Ball", "Soccer Ball");而關鍵字this將指向ball0。

因此,這行:this.name=specifiedName變成了ball0.name="Soccer Ball"。它主要是說:給ball0添加屬性name,屬性值是Soccer Ball。

我們現在只是添加了一個name屬性給ball0,看起來和上一個例子中所做的很象,但卻是一個更好更具擴展性的方法。現在,我們可以隨心所欲的創建許多帶有屬性的ball而無需我們手動添加它們。而且,人們也希望創建的Ball對象能夠清晰的看懂它的構造函數并且能夠輕松找出Ball的所有屬性。讓我們添加更多屬性到Ball里。

function Ball(color, specifiedName, owner, weight) { this.name=specifiedName;        this.color=color; this.owner=owner; this.weight=weigth; } var ball0=new Ball("black/white", "Soccer Ball", "John", 20); var ball1=new Ball("gray", "Bowling Ball", "John", 30); var ball2=new Ball("yellow", "Golf Ball", "John", 55); var balloon=new Ball("red", "Balloon", "Pete", 10); alert(ball0.name);            // 輸出 "Soccer Ball" alert(balloon.name);           // 輸出 "Balloon" alert(ball2.weight);           // 輸出 "55"

嘿!使用面向對象術語,你能夠說Ball是一個擁有如下屬性的對象類型:name,color, owner, weight。

將對象賦給屬性我們并沒被限制只能添加形如字符串或者數字之類的簡單數據類型作為屬性。我們也能夠將對象賦給屬性。下面,supervisor是Employee的一個屬性.

function Employee(name, salary, mySupervisor) { this.name=name;        this.salary=salary; this.supervisor=mySupervisor; } var boss=new Employee("John", 200); var manager=new Employee("Joan", 50, boss); var teamLeader=new Employee("Rose", 50, boss); alert(manager.supervisor.name+" is the supervisor of "+manager.name); alert(manager.name+"/'s supervisor is "+manager.supervisor.name);

函數也是一個對象。所以你可以讓一個函數作為一個對象的一個屬性。下面,我將添加兩個函數getSalary和addSalary。

function Employee(name, salary) { this.name=name;        this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=function()          {           return this.salary;          }; } function addSalaryFunction(addition) { this.salary=this.salary+addition; } var boss=new Employee("John", 200000); boss.addSalary(10000);          // boss 長了 10K 工資……為什么老板工資可以長這么多:'( alert(boss.getSalary());         // 輸出 210K……為什么默認工資也那么高……:'(addSalary和getSalary演示了幾種將函數賦給屬性的不同方法。如前面數次提到的,一個函數聲明的結果是一個對象 被創建。function Employee(name, salary) { this.name=name;        this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=function()          {           return this.salary;          }; } function addSalaryFunction(addition) { this.salary=this.salary+addition; } var boss=new Employee("John", 200000); var boss2=new Employee("Joan", 200000); var boss3=new Employee("Kim", 200000);

當你創建這個對象的更多實例時(boss2和boss3),每一個實例都有一份getSalary代碼的單獨拷貝;而與此相反,addSalary則指向了同一個地方(即addSalaryFunction)。

看看下面的代碼來理解一下上面所描述的內容。

function Employee(name, salary) { this.name=name;        this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=function()          {           return this.salary;          }; } function addSalaryFunction(addition) { this.salary=this.salary+addition; } var boss1=new Employee("John", 200000); var boss2=new Employee("Joan", 200000);// 給getSalary函數對象添加屬性 boss1.getSalary.owner="boss1"; boss2.getSalary.owner="boss2"; alert(boss1.getSalary.owner);  // 輸出 "boss1" alert(boss2.getSalary.owner);  // 輸出 "boss2" // 如果兩個對象指向同一個函數對象,那么 上面兩個輸出都應該是“boss2”。 // 給addSalary函數對象添加屬性 boss1.addSalary.owner="boss1"; boss1.addSalary.owner="boss2"; alert(boss1.addSalary.owner);  // 輸出 "boss2" alert(boss2.addSalary.owner);  // 輸出 "boss2"http:// 因為兩個對象都指向同一個函數// 當修改其中一個的時候,會影響所有的實例(所以兩個都輸出“boss2”).

也許不是重要的事情,但這里有一些關于運行類似上面的getSalary的內嵌函數的結論:

1) 需要更多的存儲空間來存儲對象(因為每一個對象實例都會有它自己的getSalary代碼拷貝);

2) javascript需要更多時間來構造這個對象。

讓我們重新寫這個示例來讓它更有效率些。

function Employee(name, salary) { this.name=name;        this.salary=salary; this.addSalary=addSalaryFunction; this.getSalary=getSalaryFunction; } function getSalaryFunction() { return this.salary; } function addSalaryFunction(addition) { this.salary=this.salary+addition; }

看這兒,兩個函數都指向同一個地方,這將會節約空間和縮短構造時間(特別是當你有一大堆內嵌函數在一個構造函數的時候)。這里有另外一個函數的功能能夠來提升這個設計,它叫做prototype,而我們將在下一節討論它。

函數:原型

每一個構造函數都有一個屬性叫做原型(prototype,下面都不再翻譯,使用其原文)。這個屬性非常有用:為一個特定類聲明通用的變量或者函數。

prototype的定義

你不需要顯式地聲明一個prototype屬性,因為在每一個構造函數中都有它的存在。你可以看看下面的例子:

function Test() { } alert(Test.prototype); // 輸出 "Object"

給prototype添加屬性

就如你在上面所看到的,prototype是一個對象,因此,你能夠給它添加屬性。你添加給prototype的屬性將會成為使用這個構造函數創建的對象的通用屬性。

例如,我下面有一個數據類型Fish,我想讓所有的魚都有這些屬性:

livesIn="water"和price=20;為了實現這個,我可以給構造函數Fish的prototype添加那些屬性。

function Fish(name, color) { this.name=name; this.color=color; } Fish.prototype.livesIn="water"; Fish.prototype.price=20; 

接下來讓我們作幾條魚:

var fish1=new Fish("mackarel", "gray"); var fish2=new Fish("goldfish", "orange"); var fish3=new Fish("salmon", "white");

再來看看魚都有哪些屬性:

for (int i=1; i<=3; i++) { var fish=eval("fish"+i);  // 我只是取得指向這條魚的指針 alert(fish.name+","+fish.color+","+fish.livesIn+","+fish.price); } 

輸出應該是:

"mackarel, gray, water, 20" "goldfish, orange, water, 20" "salmon, white water, 20"

你看到所有的魚都有屬性livesIn和price,我們甚至都沒有為每一條不同的魚特別聲明這些屬性。這時因為當一個對象被創建時,這個構造函數將會把它的屬性prototype賦給新對象的內部屬性__proto__。這個__proto__被這個對象用來查找它的屬性。

你也可以通過prototype來給所有對象添加共用的函數。這有一個好處:你不需要每次在構造一個對象的時候創建并初始化這個函數。

用prototype給對象添加函數

function Employee(name, salary) { this.name=name;        this.salary=salary; } Employee.prototype.getSalary=function getSalaryFunction() { return this.salary; } Employee.prototype.addSalary=function addSalaryFunction(addition) { this.salary=this.salary+addition; }

我們可以象通常那樣創建對象:

var boss1=new Employee("Joan", 200000); var boss2=new Employee("Kim", 100000); var boss3=new Employee("Sam", 150000); 

并驗證它:

alert(boss1.getSalary());  // 輸出 200000 alert(boss2.getSalary());  // 輸出 100000 alert(boss3.getSalary());  // 輸出 150000

這里有一個圖示來說明prototype是如何工作的。這個對象的每一個實例(boss1, boss2, boss3)都有一個內部屬性叫做__proto__,這個屬性指向了它的構造器 (Employee)的屬性prototype。當你執行getSalary或者addSalary的時候,這個對象會在它的__proto__找到并執行這個代碼。

以上這篇關于js函數解釋(包括內嵌,對象等) 就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久在线免费视频| 一区二区三区回区在观看免费视频| 日韩一区二区在线视频| 国产精品久久久久7777婷婷| 欧美一性一乱一交一视频| 国产亚洲视频在线观看| 国产精品女视频| 欧美日韩国产一区在线| 亚洲欧洲国产一区| 欧美极品少妇全裸体| 日本欧美国产在线| 日韩亚洲综合在线| 日韩在线播放视频| 日韩精品中文字幕视频在线| 91久久精品国产| 午夜伦理精品一区| 亚洲少妇中文在线| 亚洲人线精品午夜| 91成人国产在线观看| 欧美激情一区二区三区成人| 久久五月情影视| 欧美二区乱c黑人| 日韩精品久久久久久福利| 国产精品丝袜一区二区三区| 一区二区三区精品99久久| 茄子视频成人在线| 亚洲视频一区二区三区| 欧美男插女视频| 久久欧美在线电影| 久久99国产精品自在自在app| 日韩最新免费不卡| 欧美性猛交xxxx久久久| 奇米影视亚洲狠狠色| 欧美激情a在线| 国产精品免费一区豆花| 国产精品成av人在线视午夜片| 亚洲综合在线播放| 亚洲欧美在线一区二区| 久久久亚洲国产天美传媒修理工| 国产精品美女久久久免费| 992tv在线成人免费观看| 欧美性猛交xxxxx免费看| 欧美视频专区一二在线观看| 国产精品久久久久久久美男| 欧美黄色三级网站| 亚洲国产另类 国产精品国产免费| 成人性生交大片免费看小说| 国产精品久久二区| 久久久久久久网站| 欧美在线视频免费播放| 日韩中文字幕视频在线观看| 国内精品免费午夜毛片| 国产一区二区三区视频| 91在线观看免费高清完整版在线观看| 亚洲欧美综合另类中字| 久热99视频在线观看| 91精品国产自产在线老师啪| 亚洲xxx大片| 亚洲最大在线视频| 九九精品在线视频| 国产精品极品美女在线观看免费| 成人激情av在线| 精品国产拍在线观看| 日韩精品免费在线视频观看| 91久久精品美女高潮| 国产精品免费一区| 国产精品无av码在线观看| 日韩中文在线视频| 日韩免费在线看| 日韩有码在线播放| 久久视频在线播放| 国产精品视频一区二区高潮| 中文字幕亚洲综合| 欧美日韩亚洲一区二区| 久久天堂av综合合色| 日韩免费电影在线观看| 不卡av在线播放| 欧美日韩免费看| 日韩激情片免费| 91人人爽人人爽人人精88v| 精品久久久久久中文字幕一区奶水| 亚洲成avwww人| 欧美一级高清免费| 亚洲国内精品视频| 超碰97人人做人人爱少妇| 成人免费高清完整版在线观看| 亚洲色图在线观看| 日韩电影在线观看永久视频免费网站| 国产精品视频播放| 91网在线免费观看| 午夜精品久久久99热福利| 高清一区二区三区四区五区| 日韩影视在线观看| 亚洲成人激情图| 亚洲级视频在线观看免费1级| 色妞色视频一区二区三区四区| 91久久精品在线| 亚洲精品国产福利| 粗暴蹂躏中文一区二区三区| 亚洲a级在线播放观看| 亚洲理论电影网| 中文字幕亚洲天堂| 久久久国产精品一区| 国产在线观看不卡| 日韩av中文在线| 久久久中文字幕| 久久久免费观看| 日韩中文字幕网站| 欧美激情影音先锋| 欧美精品久久久久久久| 亚洲欧美日韩网| 国产suv精品一区二区| 午夜精品福利在线观看| 精品久久久视频| 欧美激情在线观看视频| 91丨九色丨国产在线| 精品一区二区三区电影| 久精品免费视频| 亚洲欧洲国产精品| 国产精品久久久久久久久久99| 国产精品爽爽ⅴa在线观看| 成人国产精品久久久久久亚洲| 久久精品国产亚洲精品2020| 亚洲国产精品成人一区二区| 日韩高清中文字幕| 中文字幕在线精品| 国产盗摄xxxx视频xxx69| 日韩中文理论片| 91最新在线免费观看| 久久亚洲精品国产亚洲老地址| 国产精品久久久久久久美男| 日韩欧美在线免费观看| 亚洲一区www| 日韩日本欧美亚洲| 欧美日韩免费网站| 欧美大尺度在线观看| 久久久久久尹人网香蕉| 久久精品国产精品| 日韩成人在线网站| 欧美与欧洲交xxxx免费观看| 国产精品吊钟奶在线| 国产噜噜噜噜久久久久久久久| 亚洲精品白浆高清久久久久久| 美日韩在线视频| 欧美在线一级va免费观看| 国产成人精品国内自产拍免费看| 亚洲天堂网站在线观看视频| 久久精品久久久久久| 日韩欧美aaa| 国产成人一区二区| 亚洲精品福利资源站| 疯狂做受xxxx高潮欧美日本| 欧美美最猛性xxxxxx| 日韩av电影手机在线观看| 亚洲综合中文字幕68页| 日韩欧美中文字幕在线观看| 日韩二区三区在线| 亚洲精品资源在线| 中文字幕亚洲第一| 欧美理论片在线观看| 日本道色综合久久影院| 久久99久国产精品黄毛片入口| 日韩精品免费视频| 少妇高潮久久久久久潘金莲|