JavaScript快速入門

一、概述

JavaScript是世界上最流行的腳本語言末购,是一種運行在瀏覽器中的解釋型的編程語言,能夠?qū)崿F(xiàn)跨平臺虎谢、跨瀏覽器盟榴。雖然只是十多天時間的產(chǎn)物,并且有很多的缺陷和陷阱婴噩,但也造就了JavaScript的靈活和強大擎场。隨著Node.js的興起,JavaScript已經(jīng)從單純實現(xiàn)前端互動几莽,發(fā)展到可以全棧實現(xiàn)整個應(yīng)用迅办。尤其是在移動互聯(lián)網(wǎng)蓬勃發(fā)展以及應(yīng)用追求極致用戶體驗的今天,JavaScript更是必須要重視和掌握的章蚣。

二站欺、變量

1、變量的聲明

使用var關(guān)鍵字進(jìn)行變量的聲明纤垂,聲明的同時也可以進(jìn)行賦值矾策。變量的聲明只能有一次,但賦值可以有多次洒忧。如果只聲明變量蝴韭,但是變量沒有被賦值,此時變量的值為undefined熙侍。

var s = "Hello";

由于JavaScript屬于動態(tài)語言榄鉴,所以在定義變量時,不需要指定變量的類型蛉抓∏斐荆可以把任意數(shù)據(jù)類型賦值給變量,同一個變量可以使用不同的數(shù)據(jù)類型反復(fù)賦值巷送。

2驶忌、變量的提升

根據(jù)JavaScript的規(guī)則,變量的聲明會被提升,但是變量的初始化并不會被提升付魔。函數(shù)外聲明的變量聊品,會被提升到文檔頂部。函數(shù)內(nèi)聲明的變量几苍,會被提升到函數(shù)頂部翻屈。

function f() {
    var x = 1 + y;
    alert(x);
    var y = 2;
}
alert(x);

如果變量在函數(shù)內(nèi)沒有聲明,該變量會被提升為全局變量妻坝。

function f() {
    x = 1;
}
alert(x);

3伸眶、變量的作用域

如果變量在函數(shù)內(nèi)聲明,則該變量的作用域為整個函數(shù)體刽宪,在函數(shù)外不可訪問厘贼,屬于局部變量。

function f() {
    var x = 1;
}
alert(x);

函數(shù)可以嵌套圣拄,內(nèi)部函數(shù)可以訪問外部函數(shù)定義的變量嘴秸,反之則不可。

function outer() {
    var x = 1;
    function inner() {
        var y = x + 1;
        alert(y);
    }
    var z = y + 1;
    alert(z);
}

如果內(nèi)部函數(shù)與外部函數(shù)定義了相同的變量售担,根據(jù)就近原則赁遗,內(nèi)部函數(shù)的變量會覆蓋外部函數(shù)的變量。

function outer() {
    var x = 1;
    function inner() {
        var x = 2;
        alert(x);
    }
}

三族铆、函數(shù)

1岩四、函數(shù)的定義

定義函數(shù)有兩種方式:聲明和表達(dá)式。

1.1 函數(shù)聲明

function function_name(parameters) {
    ......
}

函數(shù)聲明后不會馬上執(zhí)行哥攘,只有被調(diào)用的時候才會執(zhí)行剖煌。

1.2 函數(shù)表達(dá)式

var f = function (parameters) {
    ......    
};
f(parameters);

將函數(shù)存儲在變量中,之后可以通過變量名來調(diào)用逝淹,而不需要函數(shù)名稱耕姊。

2、函數(shù)的參數(shù)

函數(shù)有個內(nèi)置的對象arguments栅葡,包含了函數(shù)調(diào)用的所有參數(shù)茉兰。

參數(shù)有兩種傳遞方式:值傳遞和引用傳遞。

2.1 值傳遞

函數(shù)只是獲取參數(shù)值欣簇,如果修改參數(shù)的值规脸,不會改變參數(shù)的原始值,在函數(shù)外是不可見的熊咽。

2.2 引用傳遞

函數(shù)獲得的是對象的引用莫鸭,在函數(shù)內(nèi)部修改對象屬性時,會改變屬性的原始值横殴,在函數(shù)外可見被因。

3、函數(shù)的調(diào)用

函數(shù)可以通過四種方式進(jìn)行調(diào)用。

3.1 自我調(diào)用

函數(shù)表達(dá)式梨与,如果后面緊跟()堕花,則會自動自我調(diào)用。聲明的函數(shù)不能自我調(diào)用蛋欣。

(function () {
    alert("Hello");
})();

