2021前端個人總結(jié)

Html5

語義化標簽

header
footer
nav
article
section

文檔類型定義

在h5中只需要寫DOCTYPE HTML昵仅,因為h5不基于SGML,所以不需要引用dtd怜校,但是需要使用DOCTYPE HTML來規(guī)范瀏覽器的行為征懈;
HTML4.01基于SGML所以需要對DTD進行引用,來告訴瀏覽器文檔所使用的文檔類型。

history

window.location.hash

hash

url中的hash指的是從#開始的一串字符笤受。
通過a標簽中的href屬性可以將hash值添加到url中。
<a href="#test"></a>
點擊鏈接敌蜂,url后面就會加上#test箩兽,同時window.history會增加一條瀏覽記錄。
window.history.hash可以訪問到該記錄章喉,可以通過onhashchange事件監(jiān)聽hash值的變化
http請求不包括#號后面的內(nèi)容,

Css

display屬性

  1. inline 行內(nèi)元素汗贫,默認不換行,不能設(shè)置寬高
  2. block 塊級元素秸脱,默認換行落包,能設(shè)置寬高
  3. inline-block 可以設(shè)置寬高,而且可以不換行顯示
  4. flex 彈性盒子

flex彈性盒子

原理:通過給父元素設(shè)置display:flex;來控制子元素的位置和排列方式摊唇。
基本概念:

  1. 容器:父元素咐蝇; 項目:所有子元素;
  2. 主軸巷查,交叉軸有序,默認沿主軸排列;

容器的屬性:
flex-direction/flex-wrap/flex-flow/justify-content/align-items/align-content

  1. flex-direction 主軸的方向 row/row-reverse/column/column-reverse
  2. flex-wrap 項目換行方式 wrap/no-wrap/wrap-reverse
  3. flex-flow 前兩個值的簡寫
  4. justify-content 定義項目在主軸的對齊方式
  5. align-items 定義項目在交叉軸的對齊方式
  6. align-content 定義多根軸線的對齊方式岛请,一根軸線的時候不起作用

項目的屬性:
order/flex-grow/flex-shrink/flex-basis/flex/align-self

偽元素

附加至選擇器末尾的關(guān)鍵詞旭寿,允許你對被選擇元素的特定部分修改樣式
按照規(guī)定應(yīng)該使用雙冒號,但由于舊版的W3C規(guī)范并未對此進行區(qū)分髓需,所以兩者都可
window.getComputedStyle可以獲取偽元素的content信息
:after/before
:first-line/first-letter
:placeholder
:marker
:cue

偽類

添加到選擇器的關(guān)鍵字许师,制定要選擇的元素的特殊狀態(tài)
可以添加多個偽類
使用單冒號
:link
:visited
:hover
:active
:focus()
:checked
:disabled
:first-child/last-child
:first/last
:first-of-type/last-of-type
:not()
:nth-child()

@media 媒體查詢

在響應(yīng)式設(shè)計的時候很有用,對不同尺寸的或類型的設(shè)備顯示不同的樣式
格式:
@media mediaType and|not|only (media feature) { css code; }

或者
<link media="mediaType and|not|only (media feature)" stylesheet="css1.css">

@support

用于檢測瀏覽器是否支持某個屬性(即瀏覽器對某個css屬性是否兼容)僚匆,如果支持就使用某套方案微渠,可以在頂層用,也可嵌套使用

calc()

css中的計算函數(shù)咧擂,可以計算任意值逞盆,格式:width:calc(100% - 100px)
支持 + - * / ;運算符前后都要有空格松申,符合數(shù)學(xué)中的四則運算云芦;

css中的居中方法

1.水平居中

行內(nèi)元素:text-align:center;
塊狀元素:margin:0 auto;

2.垂直居中

line-height:height;

3.水平垂直居中

一:
position:absolute; top:50%; left:50%; transform: translate(-50%,-50%);
二:
display: flex; align-items: center; justify-content:center;

rem,em,px,vw/vh的區(qū)別

rem:長度是根據(jù)根元素的font-size來的,一般設(shè)html;
em:長度根據(jù)父元素的font-size,字體也是根據(jù)font-size;
vw/vh:即viewport width/height,視窗的寬度和高度,1vh即1%視口高度;
百分比:最近的父元素的寬高度;

移動端的適配

基本概念

  1. 屏幕尺寸:屏幕對角線的長度贸桶,單位是英寸舅逸,1英寸=2.54cm;
  2. 屏幕分辨率:屏幕橫縱方向上的像素點數(shù),單位是px,1px=1個像素點皇筛,一般表示為:縱向乘橫向琉历,例如:1960*1080
  3. 物理像素/設(shè)備像素(dp):屏幕能顯示的最小粒度,設(shè)備/物理像素固定
  4. css像素(dip):與設(shè)備無關(guān)的像素水醋,在標準顯示密度下(普通屏)旗笔,一個css像素對應(yīng)一個設(shè)備像素。蘋果的視網(wǎng)膜屏幕(Retina)的分辨率是普通屏的兩倍拄踪,一個css像素就對應(yīng)兩個設(shè)備像素蝇恶。如果用戶進行縮放,則一個css像素對應(yīng)的設(shè)備像素值也會隨之變化惶桐。

css像素與物理像素的關(guān)系依賴于scale

對于web開發(fā)者而言撮弧,我們使用的每個css 和JavaScript定義的像素本質(zhì)上都是css像素,在開發(fā)過程中我們并不關(guān)心一個css像素跨越了多少個設(shè)備像素姚糊,我們將這個依賴于屏幕特性和用戶縮放程度的復(fù)雜計算交給了瀏覽器想虎。

  1. 像素比(dpr):物理像素/獨立像素(css像素),retina屏的dpr為2叛拷,即2個物理像素對應(yīng)一個css像素舌厨,3倍屏的dpr為3。viewport中的scale和dpr是倒數(shù)關(guān)系忿薇。js中獲取dpr: window.devicePixelRatio裙椭,部分瀏覽器不支持
  2. 布局視口:layout viewport = document.documentElement.clientWidth,比實際視口要寬
  3. 真實視口:visual viewport = window.innerWidth;部分機型不能正常獲取
  4. 理想視口:ideal viewport署浩,沒有固定的尺寸揉燃,最適合移動端,不同的設(shè)備擁有不同的理想視口筋栋,它的意義在于炊汤,無論分辨率為多少,都可以完美的呈現(xiàn)給用戶。所有的iphone的理想視口都是640px*320px

適配方案:

  1. 設(shè)置meta標簽
    <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
  2. 使用rem抢腐,根據(jù)設(shè)備寬度動態(tài)設(shè)置根元素的font-size
  3. 設(shè)置viewport的scale為1/dpr姑曙,可以畫出1px的線條
  4. 使用vm/vh

關(guān)于移動端適配,參照https://www.jb51.net/article/149140.htm, http://www.reibang.com/p/b13d811a6a76

rem

基準設(shè)備寬度baseWidth(iphone678):375
基準根元素baseFontSize: 16px
baseWidth/baseFontSize = width/font-size
獲取當前設(shè)備的設(shè)備寬度迈倍,根據(jù)以上基準值伤靠,算出根元素的font-size

0.5px的線

transform:scale(0.5);

盒模型

分為IE盒模型和w3c盒模型
box-sizing:content-box; // 默認值,w3c盒模型
box-sizing:border-box; // IE盒模型
IE盒模型:width=border+padding+content;
w3c盒模型:width=content;

清除浮動

clear:both;
::after 偽元素啼染;
overflow:hidden;
父級元素設(shè)置高度宴合;

BFC(Block Formatting Context)

塊級格式化上下文,獨立的渲染區(qū)域迹鹅,與其他部分互不干擾;
觸發(fā)條件:
根元素
position:absolute/fixed;
display:inline-block/table;
float元素;
overflow!==visible;
規(guī)則:
屬于同一個BFC的兩個相鄰盒子垂直排列卦洽,并且margin會重疊;
不會與float的元素區(qū)域重疊斜棚;
計算其高度時float元素也會參與計算阀蒂;
文字層不會被浮動層覆蓋,會環(huán)繞周圍打肝;

Javascript

JavaScript組成部分

dom+bom+ECMAScript(核心)

深拷貝和淺拷貝

http://www.reibang.com/p/1c142ec2ca45
淺拷貝:for-in,Object.assign(),直接賦值
深拷貝:
遞歸脂新,
SON.Stringify()和JSON.parse(),
jQuery的extend()粗梭,
lodash庫的cloneDeep()争便,
用slice(),concat()實現(xiàn)數(shù)組的深拷貝断医,
擴展運算符滞乙,
Object.create()

本地存儲

localStorage:5M,用戶手動清理,所有同源窗口共享鉴嗤,僅存儲在瀏覽器斩启,用于長期登陸
sessionStorage:5M,瀏覽器標簽頁關(guān)閉,儲存結(jié)束醉锅,同一個瀏覽器窗口共享兔簇,僅存儲在瀏覽器,用于敏感登陸
cookie:容量不超過4k,請求中會帶上,設(shè)置過期時間硬耍,同源窗口共享垄琐,用于記錄是否登陸過,以便實現(xiàn)下次自動登陸

ECMAScript

