#javascript培訓
@author:zhoujiaping
@date:2017-08-01
使開發人員對javascript語言有較深入的理解,提升開發人員的js功底,在以后的項目中更準確、高效的使用js,編寫出高質量的js程序。
比如c語言,必須先經過編譯生成目標文件,然后鏈接各個目標文件和庫文件,生成可執行文件。
Java、scala則是先編譯成字節碼,然后解釋執行字節碼(可以理解為編譯型語言也可以理解為解釋型語言)。
準確的理解,java是編譯型語言,源代碼整個編譯成字節碼,java字節碼,再被解釋執行。
Python是解釋型語言,不過也可以先進行編譯,編譯成python的字節碼。
Javascript是解釋型語言。目前貌似還沒有直接將js整個編譯然后才執行(有說法是js動態性太強,先整體編譯難度太大,執行性能不如解釋執行高)。
注意:解釋型語言也是需要編譯的。區分編譯型語言和解釋型語言,是看源代碼是否整個編譯成目標代碼然后執行還是編譯一段執行一段。
JavaScript ( JS ) 是一種輕量級解釋型的,或是JIT編譯型的程序設計語言(參考https://developer.mozilla.org/zh-CN/docs/Web/JavaScript)
對于傳統編譯型語言來說,編譯步驟分為:詞法分析、語法分析、語義檢查、代碼優化和字節生成。
但對于解釋型語言來說,通過詞法分析和語法分析得到語法樹后,就可以開始解釋執行了(根據語法樹和符號表生成機器碼)。
這也就解釋了為什么都說js是解釋執行的,讀一句執行一句,但是實際上js中還沒執行到的代碼語法錯誤導致整個js不會執行的問題。
在瀏覽器中,多個<script>
標簽中的js代碼,是分段編譯的,但是全局對象是共享的(某一個<script>
標簽中的語法錯誤不會導致另一個<script>
中的代碼不執行)。這個可以參考http://www.cnblogs.com/RunForLove/p/4629510.html
準確的說,是某個問題是在編譯時做決策還是運行時做決策。
比如java,String s = null;變量s的類型在編譯時就可以確定為字符串類型。
比如python,變量不需要聲明,變量的類型在第一次賦值時由值的類型確定。
比如js,var val;val = ‘1’;變量val在運行val=’1’時才能確定為字符串類型。
js是動態類型語言。
Java、scala是強類型語言,變量一旦聲明,它的類型以后不能被改變。
Python是強類型語言。
Js是弱類型語言。比如
var v = ‘1’;v=1;v=true;
這在js中是合法的。
聲明式編程,告訴計算機我要做什么,而不是如何做。在更高層面寫代碼,更關心的是目標,而不是底層算法實現的過程。 例如 css, 正則表達式,sql 語句,html, xml…
命令式編程,告訴計算機如何做,而不管我想要做什么。解決某一問題的具體算法實現。例如java、c。
函數式編程,將計算機運算看做是數學中函數的計算,并且避免了狀態以及變量的概念。
很多語言并不是單純的支持某一種范式,像java8也添加了部分對函數式的支持,js是一個非常靈活的語言,支持命令式和函數式編程。一般函數式語言都會有filter、map、reduce等函數。某些情況下用函數式編程能更好的解決問題,所以對程序員的要求是不僅要熟悉命令式編程,還要熟悉函數式編程。
一般編譯型語言性能比解釋型語言高。但是由于編譯型語言需要先進行編譯。解釋型語言的好處是,部署到線上的是源代碼,可以直接修改線上環境的代碼,解決一些bug。這在做系統集成時很方便。
編譯型語言通常會用xml做配置文件,因為我們通常不會改編譯后的字節碼。解釋型語言的配置,直接寫在源代碼里更方便,用xml做配置就顯得多余。
靜態語言,有利于編譯時檢查。比如java、在ide中為對象的一個不存在的屬性賦值能在編譯時檢查出錯誤。Js是動態語言。對象的某個屬性是否存在,在編譯時無法確定。這導致某些錯誤要到運行時才可能發現。所以一般js程序的正確性,更需要單元測試保證。
強類型語言由于類型在聲明之后不允許改變,所以能實現編譯時類型檢查。
動態語言和弱類型語言,則更靈活,實現相同功能的代碼量通常更少或者更容易實現復雜功能。當然可讀性可維護性方面不如靜態語言和強類型語言。
js代碼的執行是單線程的。很多瀏覽器現在可以使用worker實現多線程。nodejs環境也可以多線程執行js。
單線程執行,避免了共享、鎖、并發更新dom等非常棘手的問題。
如下代碼
setTimeout(function(){
console.info(‘hello kitty’);
},1000);
通常認為會在1秒后在控制臺打印hello kitty。
但是js是單線程執行的,它并沒有新開一個線程等到1秒后執行該線程。而是將回調函數放在setTimeout的回調隊列里。即使1秒的時間到了,也要在執行完當前代碼之后,才調用回調。
所以如果有
setTimeout(function(){
console.info(‘hello kitty’);
},1000);
While(true){
}
那么控制臺是看不到hello kitty的。
結論是,setTimeout的回調并不一定會準時執行,它可能會延遲,甚至不會執行。
這和java中新建一個task不一樣。
與java是一個面向對象的語言不同,Js是一個基于對象的語言。
也就是說,不要把java中的那一套拿過來學習js,學習js要從0開始。
Js中沒有類的概念,沒有繼承,沒有接口,沒有多態,沒有重載。
Js和java是不同的編程語言,它有自己對世界的理解,有自己的抽象、模型、機制。
Prototype就是js中實現復用的一種機制。
我們在代碼中定義的每一個js對象,都有一個內部屬性[[proto]],它的值是一個對象。
當我們訪問對象的某個屬性時,如果這個屬性在該對象中未找到,那么解釋器就會到該對象的[[proto]]中去找,如果還沒有找到,則會去[[proto]]的[[proto]]中找,直到找到Object的prototype。這些[[proto]]相連成為一個原型鏈。
例如:
var o2 = Object.create({a:'A'})
console.info(o2.a);//A
這里我們定義了一個對象o2,指定它的[[proto]]為{a:’A’}。
通常,prototype的使用并不是這樣的,一般是在prototype中定義方法。
例如:
Var proto = {
sleep:function(){
...
},
eat:function(){
...
}
};
Var o1 = Object.create(proto);
o1.name = 'lucy';
Var o2 = Object.create(proto);
o2.nick = 'luna';
O1.sleep();
O2.sleep();
方法是各個對象公共的而屬性則是各個對象自己的。
這里我們并沒有解釋什么是對象,也沒有用到類的概念。
在js中,對象就是一組屬性名及其對應的值的集合。簡單理解就是鍵值對集合。
Js對象的創建,并不是像java一樣需要類。Js中根本沒有類的概念。
即使是新版的js,提供了class語法,它實際上也只是個語法糖,和真正的面向對象中的類的概念是不同的。
和prototype強相關的還有函數。
Js中的函數,被設計成為可以擁有多重身份的概念。后面會講到。這里只講它作為構造器時和prototype之間的關系。
例如:
function Person(name,age){
this.name = name;
this.age = age;
}
Person.prototype = {
Constructor:Person,
sayHello:function(){
Return “hello”;
}
};
Var p1 = new Person();
Var p2 = new Person();
在js中,每個函數都會有一個prototype屬性,這個是我們可以訪問的,也可以給它賦值。
每一個對象都有一個[[proto]]屬性。這個[[proto]]和它的構造器的prototype指向的是同一個對象。
初學js的時候,非常容易被函數的多重身份弄暈。
一個js函數,可以作為對象、普通的函數、對象的方法、對象的構造器。
例如:
function foo(){
}
foo.a = ‘A’;
foo.b=’B’;
函數foo可以保存字符串A和字符串B,它是一個普通對象,它的類型是Function,就好比{}的類型是Object。
function foo(){
console.info(‘hello kitty’);
}
foo();//hello kitty
這個時候,它是一個普通的函數。
Function Person(){
}
Person.prototype.sayHello = function(){
Console.info(‘hello’);
}
new Person().sayHello();
Person是對象的構造器。sayHello是對象的方法。
Js解釋器,將function作為函數和作為方法執行時,是不一樣的,主要是在作用域、this方面。
作用域,準確的說是變量的作用域,它表示的是變量起作用的范圍。
Js中變量的作用域,是詞法作用域,也叫靜態作用域。
和詞法作用域相對的,還有動態作用域。
一般我們接觸的編程語言,都用詞法作用域。比如java、scala、python、js。
詞法作用域的函數中遇到既不是形參也不是函數內部定義的局部變量的變量時,去函數定義時的環境中查詢。
動態域的函數中遇到既不是形參也不是函數內部定義的局部變量的變量時,到函數調用時的環境中查。
動態作用域由于變量的作用范圍很難確定(如果變量既不是形參也不是函數內部定義的局部變量),很難知道某個變量具體是指向哪個對象,所以現代編程都不用動態作用域。
作用域在ECMAScript5.1規范中沒有被專門解釋,但是它解釋了詞法環境的概念,以及說明了函數的[[scope]]屬性。
網上博客以及一些書籍、都有介紹js的作用域的概念,但是往往只能解決一些簡單的問題,對于更復雜的問題,往往不能給予解釋。講的最合理深入的是《javascript高級程序設計第三部》。為了做到對相關概念及原理的清晰解釋,這里用ECMAScript5.1規范中的術語。
可執行代碼、執行環境(及其三個組件詞法環境、變量環境、this)、全局環境(是一個詞法環境)、全局對象window、詞法環境、環境記錄項。
包括3種:全局代碼、eval代碼、函數代碼。
當控制器轉入 ECMA 腳本的可執行代碼時,控制器會進入一個執行環境。當前活動的多個執行環境在邏輯上形成一個棧結構。該邏輯棧的最頂層的執行環境稱為當前運行的執行環境。任何時候,當控制器從當前運行的執行環境相關的可執行代碼轉入與該執行環境無關的可執行代碼時,會創建一個新的執行環境。新建的這個執行環境會推入棧中,成為當前運行的執行環境。
解釋執行 全局代碼 或使用 eval 函數輸入的代碼會創建并進入一個新的執行環境。每次調用 ECMA 腳本代碼定義的函數也會建立并進入一個新的執行環境,即便函數是自身遞歸調用的。每一次 return 都會退出一個執行環境。拋出異常也可退出一個或多個執行環境。
例如:
var val = 'hello';
function f1(){
function f2(){
}
f2();
}
function f3(){
}
f1();
f3();
首先在執行任何js代碼之前,會創建一個執行環境,放入執行環境棧。
然后執行函數f1,在執行f1中的所有代碼之前,會創建一個執行環境,放入執行環境棧。
然后執行函數f2,在執行f2中的所有代碼之前,會創建一個執行環境,放入執行環境棧。
f2執行完畢后,從執行環境棧彈出一個執行環境。
f1執行完畢后,從執行環境棧彈出一個執行環境。
然后執行函數f3,在執行f3中的所有代碼之前,會創建一個執行環境,放入執行環境棧。
f3執行完畢后,從執行環境棧彈出一個執行環境。
如圖(執行f2時的執行環境棧)
每個執行環境包含三個組件
組件 | 作用目的 |
---|---|
詞法環境 | 指定一個詞法環境對象,用于解析該執行環境內的代碼創建的標識符引用。 |
變量環境 | 指定一個詞法環境對象,其環境數據用于保存由該執行環境內的代碼通過 變量表達式 和 函數表達式 創建的綁定。 |
This 綁定 | 指定該執行環境內的 ECMA 腳本代碼中 this 關鍵字所關聯的值。 |
其中執行環境的詞法環境和變量環境組件始終為 詞法環境 對象(這里要區分詞法環境組件和詞法環境對象)。當創建一個執行環境時,其詞法環境組件和變量環境組件最初是同一個值。在該執行環境相關聯的代碼的執行過程中,變量環境組件永遠不變,而詞法環境組件有可能改變。
變量對象保存該執行環境聲明的變量和函數的引用(對于函數代碼,還會有arguments和形參)。
如圖:
詞法環境是一個用于定義特定變量和函數標識符在 ECMAScript 代碼的詞法嵌套結構上關聯關系的規范類型。一個詞法環境由一個環境記錄項和可能為空的外部詞法環境引用構成。通常詞法環境會與特定的 ECMAScript 代碼諸如 FunctionDeclaration,WithStatement 或者 TryStatement 的 Catch 塊這樣的語法結構相聯系,且類似代碼每次執行都會有一個新的語法環境被創建出來。
環境記錄項記錄了在它的關聯詞法環境域內創建的標識符綁定情形。
外部詞法環境引用用于表示詞法環境的邏輯嵌套關系模型。(內部)詞法環境的外部引用是邏輯上包含內部詞法環境的詞法環境。外部詞法環境自然也可能有多個內部詞法環境。例如,如果一個 FunctionDeclaration 包含兩個嵌套的 FunctionDeclaration,那么每個內嵌函數的詞法環境都是外部函數本次執行所產生的詞法環境。
共有 2 類環境記錄項: 聲明式環境記錄項 和 對象式環境記錄項 。聲明式環境記錄項用于定義那些將 標識符 與語言值直接綁定的 ECMA 腳本語法元素,例如 函數定義 , 變量定義 以及 Catch 語句。對象式環境記錄項用于定義那些將 標識符 與具體對象的屬性綁定的 ECMA 腳本元素,例如 程序 以及 With 表達式 。
如下代碼
其執行過程如下
上面的圖漏了一個,環境記錄項中還有一個屬性foo。
上面的圖漏了一個,foo對應的環境記錄項中還有一個屬性bar。
上面的圖,window對象中漏了一個屬性foo,foo對應的環境記錄項中還有一個屬性bar。
這里只舉了一個簡單的例子。還有其他問題,比如詞法環境組件和變量環境組件什么時候不一樣?不一樣的時候分別又是什么?this綁定什么時候不是綁定window?除了全局執行環境,還有什么時候用到了對象式環境記錄項?涉及到構造器執行時,兩個組件和this又是什么?
當使用with的時候, 會創建一個新的詞法環境,該詞法環境的環境記錄項是一個對象式環境記錄項 。然后,用這個新的 詞法環境 執行語句。最后,恢復到原來的 詞法環境 。
這個時候,詞法環境組件和變量環境組件便不一樣了。
this綁定,可以分為4種。默認綁定、隱式綁定、顯示綁定、new綁定。
也就是說代碼中的this指代的是哪個對象,是不同的,它是根據調用方式和調用位置決定的。具體請參考《你不知道的javascript》上卷第二章?;蛘邊⒖家幏?。
注意:全局執行環境的特殊性,全局執行環境的this、詞法環境組件的環境記錄項、變量環境的環境記錄項,都是window。而函數的執行環境不會出現這種情況。
所以在全局代碼中有例如如下的特殊性:
var lang1 = 'javascript';
console.info(this.lang1);//javascript
this.lang2 = 'js';
console.info(lang2);//js
這在其他環境是模擬不出來的。你無法讓一個函數的執行環境的詞法環境組件的環境記錄項和該執行環境的this綁定到同一個對象。
由于this指向的對象并不是編譯時確定的,它是運行時確定的,所以有的函數式編程經驗的程序員強烈建議js中盡量不要使用this。
如下代碼
在執行全局代碼時,會創建一個foo函數對象,設置它的各種內部屬性,其中包括形參列表、原型、外部詞法環境(注意,這個時候函數foo以后執行時的作用域鏈除最后一個都確定了,這是在函數對象被創建時確定的。foo函數內部出現的標識符、要么在foo函數內部被聲明、要么是foo函數的形參、否則從外部詞法環境中去找)等。
在執行foo函數時,會創建一個新的詞法環境,用到它被創建時保存的外部詞法環境,形成詞法環境鏈(作用域鏈)。
如果函數foo被多次調用,那么會多次創建bar函數對象。foo執行完畢,bar函數對象可能會被釋放(如果沒有外部引用指向該函數對象,該函數對象將被釋放)。
總之,就是理解函數的相關機制,要結合創建時和執行時。
閉包是函數式編程中的一個非常重要的概念。各種書籍對閉包的解釋各不相同。
百度百科的描述是:閉包是指可以包含自由(未綁定到特定對象)變量的代碼塊;這些變量不是在這個代碼塊內或者任何全局上下文中定義的,而是在定義代碼塊的環境中定義(局部變量)。
例如:
function intIterator(){
var i = 0;
return function iter(){
return i++;
}
}
var iter = intIterator();
console.info(iter());
console.info(iter());
console.info(iter());
console.info(iter());
console.info(iter());
打印結果0,1,2,3,4
函數iter的代碼中訪問了一個自由變量i,它在iter的形參和局部變量中并未定義。導致外部函數intIterator雖然執行完畢,但是局部變量i不會被釋放。
結合前面執行環境的內容,具體過程如下:
執行intIterator函數之前
intIterator函數返回之前
iter函數返回之前
iter函數返回之后
注意:即使iter只訪問了intIterator中的一個變量i,intIterator對應的變量環境中所有的變量都不會被釋放?。?!這就是閉包使用不當造成的內存溢出?。?!
比如下面的代碼
function intIterator() {
var i = 0;
var arr = [1,2,3,4,5];
return function iter() {
return i++;
}
}
var iter = intIterator();
變量i和數組arr就不會被釋放,即使它在intIterator函數執行完畢之后。
對于i,是我們以后用到的,但是對于arr,以后再也沒被用到。
首先關于異步的概念,在編程語言里貌似沒有精確的定義?;蛘呤窃诙嗑€程語言中定義的。要準確理解什么是異步,建議參考Linux五種IO模型。
簡單說就是一個任務分成兩段,先執行第一段,然后轉而執行其他任務,等做好了準備,再回過頭執行第二段。
js中異步實現的四種方式:回調函數、事件監聽、發布訂閱、promise。
所謂回調函數,就是把任務的第二段單獨寫在一個函數里面,等到重新執行這個任務的時候,就直接調用這個函數。
一般有的操作在時序上依賴于某個異步操作的結果。比如
$.get(url,data,function(res){
render(res);
...
},’json’);
反例:
var res;
$.get(url,data,function(r){
res = r;
},’json’);
render(res);
對于初學者,一定要強調正確寫出包含異步操作的代碼。特別是有多個異步的情況。
上面是回調函數的方式?;卣{函數,是在異步操作成功之后被系統自動調用的函數。我們并不需要手動調用它。
事件監聽的例子如下
$(‘#btn’).on(‘click’,function(){
});
我們會發現其實這里也有回調函數。其實$.get用的XMLHttp也是用的事件監聽機制,事件處理函數就是我們寫的回調。
在這里區別回調和事件監聽,是因為某些情況如setTimeout,并沒有明顯的體現出事件。
使用回調函數的寫法,往往導致代碼形式可讀性差,難以維護。為了解決這個問題,jquery提供了Deferred模塊。當然還有其他的js庫也有提供相關工具。
例子
var defer = $.post(url,data,null,’json’)
.done(function(res){
...
})
.fail(function(res){
...
});
這比回調好用多了,它能夠實現回調不能實現的好多功能,比如發送請求的代碼和回調函數的注冊是分開的、可以注冊多個回調、可以把Deferred對象和其他異步的Deferred對象組合使用實現更復雜的邏輯等。
但是當有嵌套的異步時,代碼還是很丑(丑表示可讀性差,難以維護)。
ES6中提供了generator函數解決這個問題。實際上是用協程解決該問題。
于是ES7中提供了關鍵字async和await,它是generator的語法糖。
但是真心好用,異步代碼寫起來就像同步代碼??勺x性可維護性大大增強。
generator我沒用過,但是我寫過很多async函數,感覺真的好用。
oo指的是面向對象。js是一門基于對象的語言。
有些場景用面向對象思維解決問題比較方便,于是就有了js的面向對象。
js中沒有類的概念,但是和類作對比,構造器和類的相似性最大。構造器能夠用來定義創建對象的模板。我們可以把構造器當成類。但是由于語言機制,在接口、封裝、繼承、多態方面,和傳統面向對象語言總有一些差異。
沒有實現封裝的版本:
function Person(name,birthday){
this.name = name;
this.birthday = birthday;
}
Person.prototype = {
constructor:Person,
sayHello:function(){
return ‘hello’;
},
sleep:function(){
return ‘don’t bother me’;
}
};
var p = new Person(‘javascript’,’1995’);
p.sayHello();
p.sleep();
console.info(p.name);
這種方式是目前使用最廣泛的方式,將一個類的屬性定義和方法定義分開來寫。
要實現封裝,定義類時就需要做很多額外的工作,利用閉包,代碼寫起來會很多。
要實現繼承,需要通過各種技術手段,解決各種問題??梢詤⒖肌秊avascript高級程序設計》第六章。
多態包括方法重寫和重載。你可以重寫方法,但是你無法在不修改原來的方法的前提下實現方法重載。js中的重載,是在同一個方法中手動對參數做判斷。
總之,js語言不是一門真正面向對象的語言,它有它自己的機制。不要強迫用傳統面向
的思維和習慣使用它。
ES6之前,要實現模塊化,要么用第三方模塊化工具,如RequireJS和SeaJS,要么自己實現模塊化工具。
nodejs中用的是CommonJS規范。
ES6添加了模塊化特性。使用import和export。但是我在chrome 61.0.3128.0上測試發現不行。所以為了兼容性,要么用第三方庫,要么用語法轉換。
我曾經為了一個地圖相關的項目,很多地圖相關的js代碼,但是沒有用模塊化,找個函數找半天,還不一定找對。psi產品中的js代碼也沒有模塊化,有些函數、變量在當前并未定義,要確定這些函數、變量在哪里定義,需要使用搜索,而不能根據當前文件的內容確定。
強烈推薦以后寫項目的時候用模塊化工具?。?!
題外話:要關注js的新發展、一定要關注MDN(Mozilla 開發者網絡)。js中非常多的新特性,都是從Mozilla發展而來的。很多問題在MDN上都可以找到。
《javascript高級程序設計》
《javascript核心指南》
《Ecmascript5.2規范》
《你不知道的javascript上》
《你不知道的javascript中》
JavaScript 技巧與高級特性
https://www.ibm.com/developerworks/cn/web/wa-lo-dojoajax1/
深入探討 ECMAScript 規范第五版https://www.ibm.com/developerworks/cn/web/1305_chengfu_ecmascript5/
ECMAScript 5.1版本標準
http://lzw.me/pages/ecmascript/#229
Javascript 中的神器——Promise
http://www.jianshu.com/p/063f7e490e9a
談談JavaScript的詞法環境和閉包(一)
https://segmentfault.com/a/1190000006719728
ES5中新增的Array方法詳細說明
http://www.zhangxinxu.com/wordpress/2013/04/es5%E6%96%B0%E5%A2%9E%E6%95%B0%E7%BB%84%E6%96%B9%E6%B3%95/
MDN web技術文檔 javascript
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
學習js,一定要看書,看權威的書籍。Js這門語言其實是初學者不容易掌握的,網上有的言論說js很容易學,其實個人覺得js并不容易學。
該文檔中的內容,難免由于個人知識有限,無法避免理解上的一些錯誤或者不全面,個人在學習js的時候,盡量還是要看書,看規范。培訓的內容,最好作為一個引子,引起大家的思考,使知道學習js有這些內容需要掌握,有這些概念需要理清。
由于內容較多,時間和精力有限,不能對每個主題作深入的講解,有些內容甚至沒有提及,例如立即執行函數、函數的定義方式、構造器的執行過程等,這些內容需要同學們自己去學習。
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...
在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...
在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...
z53次列車實時查詢 z533次列車經站時間?Z53次列車沿途經過哪些站? 經查無z533其他列車如下:Z3321:10從寧波開始,07:18到終點站武昌,歷時10:08,全程距離1140公里。共有寧波、余姚、紹興、金華、黃石、鄂州、武昌等7個??空?。Z53車次08:55從北京西開始,19:40到昆明終點站,歷時34:45,全程3174公里,共有19個??空?,分別是:北京西、保定、石家莊、邢臺...
安裝系統時出現filename546?怎么解決?重裝系統過程中出現ghost:flie name(546)解決方案:1.如果是用光盤安裝的,請再次更換安裝光盤。如果它仍然沒有 不要更換安裝系統光盤,請更換光盤驅動器,這可能是由于光盤劃傷和損壞或光盤驅動器有問題造成的。版本問題。制作鏡像的版本高,還原鏡像的ghost版本低。3.下載的iso或gho格式的系統是否完整一致,不完整或損壞的系統肯定無法安...
《踏山河》完整版歌詞歌曲踏山河完整版歌詞?踏山河歌詞曲原唱?《踏山河》是由祝何作詞,祝何作曲,由歌手“是七叔呢”演唱的歌曲,收錄于同名專輯《踏山河》,于2020年11月19日發行。歌詞:秋風落日入長河 ,江南煙雨行舟;亂石穿空 ,卷起多少的烽火;萬里山河都踏過 ,天下又入誰手;分分合合 ,不過幾十載春秋;我在 十面埋伏, 四面楚歌的時候;把酒與蒼天對酌,縱然一去不回 此戰又如何;誰見 萬箭齊發 星...