3.2 作為函數(shù)被調(diào)用

當(dāng)函數(shù)沒有被其他對象調(diào)用時航徙,函數(shù)默認(rèn)是window全局對象的函數(shù)如贷。此時this的值是window全局對象陷虎。

function f() {
    alert("Hello");
    return this;
};
f();

3.3 作為方法被調(diào)用

可以將函數(shù)定義為對象的方法,該對象是函數(shù)的所有者杠袱。當(dāng)使用對象調(diào)用方法時尚猿,此時的this值指向調(diào)用函數(shù)的對象。

var obj = {
    x : 1,
    y : 2,
    f : function () { return this.x + this.y;}
};
obj.f();

3.4 作為構(gòu)造函數(shù)被調(diào)用

如果使用new關(guān)鍵字楣富,實際是創(chuàng)建了一個新的對象凿掂。新對象會繼承構(gòu)造函數(shù)的屬性和方法。此時this值指向新創(chuàng)建的對象纹蝴。為了區(qū)分普通函數(shù)和構(gòu)造函數(shù)庄萎,約定構(gòu)造函數(shù)的首字母為大寫。

function F(x, y) {
    this.x = x;
    this.y = y;
};
var obj = new F(1, 2);

3.5 call和apply

函數(shù)是一個對象塘安,可以調(diào)用call或apply方法糠涛。此時this值指向方法傳遞的對象。

function f(x, y) {
    return x+y;
};
arr = [1, 2];
f.call(obj, 1, 2);
f.apply(obj, arr);

call和apply方法的唯一區(qū)別就是前者傳遞整個參數(shù)列表兼犯,而后者傳遞一個參數(shù)數(shù)組忍捡。

4、閉包

內(nèi)嵌函數(shù)可以訪問上一層函數(shù)的變量切黔。閉包是可以訪問上一層函數(shù)作用域里變量的函數(shù)砸脊。如果上一層函數(shù)返回閉包函數(shù),那么就可以在上一層函數(shù)的外部訪問該函數(shù)的私有變量纬霞。利用閉包凌埂,可以實現(xiàn)調(diào)用公共方法,訪問私有變量诗芜。

此時返回的函數(shù)并沒有立刻執(zhí)行瞳抓,只有在調(diào)用返回函數(shù)時才真正執(zhí)行。因為返回函數(shù)不會馬上執(zhí)行绢陌,所以返回函數(shù)不要引用循環(huán)變量或后續(xù)會發(fā)生變化的變量挨下。否則,在真正執(zhí)行的時候脐湾,引用的變量可能已經(jīng)發(fā)生改變臭笆。

如果必須引用的話,可以再創(chuàng)建一個函數(shù),用該函數(shù)的參數(shù)綁定循環(huán)變量的值愁铺。這樣鹰霍,循環(huán)變量的值雖然發(fā)生了改變,但綁定到參數(shù)的值不會隨之改變茵乱。

四茂洒、對象

1、對象的定義

對象的定義有兩種方式瓶竭。

由若干鍵值對組成督勺,并將其賦值給一個變量。

var person = {
    name : "sean",
    age : "20",
    sayHello : function() {
        alert("Hello " + name);
    }
};
person.sayHello();

使用函數(shù)定義對象斤贰,然后創(chuàng)建新的對象實例智哀。

function person(name, age) {
    this.name = name;
    this.age = age;
};
var p = new person("sean", 20);

2、屬性和方法

由于JavaScript的對象是動態(tài)類型荧恍,所以可以給一個對象添加或刪除屬性瓷叫。當(dāng)訪問的屬性不存在時,會返回undefined送巡。如果要判斷一個屬性是否屬于某對象摹菠,可以使用in操作符。這里要注意的是骗爆,該屬性可能是對象繼承得來的次氨。如果要判斷一個屬性是否屬于某對象自身,可以使用hasOwnProperty方法淮腾。

3糟需、原型

雖然JavaScript可以面向?qū)ο缶幊蹋械膶ο蠖际菍嵗瘸粫^(qū)分類和實例的概念洲押。要想實現(xiàn)類的概念,就需要借助原型圆凰。

首先創(chuàng)建一個相當(dāng)于類概念的對象實例杈帐。

var person = {
    name : "",
    age : "",
    sayHello : function() {
        alert("Hello " + this.name);
    }
};

然后創(chuàng)建一個新的對象實例,使其依賴這個原型专钉。

var sean = {
    name : "sean"
};
sean.__prototype__ = person;
sean.sayHello();

也可以使用Object.create()方法挑童,傳入一個原型對象,并創(chuàng)建一個基于該原型的新對象跃须。