定義了語法经柴、類型狸窘、語句、關(guān)鍵字坯认、保留字翻擒、操作符氓涣、對象
類型運算符:typeof instanceof

js中的引用類型

Object Array Date Function RegExp 基本包裝類型(String Number Boolean) 單體內(nèi)置對象(Global Math)

Object

創(chuàng)建方式: 對象字面量(不會調(diào)用構(gòu)造函數(shù)),構(gòu)造函數(shù)陋气。
所有Object的實例都有的方法和屬性(不包括宿主對象):

constructor:構(gòu)造函數(shù)

hasOwnProperty(propertyName):檢測傳入的屬性名是否是該對象的實例屬性

isPrototypeOf(object):檢測該對象是否是傳入對象的原型

propertyIsEnumerable(propertyName): 檢查屬性是否可以枚舉(使用for-in遍歷)

valueOf():獲取該對象的字符串值

toString():同valueOf

toLocaleString():根據(jù)地區(qū)不同返回該對象的字符串值劳吠。

Array

  1. 數(shù)組長度可動態(tài)調(diào)整;
  2. 數(shù)組的每一項都可以是任意數(shù)值恩伺;

創(chuàng)建方式:

  1. 使用構(gòu)造函數(shù)
    var arr1 = new Array(3)
    var arr1 = Array(3)
    var arr1 = new Array('123')
  2. 使用數(shù)組字面量(不會調(diào)用構(gòu)造函數(shù))
    var arr1 = ['1', 's', 'tr']

length屬性:可讀可寫

檢測數(shù)組
Array.isArray() // 推薦使用
arr instanceof Array // 當有多個全局執(zhí)行環(huán)境時會有問題

轉(zhuǎn)換方法

valueOf():隱式調(diào)用toString()方法赴背,返回值同toString()

toString():返回數(shù)組中每個值的字符串形式拼接而成的以逗號分割的字符串

toLocaleString():調(diào)用每一項的toLocaleString()方法椰拒,返回逗號拼接的字符串

join():使用不同的分割符來拼接字符串

棧方法
特點:后進先出(Last-In-First-Out)

push(): 接收推入的值晶渠,返回數(shù)組長度
pop():移除末尾項,返回移除的項

隊列方法
特點:先進先出(First-In-First-Out)

push(): 接收推入的值燃观,返回數(shù)組長度
shift():移除起始項褒脯,返回移除的項

或者

pop(): 移除末尾項,返回移除的項
unshift():在數(shù)組起始端添加缆毁,返回數(shù)組長度

重排序方法

reverse():倒序
sort():默認升序番川,會調(diào)用toString()方法比較字符串而不是數(shù)值,可傳入一個比較函數(shù)脊框,返回排序后的數(shù)組

操作方法

concat():拼接

slice(startIndex[,endIndex]):分割數(shù)組颁督,返回分割好的數(shù)組戈盈,不會影響原數(shù)組竣蹦,當參數(shù)為負數(shù)時,會與length相加屿储,當endIndex小于startIndex,返回空數(shù)組

splice(index, 刪除的個數(shù), 替換的值):可以刪除昭灵、插入吠裆、替換 ,返回值為被刪除的數(shù)組成的數(shù)組,如果沒有則返回[]

位置方法

indexOf(val[,startIndex]):查找val在數(shù)組的索引值烂完,如果沒有返回-1
lastIndexOf():從數(shù)組尾部開始查

迭代方法
接收兩個參數(shù)试疙,第一個是回調(diào)函數(shù),第二個是作用域?qū)ο罂衮迹诙€可選祝旷。
回調(diào)函數(shù)有三個參數(shù):function(item, index, arr)
迭代方法不會影響原數(shù)組

forEach(): 沒有返回值

map():返回回調(diào)函數(shù)調(diào)用的結(jié)果組成的數(shù)組

some():回調(diào)函數(shù)中有一項返回true,結(jié)果就為true

every():回調(diào)函數(shù)中每項返回true,結(jié)果才為true

filter():返回回調(diào)函數(shù)返回true的項組成的數(shù)組

歸并方法
迭代數(shù)組每一項,構(gòu)建一個最終數(shù)組
接收兩個參數(shù)嘶窄,第一個是回調(diào)函數(shù)怀跛,第二個是初始值,第二個可選护侮。
回調(diào)函數(shù)有四個參數(shù):function(before, now, index, arr)

reduce(): 沒有返回值
reduceRight(): 沒有返回值

數(shù)組去重
https://segmentfault.com/a/1190000016418021

  1. es6 Set,無法去掉空對象
  2. indexOf敌完,includes,新建一個空的結(jié)果數(shù)組羊初,for 循環(huán)原數(shù)組滨溉,判斷結(jié)果數(shù)組是否存在當前元素什湘,如果有相同的值則跳過,不相同則push進數(shù)組晦攒。
  3. sort,先排序闽撤,再對比相鄰元素
  4. Map,利用map的key不能重復(fù)的特性去重
  5. reduce+includes

Date

使用自UTC(Coordinated Universal Time,國際協(xié)調(diào)時間)1970年1月1日零時開始經(jīng)過的毫秒數(shù)來保存日期脯颜。
創(chuàng)建方式:new Date()
參數(shù):

  1. 不傳參哟旗,獲得當前時間和日期
  2. 傳毫秒數(shù):獲得指定時間和日期
  3. 傳代表日期的字符串:調(diào)用Date.Parse(),返回日期

將指定時間和日期轉(zhuǎn)化為毫秒數(shù):Date.Parse()和Date.UTC()

Date.Parse(): 接收一個表示日期的字符串參數(shù)栋操,嘗試返回對應(yīng)的毫秒數(shù)闸餐,結(jié)果因地區(qū)而異,如果該字符串不能表示日期則會返回NaN矾芙。

Date.UTC(): 作用同上舍沙,區(qū)別在于:參數(shù)(年份,月份(0-11)剔宪,日期(1-31)拂铡,小時(0-23),分鐘葱绒,秒感帅,毫秒)只有前兩個是必須的

獲取當前時間:Date.now(),返回毫秒數(shù)

繼承的方法:toString(),toLocaleString(),valueOf()

toString():返回帶有時區(qū)信息的日期和時間
toLocaleString(): 根據(jù)瀏覽器設(shè)置的地區(qū)相適應(yīng)的格式返回日期和時間
valueOf():返回日期的毫秒表示,多用于比較日期地淀。

日期格式化方法:

toDateString():以特定于實現(xiàn)的格式顯示星期幾失球、月、日和年
toLocaleDateString():以特定于實現(xiàn)的格式顯示星期幾骚秦、月她倘、日和年

toTimeString():以特定于實現(xiàn)的格式顯示時分秒和時區(qū)
toLocaleTimeString(): 以特定于實現(xiàn)的格式顯示時分秒

toUTCString():以特定于實現(xiàn)的格式顯示完整的UTC日期

日期時間組件方法

getTime()
setTime(毫秒)

getFullYear()
setFullYear()
getUTCFullYear()
setUTCFullYear()

getMonth()
setMonth()
getUTCMonth()
setUTCMonth()

getDate()
setDate()
getUTCDate()
setUTCDate()

getDay()
getUTCDay()

getHours()
setHours()
getUTCHours()
setUTCHours()

getMinutes()
setMinutes()
getUTCMinutes()
setUTCMinutes()

getMinutes()
setMinutes()
getUTCMinutes()
setUTCMinutes()

js中的面向?qū)ο?/h2>

理解對象

簡單來說,對象是鍵值對的集合作箍。
屬性類型:數(shù)據(jù)屬性硬梁,訪問器屬性。

  1. 數(shù)據(jù)屬性:Configurable,Enumerable,Writable,Value
    configurable:是否能通過delete刪除該屬性胞得,對象上定義的屬性默認為true.
    enumerable:是否可通過for-in枚舉,對象上定義的屬性默認為true.
    writable:是否可修改荧止,對象上定義的屬性默認為true。
    value:這個屬性的值阶剑,默認undefined跃巡。
    修改屬性默認的特性:Object.defineProperty(對象,屬性,描述符對象)

    Object.defineProperty(person, 'name', {
      writable: false,
      value: 'Li'
    })
    

    注意:將configurable配置為false之后,不能delete它牧愁,也不能修改 它素邪,并且不能將它在改為true了。在調(diào)用object.defineProperty()方法猪半,如果不指定configurable兔朦、writable偷线、enumerable的值,默認為false沽甥。

  2. 訪問器屬性:getter,setter(非必須)
    configurable: 同數(shù)據(jù)屬性声邦。
    enumerable: 同數(shù)據(jù)屬性。
    get:在讀取訪問器屬性的時候會調(diào)用這個函數(shù)摆舟。
    set:在寫入訪問器屬性的時候會調(diào)用這個函數(shù)亥曹。

        var book = {
          _year:2004,
          edition: 1
        }
        Object.defineProperty(book, "year", {
          get: function() {
            return this._year
          },
          set: function(val) {
            if (val > 2004) {
              this._year = val;
              this.edition += val - 2004
            }
          }
        })
    

    注:_year前面的下劃線是一種常用的記號,表示只能通過對象方法訪問的屬性

    Object.defineProperties(book, 對應(yīng)屬性的描述符對象)
    Object.getOwnPropertyDescriptor(book, "_year")恨诱,該方法只能用于實例屬性

