本文目錄一覽:
- 1、怎麼js理解函數實例
- 2、Js編程語言中,自調用函數是什麼?舉個Js代碼例子解釋一下!
- 3、js的執行原理是什麼?
- 4、如何將javascript代碼編譯為c++或java
- 5、javascript框架是什麼意思?有什麼作用?怎麼理解?最好舉個例子
- 6、如何用js實現中綴表達式轉後綴表達式然後求值
怎麼js理解函數實例
js的函數是由事件驅動的或者當它被調用時執行的可重複使用的代碼塊。如下為其按鍵驅動時間的一個簡單示例
!DOCTYPE html
html
head
script
function myFunction()
{
alert(“Hello World!”);
}
/script
/head
body
button onclick=”myFunction()”點擊這裡/button
/body
/html
1、JavaScript 函數語法
函數就是包裹在花括弧中的代碼塊,前面使用了關鍵詞 function:
function functionname()
{
這裡是要執行的代碼
}
當調用該函數時,會執行函數內的代碼。
可以在某事件發生時直接調用函數(比如當用戶點擊按鈕時),並且可由 JavaScript 在任何位置進行調用。
提示:JavaScript 對大小寫敏感。關鍵詞 function 必須是小寫的,並且必須以與函數名稱相同的大小寫來調用函數。
2、調用帶參數的函數
在調用函數時,您可以向其傳遞值,這些值被稱為參數。
這些參數可以在函數中使用。
您可以發送任意多的參數,由逗號 (,) 分隔:
myFunction(argument1,argument2)
當您聲明函數時,請把參數作為變數來聲明:
function myFunction(var1,var2)
{
這裡是要執行的代碼
}
變數和參數必須以一致的順序出現。第一個變數就是第一個被傳遞的參數的給定的值,以此類推。
實例
button onclick=”myFunction(‘Bill Gates’,’CEO’)”點擊這裡/button
script
function myFunction(name,job)
{
alert(“Welcome ” + name + “, the ” + job);
}
/script
上面的函數會當按鈕被點擊時提示 “Welcome Bill Gates, the CEO”。
函數很靈活,您可以使用不同的參數來調用該函數,這樣就會給出不同的消息:
實例
button onclick=”myFunction(‘Harry Potter’,’Wizard’)”點擊這裡/button
button onclick=”myFunction(‘Bob’,’Builder’)”點擊這裡/button
根據您點擊的不同的按鈕,上面的例子會提示 “Welcome Harry Potter, the Wizard” 或 “Welcome Bob, the Builder”。
3、帶有返回值的函數
有時,我們會希望函數將值返回調用它的地方。
通過使用 return 語句就可以實現。
在使用 return 語句時,函數會停止執行,並返回指定的值。
語法
function myFunction()
{
var x=5;
return x;
}
上面的函數會返回值 5。
注釋:整個 JavaScript 並不會停止執行,僅僅是函數。JavaScript 將繼續執行代碼,從調用函數的地方。
函數調用將被返回值取代:
var myVar=myFunction();
myVar 變數的值是 5,也就是函數 “myFunction()” 所返回的值。
即使不把它保存為變數,您也可以使用返回值:
document.getElementById(“demo”).innerHTML=myFunction();
“demo” 元素的 innerHTML 將成為 5,也就是函數 “myFunction()” 所返回的值。
您可以使返回值基於傳遞到函數中的參數:
實例
計算兩個數字的乘積,並返回結果:
function myFunction(a,b)
{
return a*b;
}
document.getElementById(“demo”).innerHTML=myFunction(4,3);
“demo” 元素的 innerHTML 將是:
12
在您僅僅希望退出函數時 ,也可使用 return 語句。返回值是可選的:
function myFunction(a,b)
{
if (ab)
{
return;
}
x=a+b
}
如果 a 大於 b,則上面的代碼將退出函數,並不會計算 a 和 b 的總和。
6、局部 JavaScript 變數
在 JavaScript 函數內部聲明的變數(使用 var)是局部變數,所以只能在函數內部訪問它。(該變數的作用域是局部的)。
您可以在不同的函數中使用名稱相同的局部變數,因為只有聲明過該變數的函數才能識別出該變數。
只要函數運行完畢,本地變數就會被刪除。
7、全局 JavaScript 變數
在函數外聲明的變數是全局變數,網頁上的所有腳本和函數都能訪問它。
8、JavaScript 變數的生存期
JavaScript 變數的生命期從它們被聲明的時間開始。
局部變數會在函數運行以後被刪除。
全局變數會在頁面關閉後被刪除。
9、向未聲明的 JavaScript 變數來分配值
如果您把值賦給尚未聲明的變數,該變數將被自動作為全局變數聲明。
這條語句:
carname=”Volvo”;
將聲明一個全局變數 carname,即使它在函數內執行。
Js編程語言中,自調用函數是什麼?舉個Js代碼例子解釋一下!
自調用函數:
顧名思義,有2個意思
《1》自行調用的函數:
就是指,函數在頁面載入後或者之前就自行調用,無需藉助其他函數或方法來啟動;
例如:
(function(win){
win.alert(11);
})(window);
《2》自己調用自己的函數:
就是指,遞歸:在一個函數裡面調用自己的函數,當符合一定規則時,跳出自我調用,就是遞歸。
例如:
var fn = function(n){
if(n == 1) return 1;
else return n * fn(n-1);
}
js的執行原理是什麼?
JS是解釋執行的,即讀取一個語句就執行一個。以前的嚴格JS是以分號為語句的分隔符,但現在一些瀏覽器已經接受以換行符為分隔符(似乎是很多人喜歡用基於對象的編程了,而在JS中寫對象的函數是需要加分號的,所以很多人都愛忘)。
JS本身只提供語法解析與少部分內部函數支持,其他的均由宿主支持。比如在網頁JS中的window, document, navigator等對象,均是由瀏覽器提供基於其它語言的代碼,這些代碼通常被隱藏,但很大程度上決定了JS的運行效率。如果你有興趣,打開Chrome,按F12,調處Console,然後輸alert(注意沒有()),你就會發現[native code]這個東西。
如何將javascript代碼編譯為c++或java
java是不能夠編譯C/C++文件的。他們原理完全不同。背後的運行機制也完全不一樣。
C/C++源文件只能夠用C/C++的編譯器來編譯。
以GCC編譯器為例,整個編譯可以分為四步。
第一步是預處理,包括語法檢查等工作。
gcc -P abc.c
第二步由源程序生產彙編語言代碼。
gcc -S abc.c
會生成abc.s文件,這個文件里就是彙編代碼。
第三步編譯器生成目標代碼,一個源文件生成一個目標代碼。
gcc -c abc.c
會生成abc.o
第四步連接器從目標代碼生成可執行文件。
gcc abc.o
目標代碼包括機器碼和符號表(函數及變數名)。連接器的主要作用是通過符號表在庫文件和其他模塊中找到在目標代碼中引入或未定義的符號(函數及變數名),將幾個目標代碼合成可執行文件。
javascript框架是什麼意思?有什麼作用?怎麼理解?最好舉個例子
淺談js框架設計 在這個JavaScript框架隨處亂跑的時代,你是否考慮過寫一個自己的框架?下面的內容也許會有點幫助。
一個框架應該包含哪些內容?
1.語言擴展
大部分現有的框架都提供了這部分內容,語言擴展應當是以ECMAScript為基礎進行的,不應當依賴任何宿主環境,也就是說,作為一個框架的設計者,你應當保證你的語言擴展可以工作在任何宿主環境中,而不是僅僅適合瀏覽器環境。你必須保證把它放到WScript,SpiderMonkeyShell,Rhino Shell,Adobe ExtendScript Toolkit甚至FlashActionScript等環境中都能正確的工作,舉個現實一點的例子setTimeout不可以出現在其中,你也不能用XMLHTTP載入腳本運行,儘管它們看起來很貼近語言。保持這一部分的獨立性可以讓你方便的移植你的框架到其他宿主環境下。
2.數據結構和演算法
JS本身提供的內置對象非常有限,很多時候,框架應該提供一些數據結構和演算法來幫助使用者更好的完成邏輯表達。但我認為隨便翻本數據結構或者演算法書用JS挑幾個實現了加到框架中是不負責任的,多數數據結構應當以庫的形式存在而非框架。框架中的數據結構應該足夠常用而且實現不是非常複雜的,可以考慮的如集合、哈希表、鏈表、有序數組以及有序數組上的二分搜索。對JS來說,對象是一個天然的字元串哈希表,而集合很容易在哈希表上實現,因此只需要處理掉Object的內置方法,我們就可以實現一個高效的集合或哈希表。
3.DOM擴展
JS主要應用於Web開發,目前所有的框架也都用於瀏覽器環境,那麼,瀏覽器端環境里重點中的重點DOM當然也是框架的擴展目標了,如果一個框架不提供DOM的擴展,那麼其實基本沒什麼用處了。需要注意的是,DOM擴展也有w3c的標準可依,所以,不要嘗試為各種瀏覽器做一些奇怪的擴展,比如FF下面的element們的prototype,框架的編寫者應當無視它們。DOM擴展的主要任務之一是兼容性,不同瀏覽器上的DOM實現相差很多,框架必須消除這些實現帶來的差異,提供統一的訪問方式。當然,做為框架,應當提供一些更為方便的介面,將宿主提供的DOM對象用js對象封裝是個不錯的想法,但是同時這也很可能會造成內存泄露,所以做這事之前,了解內存泄露是必要的。實際上,自己想像的擴展遠不如W3C的設計,比如如果你能更完整地實現XPath,你就能比JQuery做的更好。
4.AJAX擴展
大部分現有框架出現的原因都是因為AJAX,所以如果你想設計一個受歡迎的框架,AJAX是必須要做的。跟DOM擴展很相似,AJAX擴展的主要任務是兼容和內存泄露,對AJAX的核心組件XMLHttpRequest對象,必須在IE6中使用ActiveX創建,而ActiveX又有各種版本,而隨之而來的內存泄露和兼容性變得非常麻煩,比如:事件函數名大小寫、this指向、事件函數的null賦值。處理好這些兼容性的基礎上,可以做進一步的工作,提供一些常用的實現。應該指出的是,除非你確定你提供的介面比原來的更好,否則不要改變原來的XMLHttpRequest對象的介面,比如寫一個Request函數來代替open和send,如果你不清楚W3C的專家們為什麼這麼設計,請不要把他們想像成傻瓜。我想自己另外寫一個兼容且內存安全的XMLHttpRequest加入到自己框架的命名空間里,使它從外部看上去跟W3C描述的XMLHttpRequest一模一樣是不錯的辦法,對XMLHttpRequest我認為唯一可以考慮的修改是提供onsuccess事件。當然針對一些複雜功能的AJAX擴展也是可行的,比如HTMLHttpRequest類似的擴展可以讓AJAX初學者喜歡你的框架。
5.效果
時間效果是最能刺激用戶神經的,漸隱、緩動、滑動、顏色漸變這些都很不錯,其實技術難度也不是很高。拖動效果則是瀏覽器中一個很重要的效果,用滑鼠事件來模擬本來很容易,不過兼容和setCapture也是很麻煩的事情。這一部分內容量力而為就可以了。
7.腳本管理
因為大家非常喜歡C++風格的include或者JAVA風格的import,很多框架提供了基於AJAX的腳本管理,不過同步載入的效率問題是巨大的。之前我們曾經作過各種嘗試,希望找到一個瀏覽器中不用XMLHTTP載入外部js的方法,但是最後得出的結論是:不可能。
關於這個,略微思考就可以知道,Java C++ C#都是編譯型語言,include 和import都是編譯期處理,在js中做到類似的事情是不太可能的。為了實現類似的功能,我想我們可以利用服務端程序或者編寫一個文本工具來實現。
YUI將所有的js文件依賴關係提取出來的做法是可行的,不過這不能算是include的實現方式了,維護依賴關係不是一件很簡單的事情。
8.控制項
EXT的成功告訴我們:提供優質的控制項才是框架的王道。你不能指望優質的擴展會吸引更多使用者。多數人只關心如何快速完成手邊的工作。當然不是所有框架都要提供這部分內容。控制項好壞取決於能力和美工,不過至少要保證框架里的控制項不會內存泄露。
框架設計的若干原則:
1.不要做多餘的事
對這框架設計來說,我認為一個非常必要的原則就是不要做多餘的事情,舉個極端的的例子:
function add(a,b)
{
return a+b;
}
這樣的代碼如果出現在框架中,就是個十足的笑話。不過大多數時候,事情不是那麼明顯,很多框架試圖用某種形式在JS中”實現”OOP,但是實際上,JS本身是OO的(ECMA262中明確指出來的,不像某些人所說是基於對象云云)只是有一些語法跟Java等語言不同。那麼顯然這些OOP的”實現”其實是跟上面的例子一樣的道理。另一個例子是Array.prototype.clone
Array.prototype.clone=function(){
return this.slice();
}
2.慎用prototype擴展
很多框架利用修改原生對象的prototype來做語言擴展,但我認為應當小心地看待這件事,毫無疑問這將造成一定的命名污染,你無法保證框架的使用者或者與你的框架共存的其他框架不會使用同樣的名字來完成其他的事情。特別需要注意的是,Object和Array這兩個對象的prototype擴展格外的危險,對Object來說,如果Object被修改,那麼框架的使用者將無法創建一個未被修改的乾淨的對象,這是一個致命的問題,尤其如果你的使用者喜歡用forin來反射一個對象的屬性。Array.prototype修改的危險來自js一個不知有意還是無意的小小設計,對原生的Array來說,任何情況下for和forin的遍歷結果是相同的,而因為無法控制自定義的屬性是不可枚舉的,任何Array.prototype的修改都會破壞這種特性。一方面,我認為不應當推薦用forin遍曆數組,這其中包含著錯誤的語義。另一方面,框架的設計者必須尊重這些使用者,因為對於ECMA所定義的語法而言,它是正確的做法。其中包含著這樣一個簡單的事實:假如你的框架中修改了Array.prototype,那麼一些之前能正確工作的代碼變得不可正確工作。
直接修改prototype看上去非常誘人,但是在考慮它之前應當先考慮兩種可能的方案:
(1)函數
提供一個以對象為第一個參數的函數比如 Array.prototype.each =
function ForEach(arr,f)
{
if(arr instanceof Array)/*…*/;
}
(2)繼承
以return的形式繼承一個內置對象 比如考慮Array.prototype.each=
function ArrayCollection()
{
var r=Array.apply(this,arguments);
r.each=function(){/*……*/};
return r;
}
套用一句名言,不要修改原生對象的prototype,除非你認為必要。不過修改原生對象的prototype確實有一些特殊的用途(就是”必要的情況”),主要體現在2點:文字量支持和鏈式表達。舉一個例子可以體現這兩點:
var cf=function f(a,b,c,d)
{
/*……..*/
}.$curry(3,4).$curry(5).$run();
如果希望實現類似上面的表達方式,可能就需要擴展Function.prototype,權衡一下的話,如果你認為命名污染的代價是值得的,那麼也是可以提供給使用者的。
一個比較討巧的辦法是把選擇權利交給使用者,提供一個擴展器:
function FunctionExtend()
{
this.$curry=function(){/*……*/};
this.$run=function(){/*……*/};
}
如果用戶喜歡可以FunctionExtend.apply(Function.prototype); 如果不喜歡擴展 則可以
var r=function(){/*……*/};
FunctionExtend.apply(r);
3.保持和原生對象的一致
不知你有沒有注意到,內置對象Function Array等都有這樣的性質:
new Function()跟Function的結果完全一致(String Number Boolean這種封裝型對象沒有這樣的性質)
如果框架中提供的類也具有這種性質,會是不錯的選擇。這僅僅是一個例子,如果你注意到了其他細節,並且讓框架中的類和原生對象保持一致,對使用者來說是非常有益的。
4.尊重語言 尊重用戶
編寫框架應該尊重依賴的語言環境,在對原有的元素修改之前,首先應該考慮到原來的合理性,任何語言的原生環境提供的都是經過了精心設計的,在任何修改之前,至少應該考慮這幾點:效率、命名規範、必要性、與其他功能是否重複。如果你沒有付出至少跟語言的設計者相當的工作量,你的做法就是欠考慮的。
編寫框架也應該尊重用戶的所有習慣,將編寫者的喜好強加給使用者並不是框架應該做的事情。框架應該保證大部分在沒有框架環境下能運行的代碼都能在框架下正常工作,這樣用戶不必為了使用你的框架而修改原有的代碼。
5.規範命名和使用命名空間
減少命名污染可以讓你的框架跟其他框架更好地共存。很多框架使用了命名空間來管理,這是良好的設計。命名應該是清晰且有實際意義的英文單詞,如前面3所述,為了保持和原生對象的一致,命名規則最好貼近原生對象,比如類名第一字母大寫,方法名用駝峰命名。捎帶一提prototype中的$實在是非常糟糕的設計,無法想像$出現的目的僅僅是為了讓使用者少寫幾個字母。這種事情應該交給你的用戶在局部代碼中使用
如何用js實現中綴表達式轉後綴表達式然後求值
逆波蘭表達式,它的語法規定,表達式必須以逆波蘭表達式的方式給出。逆波蘭表達式又叫做後綴表達式。這個知識點在數據結構和編譯原理這兩門課程中都有介紹,下面是一些例子:
正常的表達式 逆波蘭表達式
a+b — a,b,+
a+(b-c) — a,b,c,-,+
a+(b-c)d — a,d,b,c,-,,+
a=1+3 — a=1,3 +
http=(smtp+http+telnet)/1024 寫成什麼呢?
http=smtp,http,telnet,+,+,1024,/
逆波蘭表達式是一種十分有用的表達式,它將複雜表達式轉換為可以依靠簡單的操作得到計算結果的表達式。例如(a+b)(c+d)轉換為ab+cd+
它的優勢在於只用兩種簡單操作,入棧和出棧就可以搞定任何普通表達式的運算。其運算方式如下:
如果當前字元為變數或者為數字,則壓棧,如果是運算符,則將棧頂兩個元素彈出作相應運算,結果再入棧,最後當表達式掃描完後,棧里的就是結果。
將一個普通的中序表達式轉換為逆波蘭表達式的一般演算法是:
(1)首先構造一個運算符棧,此運算符在棧內遵循越往棧頂優先順序越高的原則。
(2)讀入一個用中綴表示的簡單算術表達式,為方便起見,設該簡單算術表達式的右端多加上了優先順序最低的特殊符號「#」。
(3)從左至右掃描該算術表達式,從第一個字元開始判斷,如果該字元是數字,則分析到該數字串的結束並將該數字串直接輸出。
(4)如果不是數字,該字元則是運算符,此時需比較優先關係。
做法如下:將該字元與運算符棧頂的運算符的優先關係相比較。如果,該字元優先關係高於此運算符棧頂的運算符,則將該運算符入棧。倘若不是的話,則將棧頂的運算符從棧中彈出,直到棧頂運算符的優先順序低於當前運算符,將該字元入棧。
(5)重複上述操作(3)-(4)直至掃描完整個簡單算術表達式,確定所有字元都得到正確處理,我們便可以將中綴式表示的簡單算術表達式轉化為逆波蘭表示的簡單算術表達式。
下面是程序化演算法流程:
1、建立運算符棧stackOperator用於運算符的存儲,壓入’\0’。
2、預處理表達式,正、負號前加0(如果一個加號(減號)出現在最前面或左括弧後面,則該加號(減號)為正負號) 。
3、順序掃描表達式,如果當前字元是數字(優先順序為0的符號),則直接輸出該數字;如果當前字元為運算符或括弧(優先順序不為0的符號),則判斷第4點 。
4、若當前運算符為'(‘,直接入棧;
若為’)’,出棧並順序輸出運算符直到遇到第一個'(‘,遇到的第一個'(‘出棧但不輸出;
若為其它,比較stackOperator棧頂元素與當前元素的優先順序:
如果 棧頂元素 = 當前元素,出棧並順序輸出運算符直到 棧頂元素 當前元素,然後當前元素入棧;
如果 棧頂元素 當前元素,直接入棧。
5、重複第3點直到表達式掃描完畢。
6、順序出棧並輸出運算符直到棧頂元素為’\0’。
各運算符及符號優先順序:
‘\0’: -1
‘)’: 1
‘(‘: 2
‘+’、’-‘: 3
‘*’、’/’、’%’: 4
‘^’: 5
其它: 0
/**
* 計算逆波蘭表達式的值
*/
function calculate(RPolishArray){
var result = 0;
var tempArray = new Array(100);
var tempNum = -1;
for(i = 0;i RPolishArray.length;i++){
if(RPolishArray[i].match(/\d/)){
tempNum++;
tempArray[tempNum] = RPolishArray[i];
}else{
switch(RPolishArray[i]){
case ‘+’:
result = (tempArray[tempNum-1] *1) + (tempArray[tempNum] * 1);
tempNum–;
tempArray[tempNum] = result;
break;
case ‘-‘:
result = (tempArray[tempNum-1] *1) – (tempArray[tempNum] * 1);
tempNum–;
tempArray[tempNum] = result;
break;
case ‘*’:
result = (tempArray[tempNum-1] *1) * (tempArray[tempNum] * 1);
tempNum–;
原創文章,作者:EYKN,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/146255.html