var sean = Object.create(person);
sean.name = "sean";
sean.sayHello();

4站叼、創(chuàng)建對象

JavaScript對每個創(chuàng)建的對象都會設(shè)置一個原型,指向該對象的原型對象菇民。除了直接創(chuàng)建一個對象外尽楔,還可以使用構(gòu)造函數(shù)來創(chuàng)建對象投储。使用構(gòu)造函數(shù)創(chuàng)建的對象,會從原型獲得一個constructor屬性阔馋,該屬性指向構(gòu)造函數(shù)本身玛荞。

5、原型鏈

當(dāng)訪問一個對象的屬性時呕寝,首先在當(dāng)前對象上查找該屬性勋眯。如果沒有找到,就到其原型對象上查找下梢。如果還沒有找到客蹋,就一直上溯到Object的原型對象。如果還沒有找到怔球,就返回undefined嚼酝。這樣就形成了一條原型鏈。

因為函數(shù)也是對象竟坛,所以函數(shù)也擁有原型鏈。首先是函數(shù)本身钧舌,然后是Function.prototype担汤,最后是Object.prototype。

6洼冻、繼承

繼承不僅僅是對象的屬性和方法的繼承崭歧,原型鏈也要體現(xiàn)出繼承關(guān)系。

首先撞牢,定義新的構(gòu)造函數(shù)率碾,并在內(nèi)部調(diào)用希望繼承的構(gòu)造函數(shù),實現(xiàn)屬性和方法的繼承屋彪。

其次所宰,借助中間函數(shù),將新的構(gòu)造函數(shù)的原型指向繼承的構(gòu)造函數(shù)的原型畜挥,實現(xiàn)原型鏈繼承仔粥。

最后,將新的構(gòu)造函數(shù)的constructor屬性重新指向新的構(gòu)造函數(shù)蟹但。

7躯泰、瀏覽器對象

window對象不但是全局對象,還表示瀏覽器窗口华糖。
屬性innerWidth和innerHeight分別表示瀏覽器窗口的內(nèi)部寬度和高度麦向,即用于顯示網(wǎng)頁的凈寬高。屬性outerWidth和outerHeight分別表示瀏覽器窗口的整個寬度和高度客叉。

navigator對象表示瀏覽器的信息诵竭。屬性appName表示瀏覽器名稱景描。屬性appVersion表示瀏覽器版本。屬性language表示瀏覽器設(shè)置的語言秀撇。屬性platform表示操作系統(tǒng)類型超棺。屬性userAgent表示瀏覽器設(shè)定的User-Agent字符串。

screen對象表示屏幕的信息呵燕。屬性width表示屏幕寬度棠绘,單位是像素。屬性height表示屏幕高度再扭,單位是像素氧苍。屬性colorDepth表示顏色位數(shù)。

location對象表示當(dāng)前頁面的URL信息泛范。屬性href表示整個URL让虐。屬性protocal表示使用的協(xié)議。屬性host表示主機名罢荡。屬性port表示端口號赡突。屬性pathname表示訪問的路徑。屬性search表示查詢參數(shù)区赵。方法assign加載一個新頁面惭缰。方法reload重載當(dāng)前頁面。

document對象表示當(dāng)前頁面笼才。屬性title表示瀏覽器窗口的標(biāo)題漱受。屬性cookie獲取當(dāng)前頁面的Cookie。方法getElementById按照元素的id獲取一個DOM節(jié)點骡送。方法getElementByTabName按照元素的標(biāo)簽名稱獲取一組DOM節(jié)點昂羡。

history對象保存瀏覽器的歷史記錄。

五摔踱、DOM

當(dāng)頁面被加載時虐先,瀏覽器解析HTML文檔,并會創(chuàng)建頁面的文檔對象模型DOM昌渤。DOM是一個樹形結(jié)構(gòu)赴穗,通過操作DOM節(jié)點,可以訪問或改變文檔的所有元素膀息。針對DOM的操作主要有四種:查找般眉、更新、插入潜支、刪除甸赃。

1、查找

要想操作DOM節(jié)點冗酿,首先需要找到要操作的節(jié)點埠对。

  • 通過id查找

    調(diào)用document.getElementById方法查找指定id的元素络断。

  • 通過標(biāo)簽名查找

    調(diào)用document.getElementByTagName方法查找指定標(biāo)簽名的所有元素。

  • 通過類名查找

    調(diào)用document.getElementByClassName方法查找指定class的所有元素项玛。

Tips:要精確地定位DOM貌笨,可以先定位父節(jié)點,再逐步縮小范圍襟沮。