創(chuàng)建對象

創(chuàng)建單個對象: 對象字面量/構(gòu)造函數(shù)
創(chuàng)建多個對象

  1. 工廠模式

    function createPerson(name, age) {
      var o = new Object();
      o.name = name;
      o.age = age;
      o.sayName = function() {
        alert(this.name)
      }
      return o
    }
    var person1 = createPerson('Li', 23);
    var person2 = createPerson('Di', 13);
    

    優(yōu)點:可以快速的創(chuàng)建多個相似的對象媳瞪;
    缺點:無法知道一個對象的類型(對象識別)。

  2. 自定義構(gòu)造函數(shù)

    function Person(name, age) {
      this.name = name;
      this.age = age;
      this.sayName = function() {
        alert(this.name)
      }
    }
    var person1 = new Person('Li', 23);
    var person2 = new Person('Di', 13);
    

    new操作符
    a. 創(chuàng)建一個新對象胡野;
    b. 設(shè)置原型鏈(將新對象的__proto__指向函數(shù)的prototype) 材失;
    c. 將構(gòu)造函數(shù)的作用域賦給新對象(綁定this)痕鳍;
    d. 執(zhí)行構(gòu)造函數(shù)的代碼(為新對象添加屬性)硫豆;
    e. 返回新對象。

    可以用instanceof檢測person1和person2的類型
    person1 instanceof Person => true
    person1 instanceof Object => true

    優(yōu)點:對象類型識別
    缺點:每個對象都有單獨的sayName函數(shù)實例笼呆,這個不必要熊响。

  3. 原型模式

    function Person() {
    }
    Person.prototype.name = 'Li';
    Person.prototype.age = 31;
    Person.prototype.sayName = function() {
      alert(this.name)
    }
    
    var person1 = new Person();
    var person2 = new Person();
    
    

    person1和person2共享所有的屬性和方法。

    關(guān)于prototype和__proto
    Person.prototype.constructor 指向 Person
    person1.__proto__ 指向 Person.prototype
    Person.prototype.isPrototypeOf(person1) 指向 true
    Object.getPrototypeOf(person1) == Person.prototype
    Object.getPrototypeOf(person1).name 值為:"Li"

    讀取對象的某個屬性的時候诗赌,先在對象實例本身讀取汗茄,如果沒有找到,則去原型對象上去找铭若,如果還沒有找到洪碳,則沿著原型鏈繼續(xù)往上找。
    可以通過person1.hasOwnProperty("age")來檢測該屬性是否是實例上的屬性叼屠。
    操作符in: `alert("name" in person1) 不管是實例屬性還是原型上的屬性都返回true.
    in配合hasOwnProperty()可以檢測屬性是否是原型屬性:

    function hasProtoProperty(object, name) {
      return !object.hasOwnProperty(name) && (name in object)
    }
    

    for-in:返回所有可枚舉的屬性(enumerable為true),包括實例上的以及原型對象上的瞳腌。屬性沒有順序。如果屬性值為undefined或是null會拋出錯誤或不執(zhí)行镜雨,所以建議先判斷嫂侍。

    Object.keys(person1)獲取對象上所有可枚舉的實例屬性。返回數(shù)組荚坞。
    Object.getOwnPropertyNames(person1)獲取對象上的所有實例屬性挑宠,不論是否可以枚舉。返回數(shù)組颓影。

    調(diào)用構(gòu)造函數(shù)會為實例添加一個指向最初原型(prototype)的指針(__proto__)各淀,如果在調(diào)用構(gòu)造函數(shù)之后重新定義prototype,則會切斷這個指針,即person.proto不再指向Person.prototype了诡挂。

    可以在原生對象(String/Number/Array/……)的原型上添加方法碎浇,但是不推薦疗我。

    缺點:所有實例共享屬性和方法,屬性值不夠靈活(當屬性值為引用值的時候)

  4. 組合使用自定義構(gòu)造函數(shù)和原型模式
    通過自定義構(gòu)造函數(shù)定義實例屬性南捂,原型模式定義共享的屬性和方法

    function Person(name, age) {
      this.name = name;
      this.age = age;
    }
    Person.prototype.sayName = function() {
      alert(this.name)
    }
    
    var person1 = new Person("Li", 12);
    var person2 = new Person("Di", 24);
    
  5. 動態(tài)原型模式

    function Person(name, age) {
     this.name = name;
     this.age = age;
     // 一下這段代碼只在初次調(diào)用構(gòu)造函數(shù)的時候執(zhí)行
     if(typeof this.sayName != "function") {
       Person.prototype.sayName = function() {
         alert(this.name)
       }
     }
    }
    
    var person1 = new Person("Li", 12);
    var person2 = new Person("Di", 24);
    
  6. 寄生構(gòu)造函數(shù)模式
    類似工廠模式,建議在特殊情況下使用吴裤。

  function Person(name, age) {
    var o = new Object();
    o.name = name;
    o.age = age;
    o.sayName = function() {
      alert(this.name)
    }
    return o
  }

  var person1 = new Person("Li", 12);
  var person2 = new Person("Di", 24);
  1. 穩(wěn)妥構(gòu)造函數(shù)模式
    穩(wěn)妥對象:沒有公共屬性,方法也不引用this對象溺健。在安全的環(huán)境中使用麦牺。

    function Person(name, age){
      var o = new Object();
      o.sayName = function() {
        alert(name)
      }
      return o
    }
    

js繼承

  1. 原型鏈繼承

    function Person(name, age) {// 父
      this.name = name;
      this.age = age;
    }
    function Student() { // 子
    
    }
    Student.prototype = new Person();
    

    每個構(gòu)造函數(shù)(Person)都有原型對象(prototype),指向Object的實例上的proto屬性鞭缭,Object.Prototype為null
    子類構(gòu)造函數(shù)的prototype指向父類的實例剖膳,而父類構(gòu)造函數(shù)的prototype指向Object的實例,通過這種關(guān)系岭辣,形成了原型鏈吱晒。
    確定原型和實例之間的關(guān)系
    a. instanceof操作符
    b. isPrototypeOf()
    Object.prototype.isPrototypeOf(instance) true
    缺點:父子之間共享引用類型的值,不能給父類構(gòu)造函數(shù)傳遞參數(shù)沦童。

  2. 借用構(gòu)造函數(shù)
    在子類的構(gòu)造函數(shù)中調(diào)用父類的構(gòu)造函數(shù)仑濒,可以避免原型鏈繼承方式中的引用類型值共享的問題,以及不方便向父類構(gòu)造函數(shù)中傳遞參數(shù)的問題(因為可能會影響父類的實例)
    通過call或者apply實現(xiàn)

    function Person(name, age) {// 父
      this.name = name;
      this.age = age;
    }
    function Student(name, age, score) { // 子
      Person.call(this, name, age)
      this.score = score
    }
    

    缺點:在構(gòu)造函數(shù)中定義方法不能實現(xiàn)方法復(fù)用

  3. 組合繼承
    原型鏈繼承(繼承原型上的屬性和方法)+借用構(gòu)造函數(shù)(繼承實例上的屬性)

    function Person(name, age) {// 父
      this.name = name;
      this.age = age;
    }
    function Student(name, age, score) { // 子
      Person.call(this, name, age)
      this.score = score
    }
    Student.prototype = new Person();
    Student.prototype.constructor = Student;
    Student.prototype.sayScore = function() {
      alert(this.score)
    }
    

    缺點:會調(diào)用兩次父類的構(gòu)造函數(shù)

  4. 原型式繼承
    由道格拉斯.克羅克福德提出偷遗,基本思想:借助原型可以基于已有的對象創(chuàng)建新對象墩瞳,同時也不用創(chuàng)建自定義類型。

    function object(o) {
      function F() {}
      F.prototype = o;
      return F()
    }  
    

    ECMAScript5新增Object.create()規(guī)范了原型式繼承氏豌,Object.create(proto[,propertiesObject])喉酌,使用現(xiàn)有的對象來提供新創(chuàng)建的對象的proto(來自MDN),返回繼承了proto的對象泵喘。第二個參數(shù)與Object.defineProperties()的第二個參數(shù)相同泪电。

    缺點:同原型鏈繼承一樣,引用類型的值會共享

  5. 寄生式繼承
    同樣由道格拉斯.克羅克福德提出纪铺,思路與原型式繼承緊密相關(guān):創(chuàng)建一個僅用于封裝繼承過程的函數(shù)相速,該函數(shù)在內(nèi)部以某種方式來增強對象,最后返回對象霹陡。

    function createAnother(original) {
      // 也可以用其他方法來創(chuàng)建clone,比如Object.create()
      var clone = object(original);
      clone.sayName = function() {
        alert('hi')
      }
      return clone
    }
    

    缺點:不能函數(shù)復(fù)用和蚪,與借用構(gòu)造函數(shù)類似

  6. 寄生組合式繼承(理想的調(diào)用方式)
    通過借用構(gòu)造函數(shù)來繼承屬性,通過原型鏈的混成形式來繼承方法烹棉。
    不用調(diào)用兩次父類的構(gòu)造函數(shù)

function inheritPrototype(subType, superType) {
  var prototype = Object(superType.prototype); // 創(chuàng)建對象
  prototype.constructor = subType;  // 增強對象
  subType.prototype = prototype; // 指定對象
}

function Person() {}
function Student() {
  Person.call(this)
}
inheritPrototype(Student, Person);

call()方法
apply()方法
Object.assign()
// todo

js淺拷貝及深拷貝
// todo

dom(文檔對象模型)

script標簽

async:
defer:
src:
type: 編寫代碼使用的腳本語言的內(nèi)容類型(MIME類型)攒霹,默認text/javascript

基本數(shù)據(jù)類型
string boolean null undefined number object(引用類型) symbol(es6)

原生js操作DOM

document.getElementById()
document.getElementsByTagName() 偽數(shù)組
document.getElementsByClassName()
document.querySelector()
document.querySelectorAll()

window.onload()

ele.style.width = '234px';
ele.innerHtml = '內(nèi)容';
ele.innerText

ele.className 獲取標簽的屬性名
ele.value 獲取表單元素的value值
ele.disabled
ele.checked
ele.selected

document.getComputedStyle() ie低版本不支持
ele.currentStyle()

onfocus()
onclick()
onblur()
onkeyup()
ondblclick()

nodeType:節(jié)點類型

  1. 元素節(jié)點
  2. 屬性節(jié)點
  3. 文本節(jié)點

nodeName:節(jié)點名
nodeValue: 節(jié)點值

  1. 元素節(jié)點:null
  2. 文本節(jié)點:文本值
  3. 屬性節(jié)點:屬性值

節(jié)點屬性
ele.parentNode
ele.childNodes 包含文本節(jié)點,空節(jié)點
ele.children
ele.firstChild/lastChild
ele.previousSibling/nextSibling

節(jié)點方法
parentEle.appendChild()
parentEle.insertBefore()
ele.cloneNode()
parentEle.replaceChild()

創(chuàng)建節(jié)點
document.createElement()
ele.innerHtml()
document.write()

刪除節(jié)點
parentEle.removeChild()

屬性
ele.getAttribute()
ele.setAttribute()
ele.removeAttribute()

Math.random()

bom(瀏覽器對象模型)

瀏覽器渲染頁面的大致過程

  1. 渲染引擎啟動html解釋器(htmlParser)解析html源碼浆洗,根據(jù)DOM API創(chuàng)建dom tree催束,Browser進程并行下載網(wǎng)絡(luò)資源(css/image/js...)。
    在dom樹中伏社,每個html標簽都有一個對應(yīng)的節(jié)點抠刺,每個文本也有對應(yīng)的文本節(jié)點塔淤,根節(jié)點就是documentElement,對應(yīng)的是html節(jié)點。當遇到script節(jié)點時速妖,將啟動js引擎解析腳本高蜂,此時會阻塞DOM樹的構(gòu)建。
    當DOM樹構(gòu)建完成時罕容,DOMContentLoaded事件會被觸發(fā)备恤。
    當DOM樹構(gòu)建完成,并且頁面依賴的資源(圖片锦秒、視頻等) 都下載完了露泊,onload事件會被觸發(fā)。

  2. 渲染引擎啟動css解釋器(cssParser,cssGrammer)處理css源碼旅择,計算出最終樣式惭笑,根據(jù)CSSOM API(css對象模型)構(gòu)建cssRuleTree(css規(guī)則樹),忽略其中的非法語法生真。

  3. 渲染引擎將domTree和cssRuleTree 合成rendering tree(渲染樹)沉噩,計算各個節(jié)點在頁面上的布局或排版,忽略head汇歹、display:none的元素屁擅,每行都是獨立的文本節(jié)點,每個節(jié)點都有對應(yīng)的css产弹。

  4. 當渲染樹創(chuàng)建后,瀏覽器就會繪制(paint)頁面到屏幕上弯囊。

這個過程并不是一次完成痰哨,實際上css和js會多次修改dom或者cssom。

重排/回流以及重繪

重排(reflow):元素的寬高引起布局的改變匾嘱,就需要重排斤斧,重排后一定會重繪;
重繪(repaint):元素的顏色霎烙、透明度撬讽、字體樣式變化會重繪,重繪不一定引起重排悬垃;

引起重排:

  1. 添加刪除可見的dom元素游昼;
  2. 元素位置、大小的變化尝蠕;
  3. 內(nèi)容改變烘豌;
  4. 頁面渲染器初始化;
  5. 瀏覽器窗口大小改變看彼;

避免重排和重繪:

  1. 使用類名來切換樣式廊佩;
  2. 多個樣式寫在一起囚聚;
  3. 批量修改樣式(先將需要改變的部分隱藏起來(display:none),修改后再展示)
  4. 緩存布局信息(offsetLeft,clientTop)标锄;當需要多次獲取這些信息時顽铸,將其保存在一個臨時變量中,通過訪問變量得到這些值料皇。
  5. 使用visible:hidden;代替display:none;

閉包

調(diào)用外部函數(shù)內(nèi)(外部作用域)的變量跋破。
缺點是常駐內(nèi)存會增大內(nèi)存使用量,并且使用不當容易造成內(nèi)存泄漏
好處是減少全局變量的使用瓶蝴,使用閉包模塊化代碼
立即調(diào)用函數(shù)有毒返,匿名函數(shù)

js跨域

解決方案:

  1. JSONP(動態(tài)創(chuàng)建scripts標簽加載其他域的js文件,在當前頁面調(diào)用加載后的文件。具體操作:向其他域傳入一個callback的參數(shù)舷手,其他域的后臺將callback參數(shù)值和json串包裝成js函數(shù)返回至當前域拧簸,將其解析成為可執(zhí)行的js文件,從而實現(xiàn)域與域之間的通信)
  2. iframe
    通過document.domain實現(xiàn)(前提是屬于同一個頂級基礎(chǔ)域和同一個協(xié)議)
  3. 后臺代理
    通過后臺轉(zhuǎn)發(fā)http請求男窟,Nginx反向代理盆赤,
  4. 后端設(shè)置響應(yīng)頭
  5. h5的postMessage,使用Window.onmessage來獲取
  6. window.name
  7. CORS:是一種新標準歉眷,支持同源通信也支持跨域通信牺六。fetch是實現(xiàn)cors通信的。
  8. websocket

ajax原理

Asynchronous Javascript And XML汗捡;異步的js和xml;
創(chuàng)建XmlHttpRequest對象(瀏覽器自帶)淑际,簡稱xhr;
優(yōu)點:局部刷新,提高用戶體驗
缺點:不利于seo優(yōu)化

var xhr = null;  
// 兼容性檢查  
if(window.XmlHttpRequest) {
  xhr = new XmlHttpRequest();
}else{
  xhr = new ActiveXObject('Microsoft XmlHttp');
}
// get請求
xhr.open('GET',url?data,true); // 異步  
xhr.send();  
// POST請求
xhr.open('POST',url,true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send(data);
// 接收響應(yīng)
xhr.onreadystatechange = function() {
  if(xhr.readyStatus === 4) {
    if (xhr.status === 200) {
      // 獲取響應(yīng)結(jié)果 xhr.responseText
    }
  }
}

瀏覽器的進程(process)與線程(thread)

進程:CPU資源分配的最小單位
線程:程序執(zhí)行的最小單位
進程與線程的關(guān)系:一個進程有多個線程共同協(xié)作完成任務(wù)扇住,同一個進程下的線程共享程序的內(nèi)存空間(代碼段春缕,數(shù)據(jù)集,堆等)艘蹋。

瀏覽器內(nèi)的進程

  1. 有多個進程锄贼,當瀏覽器每打開一個標簽頁就相當于創(chuàng)立了一個獨立的瀏覽器進程(不絕對,瀏覽器會將多個空白標簽頁合成一個進程)
  2. 輔助進程: 輔助標簽頁進程的其他進程
    a. Browser進程:瀏覽器的主進程女阀,負責(zé)協(xié)調(diào)主控宅荤,只有一個。作用有:負責(zé)瀏覽器界面顯示浸策,與用戶交互(前進后退等)冯键;負責(zé)各個頁面的管理,創(chuàng)建和銷毀其他進程的榛;網(wǎng)絡(luò)資源的管理琼了,下載等。
    b. 第三方插件進程:每種類型的插件對應(yīng)一種進程,僅當使用該插件的時候創(chuàng)建雕薪。
    c. GPU進程:最多一個昧诱,用于3D繪制等。
    d. 瀏覽器渲染進程(瀏覽器內(nèi)核)所袁,Renderer進程盏档,內(nèi)部是多線程的,即每個標簽頁所擁有的進程燥爷,互不影響蜈亩,負責(zé)渲染頁面,腳本執(zhí)行前翎,事件處理等稚配。

瀏覽器內(nèi)核(渲染進程,Renderer進程港华,渲染引擎)的常駐線程

  1. GUI(Graphical User Interface/圖形用戶界面)渲染線程
    a. 負責(zé)渲染瀏覽器界面道川,包括解析html,css立宜,構(gòu)建Dom樹冒萄,Render樹,布局與繪制等橙数。
    b. 重繪(repaint)或者重排/回流(reflow)尊流,執(zhí)行該線程
  2. JS引擎線程(js內(nèi)核),例如V8引擎灯帮,負責(zé)處理js腳本崖技,等待任務(wù)隊列的到來,然后加以處理施流,瀏覽器不論什么時候都只有一個js引擎在運行js程序响疚。
  3. 事件觸發(fā)線程,控制事件循環(huán)瞪醋,鼠標點擊,滾動頁面等等装诡,會將對應(yīng)任務(wù)添加到事件觸發(fā)線程中银受,當對應(yīng)的事件被觸發(fā)時,該線程負責(zé)將其添加到待處理事件隊列的末尾鸦采,等待js引擎空閑時處理宾巍。
  4. 定時觸發(fā)線程,setTimeOut和setInterval所在的線程渔伯。由于定時器計時并不是由js引擎計時的(因為js引擎是單線程的顶霞,如果該線程堵塞了,會影響計時的準確性),當計時完被觸發(fā)选浑,事件會被添加到待處理事件隊列的末尾等待js引擎空閑時處理蓝厌。
  5. 異步HTTP請求線程,在XmlHttpRequest連接后啟動一個新的線程古徒,如果線程檢測到請求的狀態(tài)變更拓提,如果設(shè)置有回調(diào)函數(shù),該線程會把回調(diào)函數(shù)添加到事件隊列中等js引擎空閑時處理隧膘。
  6. EventLoop輪詢處理線程代态,負責(zé)在異步代碼執(zhí)行成功后,取相應(yīng)的回調(diào)函數(shù)疹吃。

瀏覽器內(nèi)核中線程之間的關(guān)系

  1. GUI渲染線程與js引擎互斥蹦疑。
    理由:如果js引擎正在修改某個dom解構(gòu),GUI渲染線程又正在渲染頁面萨驶,那么會導(dǎo)致兩者處理的結(jié)果不一致歉摧。也可以由此推出,當js引擎正在進行復(fù)雜計算時篡撵,js引擎將會阻塞判莉,頁面長時間得不到渲染,就會很卡頓育谬。
  2. js引擎與事件觸發(fā)線程券盅、定時觸發(fā)線程,異步HTTP請求線程膛檀。
    在瀏覽器內(nèi)核中有個事件隊列锰镀。事件觸發(fā)線程、定時觸發(fā)線程咖刃、異步HTTP請求線程 這三個線程的回調(diào)函數(shù)會被放入事件隊列中泳炉,當滿足觸發(fā)條件時,并且js引擎空閑時嚎杨,就會去執(zhí)行事件隊列中事件花鹅。
    事件隊列中的任務(wù)被稱為宏任務(wù),js引擎中的任務(wù)被稱為微任務(wù)枫浙。當執(zhí)行完一個事件隊列中的事件后刨肃,js引擎會去檢測是否有沒有執(zhí)行的微任務(wù),如果有箩帚,就先執(zhí)行微任務(wù)真友。

微任務(wù)和宏任務(wù)

  1. 微任務(wù):語言標準提供的,promise,process.nextTick(),Mutation Observe
  2. 宏任務(wù):宿主對象提供的紧帕,setTimeout,setInterval,setImmediate,requestAnimationFrame,I/O操作(點擊事件盔然,輸入事件,異步http請求),UI渲染。

js代碼->process.nextTick()->promise->setTimeout->setInterval->setImmediate->I/O->UI渲染

process.nextTick():在當前執(zhí)行棧的尾部愈案,當下一次event loop詢問時執(zhí)行挺尾。
setImmediate():相當于setTimeout(fn,0),當前執(zhí)行棧所有事件執(zhí)行完畢之后執(zhí)行。比setTimeout先執(zhí)行刻帚。

任務(wù)隊列中潦嘶,每當執(zhí)行完一個異步回調(diào)函數(shù)后,event loop就會去執(zhí)行棧(即主程序)中詢問是否有微任務(wù)需要執(zhí)行崇众,這個時候如果有process.nextTick(),會執(zhí)行它掂僵,然后再去執(zhí)行微任務(wù),此時多個微任務(wù)是一起執(zhí)行的顷歌。

為什么js是單線程的锰蓬?

因為js是用來處理用戶與界面的交互,即對dom的操作眯漩,如果設(shè)計成多線程的芹扭,那么會帶來很復(fù)雜的同步問題,比如一個線程需要修改某個節(jié)點赦抖,另一個線程又要刪除這個節(jié)點舱卡,那么這個時候該以哪個線程為主就是個問題了。

h5的新標準中允許使用 new Worker 的方式來開啟一個新的線程队萤,去運行一段單獨的js文件腳本轮锥,但是它嚴格的限制了可使用的功能,比如智能用ECMAScript要尔,不能使用BOM和DOM舍杜。

Web Worker

// todo

模塊化

  1. 全局function
  2. 簡單對象(namespaced)
  3. IIFE(匿名閉包)
  4. AMD規(guī)范,require.js這個工具庫遵循了該規(guī)范赵辕,(define()/require())既绩,異步加載,用于瀏覽器端
  5. CMD規(guī)范还惠,整合了AMD和CommonJs規(guī)范饲握,sea.js這個工具庫遵循了該規(guī)范,使用define()定義模塊,export暴露模塊,require引入模塊世蔗,異步加載践美,用于瀏覽器端
  6. Node.js的CommonJs(module.exports/require),同步
  7. es6的import/export寄猩,編譯時確定依賴嫉晶,而不是運行時確定,所以是靜態(tài)的,可用于前后端

ES6新增

1.es6模塊

import/export

2.let/const

3.symbol

獨一無二的值

4.函數(shù)參數(shù)的默認值替废,數(shù)組解構(gòu)箍铭,對象解構(gòu)

5.class(語法糖)

6.promise 異步函數(shù)

異步編程的解決方案,解決了回調(diào)地獄的問題(es7的async和await也可以解決)椎镣。
缺陷:

  1. 無法取消Promise诈火,一旦創(chuàng)建它就會立即執(zhí)行,無法中途取消状答;
  2. 如果不設(shè)置回調(diào)冷守,promise內(nèi)部的錯誤不會反應(yīng)到外部;
  3. 當處于pending狀態(tài)時惊科,無法得知進展到哪個階段拍摇。

狀態(tài)(pending,fulfilled馆截,rejected)一旦改變就不會再變充活,一般是pending到fulfilled或者pending到rejected,最后的狀態(tài)為resolved蜡娶。
構(gòu)造函數(shù):Promise(fn)

7.Set和Map

8.箭頭函數(shù)

與普通函數(shù)的區(qū)別

  1. this的指向
  2. 沒有arguments綁定混卵,可訪問最近的非箭頭函數(shù)的arguments對象。
  3. 不能作為構(gòu)造函數(shù)(不支持new操作符窖张,沒有prototype)
  4. 不能使用重復(fù)命名的參數(shù)幕随,在非嚴格模式下,普通函數(shù)是支持的荤堪。
  5. 語法更簡潔合陵。

9.數(shù)組的方法

forEach()
map()
filter()
reducer()
some()
every()
find()

數(shù)組扁平化
flat()

10.模板字符串

11.對象字面量簡寫

12.展開運算符(...)

13.剩余參數(shù)(...)

將不確定數(shù)量的元素表示為數(shù)組,一般用于定義參數(shù)

HTTP(Hyper Text Transfer Protocol)

一次完整的http請求

1.域名解析
2.TCP三次握手
3.建立TCP請求后發(fā)起http請求
4.服務(wù)器響應(yīng)請求澄阳,返回html代碼
5.瀏覽器解析html代碼并請求其中的資源(css/js/image)
6.瀏覽器渲染頁面呈現(xiàn)給用戶
7.連接結(jié)束

DNS解析

將網(wǎng)址翻譯成IP地址拥知,本地域名服務(wù)器=》根域名服務(wù)器

TCP協(xié)議

三次握手,四次揮手
狀態(tài)碼(100-500)
1:信息碎赢,服務(wù)器收到請求
2
:成功低剔,操作被成功接收并處理
3:重定向
4
:客服端錯誤
5**:服務(wù)器端錯誤

GET請求和POST請求的區(qū)別

1.傳參方式:get通過url,有長度限制(url限制),post在請求體里面?zhèn)鲄谷瑳]有長度限制
2.后退會導(dǎo)致post請求重新請求
3.get請求可以被緩存
4.get請求只支持URL編碼
5.get請求會留在歷史記錄中
6.get請求只支持ASCII字符他襟齿,post沒有限制

content-type

上傳文件:multipart/form-data
表單提交:application/x-www-form-urlencoded
Json格式:application/json
html文件:text/html

http請求

參考https://www.cnblogs.com/linliquan/p/11362336.html
https://www.cnblogs.com/xuxinstyle/p/9813654.html
特點:無狀態(tài)(對事物處理沒有記憶能力),無連接(每次只處理一個請求枕赵,完成之后就會斷開)猜欺,靈活(可傳遞多種類型的數(shù)據(jù)),簡單快速拷窜,支持客戶/服務(wù)器模式

HTTP 請求報文:請求行开皿,請求頭涧黄,空行,請求體

請求行: http協(xié)議版本字段赋荆,請求方法字段笋妥,URL字段,中間用空格隔開
請求頭: 由關(guān)鍵字/值對組成窄潭,常見的有User-Agent春宣,Accept,Host……
空行:包含回車符和換行符嫉你,告訴服務(wù)端不再有請求頭
請求體: get方法沒有請求體月帝,post方法常用于表單傳輸數(shù)據(jù),經(jīng)常使用Content-Type和Content-Length

HTTP 響應(yīng)報文:狀態(tài)行均抽,響應(yīng)頭嫁赏,空行,響應(yīng)體

狀態(tài)行: http協(xié)議版本字段油挥,狀態(tài)碼潦蝇,狀態(tài)碼的描述字段,中間用空格隔開
狀態(tài)碼由3位數(shù)組成深寥,首位表示響應(yīng)的類型
1:表示服務(wù)器已經(jīng)接受請求攘乒,客戶端可繼續(xù)發(fā)送請求;
2:表示服務(wù)器已經(jīng)成功收到請求并進行處理惋鹅;
3:重定向则酝;302
4:表示客服端請求有非法內(nèi)容,跨域:403
5:服務(wù)器端出錯

響應(yīng)頭: Location,Server,Vary,Connection
空行:包含回車符和換行符闰集,告訴客服端不再有響應(yīng)頭
響應(yīng)體: 服務(wù)器返回的文本信息

前端優(yōu)化方案

  1. 合理緩存
  2. 壓縮文件(JavaScript:UglifyPlugin沽讹,MiniCssExtractPlugin,HTML:HtmlWebpackPlugin)
  3. 圖片懶加載
  4. 事件委托
  5. 防抖節(jié)流
  6. 減少http請求
  7. 合理設(shè)置緩存
  8. 靜態(tài)資源使用cdn
  9. 字體圖標

防抖和節(jié)流

優(yōu)化高頻率執(zhí)行js代碼的一種手段武鲁。
防抖(debounce):持續(xù)觸發(fā)某個事件爽雄,給定時間內(nèi)沒有再觸發(fā)就執(zhí)行一次;如果還沒有到給定時間又觸發(fā)了沐鼠,則重新開始計時挚瘟。
應(yīng)用:輸入驗證,搜索提示

節(jié)流(throttle):持續(xù)觸發(fā)某個事件饲梭,一定時間內(nèi)只執(zhí)行一次乘盖。類似眼睛一段時間內(nèi)只眨一次。
應(yīng)用:監(jiān)聽頁面元素滾動

區(qū)別: 函數(shù)節(jié)流不管事件觸發(fā)有多頻繁憔涉,都會保證在規(guī)定時間內(nèi)一定會執(zhí)行一次真正的事件處理函數(shù)订框,而函數(shù)防抖只是在最后一次事件后才觸發(fā)一次函數(shù)。 比如在頁面的無限加載場景下兜叨,我們需要用戶在滾動頁面時布蔗,每隔一段時間發(fā)一次 Ajax 請求藤违,而不是在用戶停下滾動頁面操作時才去請求數(shù)據(jù)。這樣的場景纵揍,就適合用節(jié)流技術(shù)來實現(xiàn)。

Vue

diff算法
object.defineProperty
生命周期:create mount update destroy

vue-router

  1. 鉤子函數(shù)
    全局鉤子:beforeEach议街,afterEach
    全局解析守衛(wèi):beforeResolve
    路由鉤子:beforeEnter,beforeLeave
    路由組件鉤子:beforeRouteEnter beforeRouteUpdate beforeRouteLeave
  2. 動態(tài)路由
    /:id
    this.$route.params.id
  3. 路由組件
    router-view
    router-link
  4. 路由跳轉(zhuǎn)
    router.push()
    router.replace()
    router.go()
  5. 路由模式
    hash(默認):基于onhashchange事件
    history(需要后端支持): h5的replaceState和pushState

vuex

vue中管理數(shù)據(jù)的倉庫
state,getter,mutation(同步泽谨,dispatch),action(異步,commit),module
應(yīng)用場景:跨組件通信

vue中的組件傳值方式

props
emit,on
event bus
$refs:獲取vue實例特漩,可以調(diào)用其中的方法和屬性

vue中注冊組件的方法
vue.extend()
vue.component()

vue中static和assets的區(qū)別
static:webpack不會打包里面的文件吧雹,必須使用絕對路徑引用里面的文件
assets:webpack會打包里面的文件,重新編譯

React

使用

  1. 項目中使用react全家桶: Create React App
  2. 服務(wù)端渲染react:next.js
  3. ……

Class組件

函數(shù)組件

沒有this涂身,不能讀取this.state
常用作展示類的組件

render prop

高階組件

新特性(react16.8):hook

加強版的函數(shù)組件雄卷,在函數(shù)組件中,需要什么功能就添加對應(yīng)的hook蛤售,將對應(yīng)的功能勾進來丁鹉,可以用官方提供的一些鉤子,也可以自定義鉤子

定義:Hook是一個特殊的函數(shù)悴能,它可以讓你勾入react的特性
使用場景: 當在編寫函數(shù)式組件并且意識到需要向其添加一些state揣钦,以前是需要將其轉(zhuǎn)換成class,現(xiàn)在可以使用hook
使用規(guī)則:不要在循環(huán)漠酿、條件冯凹、嵌套中使用;僅在react的函數(shù)組件中和自定義hook中調(diào)用

useState Hook/State Hook


定義一個state變量
使用方法:
const [count, setCount] = useState(0)
參數(shù):初始state的值
返回值:返回當前的state和setState炒嘲,需成對獲取

useEffect Hook/Effect Hook


數(shù)據(jù)獲取宇姚,設(shè)置訂閱以及手動更改 React 組件中的 DOM 都屬于副作用,可以把 useEffect Hook 看做 componentDidMount夫凸,componentDidUpdate 和 componentWillUnmount 這三個函數(shù)的組合浑劳。
React 組件中有兩種常見副作用操作:需要清除的(例如定時器,訂閱好友的在線狀態(tài))和不需要清除的寸痢,前者只需要將清除的函數(shù)通過return返回回去呀洲,react將會自動的在組件卸載時調(diào)用。注意:組件每次重新渲染的時候也會調(diào)用清除函數(shù)啼止,也正是這樣規(guī)避了使用class時沒有在componentDidMount的生命周期函數(shù)中處理而出現(xiàn)的bug道逗。
使用:
useEffect(() => {} [, state]),第二個可選參數(shù)為state献烦,用于在react重新渲染之前比較前后兩次的state的值是否一樣滓窍,如果相同,則跳過此次操作巩那,否則就會重新渲染吏夯。當?shù)诙€參數(shù)為[]時此蜈,react只會執(zhí)行一次effect(僅在組件掛載和卸載時使用)
好處:
關(guān)注點分離,即useEffect()允許用戶以代碼的用途來分割它們噪生,而不是通過生命周期函數(shù)來分割它們

useReducer


自定義hooks


用于共享組件之間的邏輯
只需要函數(shù)名為use開頭

虛擬dom diff算法
生態(tài)完整
屬于MVC框架中的view層裆赵,數(shù)據(jù)單向流動
共享組件之間的狀態(tài)邏輯: render props 和高階組件
生命周期:
componentWillMount() componentDidMount()
componentWillReceiveProps() shouldComponentUpdate() componentDidUpdate()
componentWillUnmount()

react-router

安裝:react-router-dom
模式:history:BrowserRouter,hash:HashRouter
主要的組件有:
BrowserRouter跺嗽、HashRouter: 包裹路由組件战授,在最底層
Switch、Route:匹配路由的組件
Link桨嫁、NavLink:導(dǎo)航組件植兰,兩者都會渲染成a標簽,NavLink可以設(shè)置activeClassName璃吧,當導(dǎo)航到這個組件時楣导,就會應(yīng)用這個樣式
Redirect:重定向

搭建react全家桶單頁應(yīng)用步驟

初始化一個項目:npm init
創(chuàng)建項目文件夾,配置webpack
配置入口頁面
在入口頁面添加路由(react-router-dom)

Axios

基于promise的HTTP庫畜挨,可以在瀏覽器中和nodejs中使用
特性:

  1. 在瀏覽器中創(chuàng)建XmlHttpRequest;
  2. 在node.js中創(chuàng)建http請求筒繁;
  3. 支持promise API
  4. 攔截請求和響應(yīng)
  5. 取消請求
  6. 自動轉(zhuǎn)換JSON數(shù)據(jù)
  7. 客戶端支持防御XSRF

攔截器

axios.interceptor.response/request
修改請求頭的一些配置
添加請求中的加載動畫
添加參數(shù)

常用方法

axios(config)
axios(url[,config])

請求方法的別名

axios.get()
axios.post()

封裝

  1. 安裝并引用axios
  2. 創(chuàng)建axios的實例:axios.create(配置對象)
  3. 請求攔截:axios.interceptors.request.use(),處理請求數(shù)據(jù)
  4. 響應(yīng)攔截:axios.interceptors.response.use()朦促,處理數(shù)據(jù)膝晾,超時
  5. get請求封裝,設(shè)置content-type(form-data或application/json)
  6. post請求封裝务冕,設(shè)置content-type(form-data或application/json)
  7. 暴露模塊

Fetch

Webpack

webpack面試:https://juejin.cn/post/6844904094281236487#heading-0

模塊打包工具血当,可壓縮,優(yōu)化代碼格式
支持大部分模塊規(guī)范:COMMONJS禀忆、AMD(require.js)臊旭、CMD(sea.js)、ES6模塊

核心

entry:一個或多個入口箩退,一般是js文件离熏,通過遞歸找到依賴文件,多入口文件的entry通過鍵值對的形式輸入

output:出口文件及位置

loader:webpack本身只能解析js/json文件戴涝,loader使webpack可以解析打包其他格式的文件滋戳,在module.rules中配置,test指定匹配規(guī)則啥刻,use指定使用的loader

常見的loader
css-loader: 支持.css文件的加載和解析奸鸯,轉(zhuǎn)換成commonjs對象
style-loader: 將樣式通過style標簽插入到head中
url-loader: 內(nèi)部使用了file-loader,可以自動將較小文件打包成base64
file-loader: 圖片可帽、字體的打包
raw-loader: 將文件以字符串的形式導(dǎo)入(base64)
babel-loader: 轉(zhuǎn)換es5以上版本的新特性語法
vue-loader
postcss-loader
image-loader
sass-loader/less-loader: 將sass/less文件轉(zhuǎn)換成css文件
sass-resources-loader: 提取sass中的全局變量
ts-loader: 將typeScript轉(zhuǎn)換成js
thread-loader: 多進程打包css和js

plugin:插件娄涩,擴展功能,資源管理映跟,環(huán)境變量注入蓄拣,作用于整個構(gòu)建過程扬虚,放到plugins數(shù)組中

常見的plugin
define-plugin:定義環(huán)境變量
commons-chunk-plugin:提取公共代碼
clean-webpack-plugin:清理構(gòu)建目錄
extract-text-webpack-plugin:將css從bundle文件里提取成一個獨立的css文件
mini-css-extract-plugin:將css提取成一個單獨的css文件,支持webpack4球恤,使用link標簽的方式插入到HTML中
copy-webpack-plugin:將文件或文件夾拷貝到構(gòu)建的輸出目錄
html-webpack-plugin:創(chuàng)建html文件去承載輸出的bundle
uglify-js-webpack-plugin:壓縮混淆js代碼
zip-webpack-plugin:將打包的資源生成zip文件
web-webpack-plugin:為單頁應(yīng)用輸出html辜昵,比前者好用
hot-module-replacement-plugin:熱更新,webpack自帶碎捺,在devServer中配置hot:true會自動引入這個插件路鹰,具體作用:將HMR runtime注入到webpack打包的bundle.js中,使其可以與HMR server建立websocket通信收厨,從而實現(xiàn)熱更新

mode(webpack4新增字段)
可選值

  1. development: 設(shè)置process.env.NODE_ENV: development,開啟NamedChunksPlugin和NamedModulesPlugin
  2. production: 設(shè)置process.env.NODE_ENV: production,開啟FlagDependencyUsagePlugin, FlagIncludedChunksPlugin, ModuleConcatenationPlugin, NoEmitOnErrorsPlugin, OccurrenceOrderPlugin, SideEffectsFlagPlugin, TerserPlugin
  3. none: 不開啟任何優(yōu)化項

webpack中的文件監(jiān)聽

  1. webpack --watch 需要手動刷新瀏覽器
  2. 在webpack.config.js中設(shè)置watch:true
    原理:輪詢(poll)判斷文件的最后編輯時間是否變化,某個文件發(fā)生了變化并不會立刻告訴監(jiān)聽者优构,而是先緩存起來诵叁,等待一段時間(aggregateTimeout:默認300ms)再告訴監(jiān)聽者,可以設(shè)置ignored(不監(jiān)聽的文件或文件夾)來提高性能
module.exports = {
  watch: true, // 默認false
  watchOptions: {
    ignored: /node_modules/, 
    aggregateTimeout: 300,
    poll: 1000
  }
}
  1. 熱更新WDS(webpack-dev-server)
    wds不輸出文件,不刷新瀏覽器(可添加--open)钦椭,是放在內(nèi)存中拧额,一般配合HotModuleReplacementPlugin(webpack自帶)使用,在webpack-dev-server中配置hot:true,會自動引入這個plugin
  2. 使用webpack-dev-middleware
    將webpack打包的文件傳輸給服務(wù)器彪腔,適用于靈活的定制場景
    const express = require("express");
    const webpack = require("webpack");
    const webpackDevMiddleware = require("webpack-dev-middleware");
    
    const app = express();
    const config = require('./webpack.config');
    const compiler = webpack(config);
    
    app.use(webpackDevMiddleware(compiler, {
      publicPath: config.output.publicPath
    }))
    
    app.listen(3000, function() {
      console.log('Example app is listening on port 3000!\n')
    })
    

熱更新原理分析:
HMR runtime
HMR server
Bundle server
websocket

使用webpack優(yōu)化前端代碼

  1. 代碼壓縮
    壓縮js:UglifyJsWebpackPlugin(webpack4內(nèi)置)和ParallelUglifyPlugin
    壓縮css:OptimizeCssAssetsWebpackPlugin,同時使用cssnano(css預(yù)處理器)
    壓縮html: htmlWebpackPlugin, 設(shè)置壓縮參數(shù)minify
  2. 自動清理構(gòu)建目錄
    clean-webpack-plugin
  3. 增強css
    自動補全瀏覽器前綴:autoprefixer插件(后置處理器)侥锦,配合postcss-loader使用
    px自動轉(zhuǎn)化成rem: px2rem-loader配合手淘的lib-flexible庫(自動計算根元素font-size的值)
  4. 靜態(tài)資源內(nèi)聯(lián)

意義:
a. 頁面框架初始化腳本
b. 上報相關(guān)打點
c. css內(nèi)聯(lián)避免頁面閃動
d. 減少http網(wǎng)絡(luò)請求數(shù)(小圖片或字體內(nèi)聯(lián):url-loader)

 html和js的內(nèi)聯(lián):使用raw-loader   

a. html: ${require('raw-loader!babel-loader!./metal.html')}
b. js: <script>${require('raw-loader!babel-loader!../node_modules/lib-flexible.js')}</script$>
c. css: 借助style-loader或者使用html-inline-css-webpack-plugin

  1. 多頁面打包
    多頁面: 每次頁面跳轉(zhuǎn)的時候,后臺服務(wù)器都會返回一個新的html文檔
    頁面解耦德挣,利于seo
    webpack中的實現(xiàn): 利用glob.sync,配合html-webpack-plugin插件
    entry恭垦; glob.sync(path.join(__dirname, './src/*/index.js'))

  2. source map
    通過source map 定位到源代碼,開發(fā)環(huán)境開啟格嗅,生產(chǎn)環(huán)境關(guān)閉
    關(guān)鍵字:
    eval: 使用eval包裹代碼塊
    source map: 產(chǎn)生.map文件
    cheap: 不含列信息
    inline: 將.map作為DataURI嵌入番挺,不單獨生產(chǎn).map文件
    module: 包含loader的source map

  3. 提取頁面公共資源
    基礎(chǔ)庫的分離:
    將react、react-dom通過cdn引入屯掖,不打入bundle中
    使用html-webpack-externals-plugin
    或者:
    使用splitChunksPlugin(webpack4內(nèi)置玄柏,代替CommonsChunkPlugin)進行公共腳本分離
    sass-resource-loader

  4. 搖樹優(yōu)化(tree shaking)
    概念: 一個模塊中可能有多個方法,只要某個方法用到了贴铜,整個模塊都會被引入進來粪摘,tree shaking則是將用到的方法打包,其他的方法會在uglify的階段擦除掉
    webpack默認支持绍坝,在.babelrc里面設(shè)置modules: false
    當mode設(shè)置為production的時候默認開啟
    要求: 必須是es6的語法徘意,cjs不支持
    es6模塊特點:
    a. 只能作為模塊頂層的語句出現(xiàn)
    b. import 的模塊名只能是字符串常量
    c. import binding是 immutable(不可變的)

  5. scope hoisting(作用域提升)
    webpack打包分析
    a. 打包出來是一個IIFE(匿名閉包)
    b. modules是一個數(shù)組,每一項是一個模塊初始化函數(shù)
    c. __webpack_require用來加載模塊陷嘴,返回module.exports
    d. 通過WEBPACK_REQUIRE_METHOD(0)啟動程序
    scope hoisting可以減少函數(shù)聲明代碼和內(nèi)存開銷
    webpack4中mode設(shè)為production會自動引用映砖,同樣只支持es6語法,不支持cjs

  6. 代碼分割和動態(tài)引入
    代碼分割:webpack將代碼庫分割成chunks灾挨,當代碼需要運行的時候才會被加載
    適用場景:腳本懶加載邑退,使初始腳本更兄袼巍; 抽離相同代碼塊到一個共享塊
    CommonJS: require.ensure
    ES6: 動態(tài)import(目前還沒有原生支持地技,需要babel轉(zhuǎn)換)

  7. 結(jié)合Eslint使用
    Airbnb: eslint-config-airbnb, eslint-config-airbnb-base

  8. 打包庫和組件
    可通過多種方式引用:CJS/AMD/ES-MODULE
    有壓縮版和未壓縮版
    示例:

{
  mode: 'production',
  entry: {
    'large-number': './src/index.js',
    'large-number.min': './src/index.js'
  },
  output: {
    filename: '[name].js',
    library: 'largeNumber',
    libraryExport: 'default',
    libraryTarget: 'umd'
  }
}
  1. 服務(wù)器端渲染(減少http請求蜈七,減少白屏?xí)r間,利于seo)
    客服端:
    a. 使用react-dom/server的renderToString將react組件渲染成字符串莫矗;
    b. 服務(wù)端路由返回對應(yīng)的模板
    c. 打包出針對服務(wù)端的組件
    服務(wù)器端渲染會出現(xiàn)的問題:
    瀏覽器的全局變量(window,document)node端不支持——添加判斷語句
    某些組件不兼容——根據(jù)打包環(huán)境單獨打包適配
    不支持fetch——使用isomorphic-fetch或者改用axios
    nodejs無法解析css——將style-loader替換成isomorphic-style-loader或者服務(wù)端打包時通過ignore-loader忽略掉css解析
    將打包后的html模板作為服務(wù)器端返回的HTML模板飒硅,將打包后的react組件通過占位符的形式放入合適位置

  2. 優(yōu)化構(gòu)建時命令行顯示的日志
    production => stats: errors-only
    development => 在devServer中設(shè)置 stats: errors-only
    注意:引入的方法不能有副作用(即相同的輸入得到不同的輸出,引用了全局變量就會有副作用)作谚,否則會失效

webpack構(gòu)建速度和體積優(yōu)化

  1. 初級優(yōu)化: 使用webpack內(nèi)置的stats
  2. 使用speed-measure-webpack-plugin分析速度
  3. 使用webpack-bundle-analyzer分析體積
  4. 使用高版本的webpack和nodejs,高版本意味著高性能(但也存在問題三娩,酌情使用)
  5. 多進程多實例構(gòu)建(thread-loader/parallel-webpack/happy-pack(沒有維護了推薦第一個))
  6. 多進程并行壓縮代碼(parallel-uglify-plugin/uglifyJs-webpack-plugin/terser-webpack-plugin/)
  7. 進一步分包:預(yù)編譯資源模塊(DLLPlugin進行分包,DllReferencePlugin對manifest.json)
  8. 緩存:提升二次構(gòu)建速度(babel-loader/terser-webpack-plugin/cache-loader/hard-source-webpack-plugin)
  9. 縮小構(gòu)建目標:合理配置resolve
  10. 使用tree-shaking 擦除無用的js和css: purgecss-webpack-plugin配合mini-css-extract-plugin
  11. 圖片壓縮:配置image-webpack-loader(基于Node庫的imagemin或者tinypng API)
  12. 動態(tài)polyfill:polyfillServices(根據(jù)不同的機型(userAgent)下載不同版本的polyfill)

webpack構(gòu)建原理分析

  1. 命令行輸入指令妹懒,npm會讓命令行工具進入node_modules.bin目錄查找webpack.sh/webpack.cmd文件雀监,進一步執(zhí)行node_modules\webpack\bin\webpack.js
  2. 分析webpack.js(啟用子進程運行命令,安裝依賴眨唬,判斷webpack-cli是否安裝)
  3. 分析webpack-cli所做的工作(引入yargs,對命令行進行定制会前;分析命令行參數(shù),轉(zhuǎn)換參數(shù)匾竿,組成編譯配置項瓦宜;引用webpack,根據(jù)配置項進行編譯和構(gòu)建)
  4. 分析webpack-cli源碼(處理命令行參數(shù)岭妖,生成最終配置項options,實例化webpack對象临庇,執(zhí)行構(gòu)建流程)

手寫loader

本質(zhì):導(dǎo)出為函數(shù)的JavaScript模塊,函數(shù)接收資源区转,返回處理后的資源
執(zhí)行順序:從右往左串行執(zhí)行(函數(shù)式編程中的compose組合方式)
開發(fā)和調(diào)試:使用loader-runner苔巨,允許在不安裝webpack的情況下運行l(wèi)oader
輔助功能:loader-utils

手寫插件

本質(zhì):導(dǎo)出一個類,包含有apply()和hooks

文件指紋

打包后輸出文件名的后綴废离,用于版本管理侄泽,發(fā)布時僅需要發(fā)布更改過的內(nèi)容,沒有更改過的使用緩存
生成:
hash: 只要項目有改動蜻韭,hash就會變
contentHash:根據(jù)文件內(nèi)容定義悼尾,文件內(nèi)容變動,他就會變,常見的場景:一個js文件引用了css文件肖方,css文件一般使用contentHash
chunkHash:不同的entry會有不同的chunkHash,chunk內(nèi)容改變闺魏,他就會變

占位符名稱:
[ext]: 資源后綴名
[name]: 文件名
[path]: 文件的相對路徑
[folder]: 文件夾
[contenthash]: hash值,md5加密,長度值為32位俯画,[chunkhash:8]表示取前8位
[hash]: hash值

js的文件指紋設(shè)置:
output.filename: '[name]_[chunkhash:8].js'
css的文件指紋設(shè)置:
使用MiniCssExtraPlugin提成單獨的文件再設(shè)置析桥,與style-loader功能互斥,不能同時使用
new MiniCssExtractPlugin({
filename: [filename]_[contenthash:8].css
})
圖片的文件指紋設(shè)置:在file-loader中設(shè)置
loader: "file-loader",
options: {
name: 'img/[name][hash:8].[ext]'
}

名詞解釋:
bundle:打包的文件
chunk:代碼塊,由多個模塊組成
module:模塊泡仗,一個文件

AST

抽象語法樹(Abstract Syntax Tree)埋虹,源代碼的抽象語法結(jié)構(gòu)的樹狀表現(xiàn)形式

babel

presets

每一項都對應(yīng)一部分功能的集合

plugins

每一項都對應(yīng)一個功能

微信公眾號

openId

當用戶關(guān)注了公眾號,公眾號可獲得該用戶的openId(加密的微信號)娩怎,不同的公眾號openId不同搔课,

unionId

同一個開放平臺賬號下的微信公眾號和應(yīng)用(app)對應(yīng)每個用戶都有個共同的unionId

網(wǎng)頁授權(quán)(scope參數(shù))

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

參數(shù) 是否必須 說明
appid 公眾號的唯一標識
redirect_uri 授權(quán)后重定向的回調(diào)鏈接地址,用urlEcode進行編碼
response_type code
scope 應(yīng)用授權(quán)作用域
state 重定向后會帶上state參數(shù)截亦,開發(fā)者可以填寫a-zA-Z0-9的參數(shù)值爬泥,最多128字節(jié)
#wechat_redirect 返無論直接打開還是做頁面302重定向時候,必須帶此參數(shù)回國家地區(qū)語言版本
  1. 靜默授權(quán) snsapi_base 不彈出授權(quán)頁面崩瓤,直接跳轉(zhuǎn)袍啡,只能獲取用戶openid
  2. 非靜默授權(quán) snsapi_userinfo 彈出授權(quán)頁面,可通過openid拿到昵稱却桶、性別葬馋、所在地。并且肾扰, 即使在未關(guān)注的情況下,只要用戶授權(quán)蛋逾,也能獲取其信息

用戶授權(quán)后跳轉(zhuǎn)頁面

redirect_uri/?code=CODE&state=STATE集晚。

調(diào)用憑證

當用戶授權(quán)給公眾號之后,公眾號可以獲得一個網(wǎng)頁授權(quán)特有的access_token区匣,后期可通過這個access_token進行接口調(diào)用(獲取用戶基本信息)

相關(guān)接口

獲取用戶基本信息(openId和unionId通用)

GET https://api.weixin.qq.com/cgi-bin/user/info?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
get請求 https協(xié)議

參數(shù) 是否必須 說明
access_token 調(diào)用接口憑證
openId 普通用戶的標識偷拔,對當前公眾號唯一
lang 返回國家地區(qū)語言版本
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市亏钩,隨后出現(xiàn)的幾起案子莲绰,更是在濱河造成了極大的恐慌,老刑警劉巖姑丑,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛤签,死亡現(xiàn)場離奇詭異,居然都是意外死亡栅哀,警方通過查閱死者的電腦和手機震肮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來留拾,“玉大人戳晌,你說我怎么就攤上這事〕杖幔” “怎么了沦偎?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我豪嚎,道長搔驼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任疙渣,我火速辦了婚禮匙奴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘妄荔。我一直安慰自己泼菌,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布啦租。 她就那樣靜靜地躺著哗伯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪篷角。 梳的紋絲不亂的頭發(fā)上焊刹,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音恳蹲,去河邊找鬼虐块。 笑死,一個胖子當著我的面吹牛嘉蕾,可吹牛的內(nèi)容都是我干的贺奠。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼错忱,長吁一口氣:“原來是場噩夢啊……” “哼儡率!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起以清,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤儿普,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后掷倔,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體眉孩,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年今魔,在試婚紗的時候發(fā)現(xiàn)自己被綠了勺像。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡错森,死狀恐怖吟宦,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情涩维,我是刑警寧澤殃姓,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布袁波,位于F島的核電站,受9級特大地震影響蜗侈,放射性物質(zhì)發(fā)生泄漏篷牌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一踏幻、第九天 我趴在偏房一處隱蔽的房頂上張望枷颊。 院中可真熱鬧,春花似錦该面、人聲如沸夭苗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽题造。三九已至,卻和暖如春猾瘸,著一層夾襖步出監(jiān)牢的瞬間界赔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工牵触, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留淮悼,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓揽思,卻偏偏與公主長得像敛惊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子绰更,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

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