2锥惋、更新

定位好節(jié)點之后,就可以進(jìn)行更新操作开伏。

  • 修改innerHTML屬性

    不但可以修改一個DOM節(jié)點的文本內(nèi)容膀跌,還可以通過HTML片段修改DOM節(jié)點內(nèi)部的子樹。

  • 修改innerText或textContent屬性

    可以對字符串進(jìn)行HTML編碼固灵,保證無法設(shè)置任何HTML標(biāo)簽捅伤。這兩個屬性的區(qū)別是前者不返回隱藏元素的文本,而后者則返回所有文本巫玻。

  • 修改style屬性

    可以用來設(shè)置CSS樣式丛忆。如果是無效的屬性名,可以在JavaScript中使用駝峰式命名屬性大审。

3蘸际、插入

可以插入新的節(jié)點,從而改變DOM結(jié)構(gòu)徒扶。

  • appendChild方法

    把一個子節(jié)點添加到父節(jié)點的最后一個子節(jié)點。如果子節(jié)點已經(jīng)存在根穷,會先從原來的位置刪除姜骡,然后再插入到新的位置。通常會新創(chuàng)建一個節(jié)點屿良,然后插入到指定位置圈澈,實現(xiàn)動態(tài)添加節(jié)點。

  • insertBefore方法

    父節(jié)點會將新建的子節(jié)點插入到參照節(jié)點之前尘惧。

4康栈、刪除

可以刪除節(jié)點,從而改變DOM結(jié)構(gòu)喷橙。

  • removeChild方法

    首先獲得要刪除的節(jié)點和它的父節(jié)點啥么,然后調(diào)用父節(jié)點的方法將其刪除。遍歷父節(jié)點的子節(jié)點并進(jìn)行刪除操作時贰逾,父節(jié)點的children屬性會在子節(jié)點發(fā)生變化時實時更新悬荣,需要特別注意。

六疙剑、異步處理

JavaScript語言是單線程的氯迂,一次只能完成一個任務(wù)践叠。好處是實現(xiàn)簡單,壞處是如果有任務(wù)耗時很長嚼蚀,其他的任務(wù)就必須得排隊等待禁灼,直到該任務(wù)完成。導(dǎo)致的結(jié)果就是造成瀏覽器無響應(yīng)轿曙,其他任務(wù)無法執(zhí)行弄捕,體驗極差。

因此拳芙,JavaScript語言分成兩種任務(wù)執(zhí)行模式:同步和異步察藐。所謂同步,就是指程序的執(zhí)行順序與任務(wù)的排列順序是一致的舟扎、同步的分飞。所謂異步,是指每個任務(wù)有一個或多個回調(diào)函數(shù)睹限,后一個任務(wù)無需等待前一個任務(wù)完成就可執(zhí)行譬猫,當(dāng)前一個任務(wù)完成后,執(zhí)行回調(diào)函數(shù)羡疗。這樣染服,程序的執(zhí)行順序與任務(wù)的排列順序是不一致的、異步的叨恨。

1柳刮、回調(diào)函數(shù)

這是異步處理最常用的的方法。

兩個同步執(zhí)行的函數(shù):

f1();
f2();

兩個異步執(zhí)行的函數(shù):

function f1(callback){
    setTimeout(function () {
        // f1的任務(wù)代碼
        callback();
    }, 1000);
}

f1(f2);

回調(diào)函數(shù)的優(yōu)點是簡單痒钝、容易理解秉颗。缺點是不利于閱讀和維護(hù)、高耦合送矩、流程混亂蚕甥,每個任務(wù)只能指定一個回調(diào)函數(shù)。

2栋荸、事件監(jiān)聽

采用事件驅(qū)動模式菇怀,由事件來決定要進(jìn)行的處理,而不是代碼的順序晌块。

為f1綁定一個事件爱沟,當(dāng)f1發(fā)生done事件,就執(zhí)行f2:

f1.on('done', f2);

執(zhí)行完成后摸袁,立即觸發(fā)done事件钥顽,從而開始執(zhí)行f2:

function f1(){
    setTimeout(function () {
        // f1的任務(wù)代碼
        f1.trigger('done');
    }, 1000);
}

事件監(jiān)聽的優(yōu)點是容易理解,可以綁定多個事件靠汁,每個事件可以指定多個回調(diào)函數(shù)蜂大,低耦合闽铐。缺點是流程不夠清晰。

3奶浦、發(fā)布/訂閱

與事件監(jiān)聽類似兄墅。某個任務(wù)執(zhí)行完成之后,會發(fā)布一個信號澳叉,其他任務(wù)可以訂閱這個信號隙咸,從而知道什么時候可以開始執(zhí)行。又稱為觀察者模式成洗。

訂閱信號:

jQuery.subscribe("done", f2);

發(fā)布信號:

function f1(){
    setTimeout(function () {
        // f1的任務(wù)代碼
        jQuery.publish("done");
    }, 1000);
}

取消訂閱:

jQuery.unsubscribe("done", f2);

可以了解存在多少信號五督、每個信號有多少訂閱者,從而監(jiān)聽程序的運行瓶殃。

4充包、Promises對象

該對象是CommonJS提出的一種規(guī)范,旨在為異步編程提供統(tǒng)一接口遥椿。

每一個異步任務(wù)返回一個Promises對象:

function f1(){
    var dfd = $.Deferred();
    setTimeout(function () {
        // f1的任務(wù)代碼
        dfd.resolve();
    }, 500);
    return dfd.promise;
}

該對象有一個then方法基矮,可以指定回調(diào)函數(shù):

f1().then(f2);  

優(yōu)點是回調(diào)函數(shù)可以使用鏈?zhǔn)綄懛ǎ鞒糖逦诔。⑶胰绻粋€任務(wù)已經(jīng)完成家浇,再添加回調(diào)函數(shù),該回調(diào)函數(shù)會立刻執(zhí)行碴裙。缺點是編寫和理解比較困難钢悲。


參考資料:

w3cschool

廖雪峰的JavaScript教程

阮一峰:Javascript異步編程的4種方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市舔株,隨后出現(xiàn)的幾起案子譬巫,更是在濱河造成了極大的恐慌,老刑警劉巖督笆,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異诱贿,居然都是意外死亡娃肿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進(jìn)店門珠十,熙熙樓的掌柜王于貴愁眉苦臉地迎上來料扰,“玉大人,你說我怎么就攤上這事焙蹭∩硅荆” “怎么了?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵孔厉,是天一觀的道長拯钻。 經(jīng)常有香客問我帖努,道長,這世上最難降的妖魔是什么粪般? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任拼余,我火速辦了婚禮,結(jié)果婚禮上亩歹,老公的妹妹穿的比我還像新娘匙监。我一直安慰自己,他們只是感情好小作,可當(dāng)我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布亭姥。 她就那樣靜靜地躺著,像睡著了一般顾稀。 火紅的嫁衣襯著肌膚如雪达罗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天础拨,我揣著相機與錄音氮块,去河邊找鬼。 笑死诡宗,一個胖子當(dāng)著我的面吹牛滔蝉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播塔沃,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼蝠引,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蛀柴?” 一聲冷哼從身側(cè)響起螃概,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎鸽疾,沒想到半個月后吊洼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡制肮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年冒窍,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豺鼻。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡综液,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出儒飒,到底是詐尸還是另有隱情谬莹,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站附帽,受9級特大地震影響埠戳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜士葫,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一乞而、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慢显,春花似錦爪模、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至应狱,卻和暖如春共郭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疾呻。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工除嘹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人岸蜗。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓尉咕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親璃岳。 傳聞我的和親對象是個殘疾皇子年缎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,876評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 轉(zhuǎn)載請聲明出處 博客原文 隨手翻閱以前的學(xué)習(xí)筆記,順便整理一下放在這里铃慷,方便自己復(fù)習(xí)单芜,也希望你有也有幫助吧 第一課...
    程序員poetry閱讀 12,676評論 13 94
  • 最近有個錘子用戶起訴羅永浩,王公子轉(zhuǎn)了一條犁柜,于是羅正面回應(yīng)了一下洲鸠,最后還祝王公子和他爹的各項生意發(fā)展順利,很多...
    玖光年閱讀 246評論 0 0
  • 我是3653甜趣陶心馋缅,純白色彩鉛小白一枚坛怪。今天開始彩鉛學(xué)習(xí)之路。 橙子學(xué)院彩鉛島島主推薦了初學(xué)者比較適合的彩鉛筆:...
    甜趣陶心閱讀 249評論 2 1
  • 我一直在反思股囊,我為什么總是過不好我想要的生活。 今天剛和先生吵架更啄。因為經(jīng)濟上的一些事稚疹。我覺得我們兩個過的很糟糕,很...
    一個暖暖閱讀 1,028評論 0 0
  • 陸羽在后世被尊稱為茶圣,在茶領(lǐng)域的造詣無需多說内狗;不過他的身世卻是悲慘的怪嫌,今天我們用輕松點的語言來看看他的一生。 上...
    Z小五閱讀 528評論 0 1