JS1

第一章

前端三大語言:HTML(專門編寫網頁內容)、CSS(編寫網頁樣式)、JS(專門編寫網頁交互行為)

能簡寫盡量簡寫

交互(IPO): ①用戶輸入;②執行: 程序接受、處理、響應數據;③輸出處理結果

原生JS:不需要下載任何第三方文件,僅依靠瀏覽器就可直接執行的js代碼

學習版本:ES6(2015)

現版本:ES7

中文亂碼問題:引入的 .js 文件要與HTML文件一樣是UTF-8模式,否則要在script中加?charset="gbk",但兩個不能同時使用

API(Application Programming Interface,應用程序編程接口)是一套用來控制Windows的各個部件的外觀和行為的一套預先定義的Windows函數

如果回調函數無法取名,可以在回調函數中調用定義的另一個有名的函數,以此來達到目的

判斷數據是否為null、0、""、NaN、null、undefined一律可以省略等號后的值,只判斷是否為false

js的事件監聽跟css不一樣,css只要設定好了樣式,不論是原來就有的還是新添加的,都有一樣的表現,而事件監聽不同,只能給已經加載好的元素綁定事件

_______________________________________________________________________________________________

typeof null返回object

最初,JavaScript使用標記位來區分對象類型和原始類型:對象值使用0來標識,原始值使用1,因此,導致全為0的null被識別為object

JavaScript可以通過typeof ...來判斷原始數據類型,但不能夠準確判斷引用類型,但可以用Object的toString方法來判斷:?console.log(Object.prototype.toString.call(要判斷的數據))

一元運算符: 有些運算符兩邊有2個操作數,比如2+3、6%5等,這些叫做二元運算符

? ? ? ? ? ? 只有一個操作數的叫做一元運算符,它們的優先級高于二元運算符

? ? ? ? ? ? 一元運算符包括: ++(自加)、--(自減)、!(邏輯非)

JS的運算規則: 優先級相同的運算符從左向右計算(賦值運算符相反)

var a=1;b=++a+a++; 表示 b=2+2;

var a={n:1};

var b=a;

a.x=a={n:2}; ? ?//從左往右讀(取出來),從右往左執行

? ? ? ? ? ? ? ? //先執行a.x={n:2},再執行a={n:2}

console.log(a.x);? ? //undefined

console.log(b.x);? ? //{n:2}

console.log(a);? ? ? //{n:2}

console.log(b);? ? ? //{n:1, x:{n:2}}

_______________________________________________________________________________________________

1、Javascript概述

Javascript運行于Javascript 【解釋器/引擎】中的解釋性腳本語言

Javascript運行環境:1、Javascript解釋器 :NodeJS

? ? ? ? ? ? ? ? ? ? 2、嵌入在瀏覽器中的內核(引擎)

? 解釋型:無需編譯,直接運行,出錯就停止

? 腳本語言:純文本語言

? JS解釋器和JS引擎:1、獨立安裝的JS解釋器:NodeJS

? ? ? ? ? ? ? ? ? ? 2、嵌入在瀏覽器內核中的JS解釋器:只要有瀏覽器,就能運行JS

2、Javascript 發展

? ①1992年 Nombas公司開發了一款腳本語言 ScriptEase ,可以嵌入在網頁中

? ②1995年 Netscape(網景)公司為Navigator2.0瀏覽器開發了一款腳本語言 LiveScript,為了蹭熱點將其命名為 Javascript,其實Javascript與Java沒有一點關系

? ③1996年,Microsoft ,為了IE3.0,發布了一個Javascript克隆版本 JScript

? ④1997年 Javascript1.1 作為草案提交給了ECMA(歐洲計算機制造商協會)→ECMA-262標準→ECMAScript(ECMA制定的JavaScript語言國際標準,規定了JS語言的核心語法)

3、Javascript (原生JS)的組成

??① 核心(ECMAScript,簡稱ES,ECMA制定的JavaScript語言國際標準,規定JS語言的核心語法)

? ② 文檔對象模型(DOM---Document Object Model)允許讓JS和HTML元素進行對話

?專門操作網頁內容的API

? ③ 瀏覽器對象模型(BOM—Browser Object Model)允許讓JS和瀏覽器進行對話和操作

?專門操作瀏覽器窗口的API

4、Javascript特點:

? ①任何編輯工具(例如:記事本)都可以編寫Javascript,語法類似于Java,C,...

? ②無需編譯,由JS解釋器運行(自上向下邊讀邊解釋邊執行,后解釋的相同內容會覆蓋先解釋的)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?賦值:?從左往右讀(取出來待執行),從右往左執行(賦值)

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?運算:從左往右計算

? ③弱類型語言:聲明變量時,不必提前規定變量的數據類型,先后可保存不同類型的數據,由值來自動隱式轉換數據類型

? ④基于對象的編程語言———萬物皆對象

5、 Javascript的用途

? ①客戶端Javascript:瀏覽器中運行

? ? 1、客戶端數據計算

? ? 2、客戶端表單輸入驗證

? ? 3、瀏覽器事件的觸發和處理

? ? 4、客戶端動畫效果特效制作

? ? 5、服務器的異步數據提交(ajax)

? ②服務器端Javascript:1、分布式運算????2、實時服務器????3、窗口應用????4、網絡應用

_______________________________________________________________________________________________

Javascript基礎語法

1、JS運行在腳本解釋引擎:專門解析JS語言,并執行js程序的小軟件

瀏覽器內核:負責頁面內容的渲染,由兩部分組成:

? ①內容排版引擎:解析 HTML 和 CSS,并顯示網頁內容和樣式的小軟件,效率高

? ②腳本解釋引擎:解析并執行 Javascript 程序的小軟件,效率略低

全球僅有四個獨立的瀏覽器內核

? ? ? ? 瀏覽器 ? ? ? ? ? ?內核 ? ?內容引擎 ? ?腳本引擎

? ? Microsoft IE ? ? ? ?Trident? ? -- ? ? ? ? Chakra

? ? Mozilla Firefox ? ? ?Gecko? ?? -- ? ? ? ?Monkey系列

? ? Apple Safari ? ? ?? Webkit ? ?Webcore ? ? ?Nitro

? ? Google Chrome ? ? ?Webkit? ?Webcore ? ? ? V8

? ? Opera ? ? ? ? ? ? ?Presto? ? ?-- ? ? ?? Carakan

? ? Opera(2013 -) ? ? ? Webkit ? ?Webcore ? ? ? V8

2、Javascript運行環境

運行環境:

? ①安裝獨立的Javascript解釋器—Node.js

? ? 步驟:1、安裝NodeJS

? ? ? ? ? 2、運行JS腳本:console.log ("輸出的內容");

? ②瀏覽器內核嵌入的JS解釋器:在console中輸入腳本運行,將JS腳本嵌入在HTML網頁中執行

_______________________________________________________________________________________________

輸出位置(3個)

①向頁面添加內容:<script>document.write("html代碼段");</script>? /*document:當前網頁(不推薦)*/

②彈出對話框:彈出對話框顯示消息:alert("提示消息");? ?? /*彈出瀏覽器預定好的樣式,不可修改*/

③向控制臺中輸出內容:F12→console.log("xx");? ? /*控制臺專門用于調試程序,臨時顯示調試結果*/

書寫位置(2處)

①頁面的<script type="text/javascript"></script>標簽中嵌入腳本

? EX:?<script>document.write("xxx");</script>

? ? ? document.write:網頁中打印輸出一句話!里面的內容是交給內容排版引擎解析的

? EX:docume.write("<h1>第一個JS</h1>");

一旦進入script標簽內,就要使用js的語法

問題: 不符合內容與行為分離的原則,不便于維護和共用

②將腳本嵌入在外部的腳本文件中

? 1、創建腳本文件并編寫JS腳本:創建一個**.JS文件;直接編寫JS腳本

? 2、使用網頁中進行引入:<script src="url"></script>

? ? ?注意:必須成對出現,兩個script標簽之間不允許出現其他內容

? ? ?放在<head></head>中,瀏覽器解析head部分時就會執行這個代碼,然后才會解析頁面其它部分

? ? ?放在<body></body>中,瀏覽器讀取到該語句時才會執行(一般使用此方法)

3、JS基本調試

? JS運行過程中,如果出現錯誤,則終止本塊的執行,但不影響后續代碼塊執行

? <script></script>:代碼塊

4、基本語法規范

? ①代碼的基本組成:語句

? ? 語句:允許被JS引擎所解釋的代碼,由表達式,關鍵字,運行符所組成

? ? 注意:嚴格區分大小寫

? ? ? ? ?所有的標點,全部都是英文的

? ? ? ? ? 字符串可以用" "或' '

? ? ? ? ?語句都是以;表示結束

? ②JS中的注釋:單行注釋:// ? ? ? ? ? ? ? ? ? ? ?多行注釋:/**/

_______________________________________________________________________________________________

輸出臺操作(F12):

①Shift+Enter: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*僅換行暫不執行,用于多行輸出*/

②console.log("Hello World!"); ? ? ? ? ? ? ? /*每寫log一次,都自動換行*/

③左上角圓形叉號:Clear console ? ? ? ? ? ? ? /*清空控制臺*/

④調出剛寫過的代碼段:上下鍵切換

調試程序:2種

斷點調試:debugger; ? ?/*加在console.log 之前,在開著F12的情況下才有效*/

console.log(" , , "); /*在控制臺輸出(""中的+會將這兩個變量視為字符串,最后一個不能加,)*/

啟用嚴格模式:在script頂部插入:"use strict"; ? ? ? ? ? ? /*解決靜默失敗*/

嚴格模式下: 不用var定義變量是非法的,會導致錯誤;調用函數中的this值是undefined

非嚴格模式下: 不用var定義變量是全局變量;調用函數中的this值是全局對象

輸入: prompt("輸入提示") ? ? ? ? /*輸入框: 專門請用戶輸入一個數據的對話框*/

_______________________________________________________________________________________________

變量和常量

變量

1、什么是變量:內存中存儲一個數據的存儲空間,再起一個名字,為了重用

? ?量:數據

? ?變量:變化的數據

? ?內存:保存程序在運行過程中所需要用到的數據

?? 變量:內存中的一段存儲空間,用于保存數據

?? 值:變量中所保存的數據

?? 變量名:內存地址的別名即保存數據的空間的名稱

2、變量的聲明

①聲明變量:在內存中,創建一個存儲空間,再起一個名字

var 變量名;

默認值:undefined:專門表示一個從未使用過的變量

②為變量賦值:將數據保存在變量中(盡量不要讓變量空著,賦初值)

變量名=值;

注意:只有等號才能改變變量中的值;等號會覆蓋變量中的原值;變量賦值前必須先聲明(給未聲明過的變量賦值,普通情況下自動創建新變量并保存值;ES5模式規定禁止給未聲明的變量賦值)

取用:取出變量中的值做運算,只要使用變量值,等效于直接使用變量中的值

? ? ? 不加引號的都會當做變量

③聲明變量并賦值

var 變量名=值; ? ? ? ? ? ? ? ?/*只有等號才能賦值*/

注意:如果變量的值時非數字類型的話,要使用''或""括起來

? ? ? 聲明時可以省略var關鍵字,省略后成為了全局變量,推薦不要省略var關鍵字

④推薦:?一條語句聲明多個變量,用,分隔(每個變量必須要用=才能賦值)(建議多個變量換行寫)

? ? 例:var 名1="xxx",名2="xxx",名3="xxx";

3、變量名的命名規范

? ①不允許是JS的關鍵字或保留關鍵字

? ②可以包含字母,數字,下劃線(_),$

? ③不能以數字開頭

? ④盡量見名知義

? ⑤可以采用“匈牙利命名法”,“駝峰命名法”,“下劃線命名法”

? ? 駝峰命名法:變量名稱,如果只有一個單詞組成,采用全小寫模式 ? 例:var age

? ? 如果變量名由多個單詞組成,第一個單詞全小寫,其余的每個單詞的首字母,變大寫

4、變量的使用

①變量定義后,未賦過值而直接使用

? EX:var userName;

? ? ? console.log (userName); ? ? 結果為:undefined,表示沒有值

②對變量進行存取操作

? 1、獲取變量的值-GET操作

? ?? 例:var userAge=18;--------存值

? ? ? ?? console.log(userAge);------------取值

? ? ? ? ?document.write(userAge);----------取值

? ? ? ?? user-----存值操作 ? 18------取值操作

輸出從未聲明的變量時會返回:ReferenceError ? ? ? 沒有找到對象

? 總結:只要變量沒有出現在=左邊,一律是取值

? 2、設置變量的值 – SET操作

? ? ?例:var userAge=15;

? ? ? ?? var newAge=userAge

? ? ? ?? userAge---取值 ? newAge---存值

? ? ? ?? newAge=newAge+15;

? ? ? ? ?console.log(newAge);--------30

? 總結:只要變量出現在=左邊,一律是存值操作

筆試題: var a,b=2; ?→ ?a:undefined? b:2

? ? ? ? var a=b=2; ?→ ?a:2 ?b:2 (在函數中時,a是局部變量,b是全局變量)

_______________________________________________________________________________________________

常量

1、什么是常量

一經聲明定義后,就不允許被修改的數據成為常量

目的:保證數據的準確性

適合用常量表示的數據:EX:1、圓周率:兀=3.1415926; ?2、一周有7天

2、語法

const 常量名=值;

注意:①常量不允許賦值,否則會靜默失敗,ES5嚴格模式會報錯

? ? ? ②聲明變量時,必須初始化其值

? ? ? ③習慣上,常量名采用純大寫形式

取值:和變量用法一樣

var 變量=prompt("提示")? /*請用戶輸入變量的值,并保存在變量中,不能在node里使用prompt*/

_______________________________________________________________________________________________

數據類型(掌握)

1、什么是數據類型

?? 保存在內存中數據的真實類型,約束了數據在內存所占的空間大小,存儲結構

?? 不同的數據類型,擅長執行的操作不一樣,就需要配套合適的存儲結構,給操作提供便利

2、數據類型分類

原始類型(基本數據類型: 值直接保存在變量本地的數據類型)

? 包括5個: number、string、boolean、null、undefined

引用類型: 值無法直接保存在變量本地的復雜數據類型

? 包括: Array、Function、Date、RegExp、Error、Object、String、Number、Boolean、Math、Window

數組是引用類型的對象,對象的本質就是關聯數組,只不過用法更簡單

函數名其實僅是一個普通的變量 ,函數其實是保存代碼段的引用類型的對象

? ①number類型:

專門用于存儲數字,表示32(8位一個字節)位的"整數",也可以標識64位的"浮點數",采用二進制存儲(),凡是不加引號的數字直接量,默認都是number類型

何時: 如果一個數值可能需要比較大小和進行數學計算時

存儲空間: 整數占4個字節,浮點數占8個字節,數值大小和存儲空間無關(1字節=8位二進制)

特殊:舍入誤差:計算機中也有計算不盡的數值

原因:number類型底層都是二進制存儲

解決:四舍五入

n.toFixed(n)//四舍五入,保留n位小數,返回字符串類型,傳入數字,可Number(x).toFixed(2)

typeof x / typeof(x) ? ? ? ? ? /*返回變量x中存儲的數據類型*/

var m=n.toString(2) ? ? ? ? ?? /*把n中的數值(先轉為Unicode)轉換為內存中的二進制形式*/

? ②string類型

什么是: 凡是加引號的一串字符直接量都是字符串類型,EX:姓名,性別,住址,身份證號,不用做計算和比較大小,都用""或''包裹

何時: 記錄一串文字

js中一切文字都是由Unicode字符、數字、標點符號的序列組成的

Unicode 是編碼(對全球主要語言的每個字編一個號)的一種,Unicode下所有的字符,每個字符均占2字節,而且每個字符都有一個獨一無二的Unicode碼

字母和數字占1個字節,漢字占2個字節

string類型的數據在使用過程中,要用""或''引起來

特殊字符需要轉義,稱為轉義字符(字符串中具有特殊功能的字符)

如果在字符串中包含了和js語法沖突的','等,都要用\轉義為普通字符

? 轉義字符 ? ? ? ? ?表現(輸出)形式

? ?\n ? ? ? ? ? ? ?? 一個換行

? ? \t ? ? ? ? ?? ? ? 制表符

? ? \\ ? ? ? ? ? ? ? ? ? \

? ? \" ? ? ? ? ? ? ? ? ? ''

? ? \' ? ? ? ? ? ? ? ? ? '

例:var str= '你\n好';

? ? 路徑:所有操作系統都支持/斜線,所以保存路徑時要將\換成/:

var n=str.charCodeAt(i);? //查看字符串str中下標i位置字符的unicode號

String.fromCharCode(unicode號)? ? //將unicode號,反向轉回文字,一次只能轉一個字,要用循環

var m=n.toString(2);? ?? //將n中的數值轉換為二進制形式

parseInt(10000000000,2);??//把二進制數轉換成十進制

var str=x.toString();? ? //將 x 轉為字符串類型,不改變原值x。x為數組時,結果str用,分隔

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? x不能是null或undefined ———?不是萬能

var str=String(x);? ? ? ? //將x轉為字符串類型———萬能(首選)

? ③boolean類型

作為條件的結果,來表示肯定(真)或否定(假)

何時: 只要作為判斷條件的結論時,就用boolean類型

取值:true:真(肯定)

? ? ? false:假 (否定)

例:var xxx=true;

該類型數據可以參與到數字的運算中:true = 1 ??false = 0

? ④undefined /⑤null

undefined:空,由程序自動為一個變量初始化之用;表示一個聲明后未賦值的變量、沒有返回值的函數

null:空,讓程序員用于手動清空一個變量之用,表示一個空地址

第二章*****************************************************************************************

x:任何數據

str:字符串

num:數字

數據類型轉換:(凡是從頁面上獲得的都是字符串)

作用:將不需要的數據類型,轉化為需要的數據類型

js四大特點:弱類型的3大特點:

?????1. 聲明變量時,不需要提前規定變量中存儲的數據類型

?????2. 同一個變量先后可保存不同類型的數據

?????3. js會根據自身的需要,隱式轉換數據的類型

何時:只要給定的數據類型不是想要的,都要轉換

方法有2種:

1、隱式轉換: 不需要程序員干預,由js自動完成的數據類型轉換

??? 何時: 只要給定的數據類型和js運算要求的類型不相符,js都會自動轉化數據類型,再運行

? ? 如何:每種運算中都自帶隱式轉換

? ? ? ? ? 比如: 算數計算中

規則:

? ? ①默認:一切都轉為number類型,再做計算

? ? 為什么: 因為number類型最適合計算

? ? ? ? bool: true->1 ? ? ?false->0

? ? ②特殊:+運算中,只要碰到一個字符串,一切都轉為字符串,+運算變為字符串拼接

若字符串左邊有變量,先計算變量,從左到右依次計算(按優先級),到字符串的位置后,都轉化為字符串

2. 強制轉換:程序員主動調用轉換函數實現的類型轉換(3種情況)

??? 何時: 只要給定的數據類型不是想要的,且自動轉換的結果也不是想要的,就要強制轉換

console.log(typeof x); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*輸出str的數據類型*/

_______________________________________________________________________________________________

其他類型轉number: 2種:

1. Number(x): 將純數字x字符串或bool轉為number類型(不直接修改原變量的值,而是返回新值)

x=Number(x); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? /*用于隱式轉換中自動調用*/

? ? 何時: 都是隱式轉換,其實相當于自動調用Number(x),很少主動使用

? ? 問題: 只能轉換純數字組成的字符串和bool類型

? ? 如果轉不了: 就返回NaN

? ?NaN: 代表一切不是一個數字的任何值:Not a Number

? ? NaN參與任何運算結果只能是NaN

2. parseFloat/parseInt(str):?將字符串str轉為number類型,可去除結尾非數字字符,但不去掉開頭的,因為表達式從左到右依次執行,所以可以在計算后直接加個單位(首選parseFloat)

? ? parseFloat可保留小數部分

? ? parseInt? 去掉小數部分(向下取整)? ? ?? //當使用e作為計數符號時,也會去掉e符號

? ? 何時: 只要將字符串轉number,首選parseFloat(),Number()太局限

? ? ? ? ? 如果確實需要去掉小數,才選parseInt

? ? ? ? ? 如果轉不了,也返回NaN

強調: 參數應該是string類型,如果給定的值不是string類型,則先執行隱式轉換,轉為string類型,再轉number

? ? ? Number/parseFloat/parseInt 都會自動去掉空格

特殊:

parseFloat("true") ?->NaN

Number(true) ?->1

Number("") ?->0

Number(null) ->0

Number(undefined) ->NaN

其他類型轉string: 2種:

1.var str=x.toString() ?將 x 轉為字符串類型,并返回結果。x為數組時,用,分隔

? ? x不能是null或undefined ———?不是萬能

2.var str=String(x)?將x轉為字符串類型——萬能(首選)

? ? 其實,隱式轉為string時,都是程序自動調用String

其他類型轉Boolean類型: 1種

Boolean(x)

? ? 規則: 只有5個值會被轉為false:0? ""? NaN? null? undefined

? ? ? ? ? 其余都轉為true

? ? 其實, 隱式轉為bool時,都是程序自動調用Boolean(x)

_______________________________________________________________________________________________

運算符和表達式

程序: 人的想法在計算機中的執行

運算符: 程序中模擬人的想法的特殊符號

表達式: 由數據,變量和運算符組成的完成一項單一任務的語句

算數運算: + , - , * , / , %

%: 模運算/取余數: 被除數/除數,不要商,要除不盡的余數部分(取零頭)

? 何時: 1. 取余數,可限制一個結果不超過指定的最大值

? ? ? ? 2. 判斷能否整除

? ? ? ? ?? 判斷偶數: 能被2整除 n%2==0

? ? ? ? ?? 判斷奇數: 不能被2整除 n%2!=0

隱式轉換

默認:都轉number

特殊:+運算中,碰到字符串,都轉字符串,+運算變為字符串拼接(在外面套一個parseFloat)

? ? ?字符串左邊的變量會先進行計算,遇到字符串全部轉為字符串(按優先級,從左到右)

? ? ?true在計算中為1,false為0;在字符串中為true/false

舍入誤差: 計算機中,也有計算不盡的數值(如0.3-0.1, 0.1*3),一般是浮點型

解決:

1. 按指定位數四舍五入: n.toFixed(2)

?? 今后幾乎所有顯示金錢數的地方都要toFixed(2)

2. 存儲: 保存很長位數的小數: 0.39999999

關系運算: 用兩個值做比較,做判斷(若試圖比較未定義的變量,會報錯)

包括:>? <? >=? <=? ==? !=

返回值: bool 類型的true/fasle

隱式轉換:默認都轉為 number

特殊:1. 兩個值都是字符串, 則不再轉數字,而是依次比較兩個字符串的每個字符unicode號

? ? ? ? 一個是字符串,一個是number,會進行隱式轉換

? ?? 2. 判斷NaN:NaN和任何值做> < >= <= ==5種比較時,永遠false

? ? ? ? ? ? ? ? ?NaN和任何值做!=比較時,永遠是true

? ? ?? 問題:NaN==NaN ?=>false 用普通的==無法判斷NaN

? ? ?? 解決:isNaN(num) 專門代替==,用來判斷num是不是NaN

? ? ?? 何時: 只要判斷是不是NaN,都用isNaN(num)函數

? ? ?? 反用: 判斷一個值是不是數字:!isNaN(num),若是數字,則返回true

? ? ? ?注意:?空字符串、純數字的字符串返回false(不是NaN)

? ?? 3. 區分null和undefined

?????? 問題:==比較時,會自動將undefined隱式轉為null

? ? ? ? ? ?? null==undefined ? ?=> null=null

?????? 解決:=== 全等: 類型必須先相同,值再相等(!==,不全等同理)

? ? ? ? ? ? ?其實===就是不帶隱式轉換的==

總結:

= 賦值,只有=可以改變變量中的值

== 自帶隱式轉換作比較

=== 不帶隱式轉換作比較

注意: 兩個對象作比較,不做任何轉換,直接比較兩個對象的地址值(判斷兩個變量是否引用同一個對象)

邏輯運算: 將多個關系運算,綜合起來得到最終結論

何時: 只要根據多個條件,綜合得出最終結論時

包括:&&與(而且) ? ||或(要么) ? !非(沒有)

條件1&&條件2...:

? ? 要求所有條件都為true,結果為true

? ? 只要一個條件為false,結果為false

條件1||條件2...:

? ? 只要一個條件為true,結果為true

? ? 除非所有條件都為false,結果才為false

!條件: 顛倒 條件的 判斷結果

隱式轉換: 默認將每個條件都轉為bool類型

短路邏輯: 如果前一個條件已經可以得出最終結論,則后續條件不再執行

???? &&: 只有前一個條件為false時,后續條件才不執行

???? ||: 只要前一個條件為true時,后續條件不再執行

利用短路:①簡單分支結構: 1個條件,1件事,只有滿足才做

? ? ? ? ? ? 如何: 條件&&(操作) ? (最簡單的條件判斷語句,注意加())

? ? ? ? ? ②利用||選擇默認值,如果給定的值有效,則使用給定的值,否則使用默認值代替

? ? ? ? ? ? 如何:給定值||默認值

? ? ? ? ? ? 無效:只要給定的值為0 "" NaN null undefined

注意:如果邏輯運算最后執行的是一個關系運算,則返回bool

? ??如果邏輯運算最后執行的是一個值,則返回值,而不返回bool

_______________________________________________________________________________________________

位運算: 了解

用二進制簡化普通十進制的計算或操作

1. 左移/右移:

m<<n ?m左移n位,相當于m*2的n次方

m>>n ?m右移n位,相當于m/2的n次方

? ? 1<<3=1*23=8

? ? 2<<3=2*23=16

? ? 8>>3=8/23=1

2. 取整:

? ? n^0?? n|0?? n>>>0 ? ? ? ? 代替/簡化Math.floor(n),用來把n向下取整(^ 按位異或)

3. 交換兩變量的值:

? ? var a=3,b=5;

? ?? 方法一: var t=b; b=a; a=t;

? ?? 方法二:a+=b; b=a-b; a-=b;

? ?? 方法三:a^=b; b^=a; a^=b;(二、三只能交換number類型的數據)

? ? ?方法四:?a=a+b; b=a-b; a=a-b;

賦值運算:

?????擴展賦值運算: 對特殊賦值運算的簡化

? ? ?何時:只要取出變量中的值,計算后,再存回原變量中

? ? ?a=a+b 將a的值+b的值,再存回a中

?????將b的值累加到a上:可簡寫為a+=b

? ? a=a+b ?-> ?a+=b;

??? a=a-b ?-> ?a-=b;

??? a=a*b ?-> ?a*=b;

??? a=a/b ?-> ?a/=b;

??? a=a%b ?-> ?a%=b;

? 更簡化: 遞增遞減運算: 如果每次累加1/累減1

??? a+=1? ->? a++

??? a-=1? ->? a--

前++和后++

1. 如果單獨使用, 前后都一樣

2. 如果參與到其他表達式中時:

?? 相同:變量中的值一定都會變化,+1

?? 不同: 前++,使用返回+1后的 新值去運算

? ? ? ? ?后++,使用返回+1前的 舊值去運算

注意:所有表達式都從左到右依次執行;先執行的操作會影響后續操作

函數中: return i++; ? ?返回+1前的 舊值去運算

注意: ++a并不總和a=a+1完全一樣,++運算符不會進行字符串連接操作,它會先將操作數轉換為數字并增1

比如: var a="1"; ? ?++a為2, ?a+1為字符串"11"

第三章*****************************************************************************************

一、函數類型

定義: 內存中封裝一項任務步驟清單的代碼段,再起一個名字

為什么:代碼重用、劃分功能

何時: 只要一段代碼,可能被反復使用,就都要先封裝在函數中,再反復調用函數

如何: 分2步

1、聲明(兩種方法)

①function函數名(參數變量列表){ ? ? /*形參*/ /*function創建函數*/

? ? ?函數體(代碼段);

? ? ?return 返回值; ? ? ? ? ? ? ? ? /*返回值要接住,再輸出才能顯示*/

? ?}

② 函數名=function(參數變量列表){

? ? ?函數體(代碼段);

? ? ?return 返回值;

? ?}

參數: 函數運行時,接收傳入函數的數據的變量。參數用法和普通變量完全一樣,只不過不用var聲明

參數列表: 多個參數間用逗號分隔(參數變量1,參數變量2...)

? 何時:若一項任務必須某些數據才能正常執行時,就必須定義參數

? 作用:①提醒調用者正確使用函數;②讓函數變得更靈活

? 返回值: 函數執行的結果(由是否需要返回結果決定是否返回值)

? ? ? ?何時: 如果函數的調用者需要獲得函數執行結果

? ? ? ?如何返回: return 返回值;

? ? ? ?作用:①return可單獨使用: 退出函數;②退出函數時,順便返回結果

? ? ? ?如果沒有返回值的函數,就會默認返回undefined

2、調用: 讓引擎按照函數的步驟清單,執行任務

var 返回值=函數名(參數值列表);

或 ?函數名(參數值列表); ? ? ? ? ? ? ? ? ? /*實參*/

何時: 函數只有調用才執行,不調用不執行

參數值列表: 傳入函數的執行時必須的數據列表

? 只要函數定義時規定了參數變量,調用時都要傳入參數值,且順序和個數保持一致

? 每個參數值之間用逗號分隔

_______________________________________________________________________________________________

作用域scope: 一個變量的可用范圍

為什么:避免不同范圍的變量之間互相污染(注意執行順序)

包括: 2種:

1.全局作用域: window(保存著全局變量)

什么是: 程序中的任何位置都可以訪問的范圍

? ? ?全局變量: 保存在全局作用域中,程序任何位置都可使用的變量

? ? ? 特點:隨處可用,可反復使用

? ? ? 何時: 如果一個變量需要反復使用,或跨函數隨處可用時,只要不屬于任何函數的變量,都是全局的

? ? ? 用法:console.log(變量名);

2.函數作用域:(保存著局部變量)

什么是: 僅函數內可用的范圍

? ? ?局部變量: 保存在函數作用域中,僅函數內可用的變量

? ? ? 特點:僅在函數內可用,不可重用

? ? ? 何時: 如果只限于當前函數內使用,函數外不可用時

? ? ? 如何:1.函數的參數變量

? ? ? ? ? ? 2.在函數內用 var 聲明的變量

總結: 優先定義并使用局部變量

? ? ? 盡量少使用全局變量——避免被污染

變量的使用順序:優先使用函數內的局部變量,局部沒有才去全局找

聲明提前(hoist,提起):

什么是: 在開始執行程序前,引擎會將var聲明的變量和function聲明的函數,提前到"當前作用域"頂部集中優先創建,再開始執行程序 ? ? ? ? ?? /*但是賦值留在原地?*/

筆試: 如果先使用,后聲明,一定在考聲明提前,就要將所有var和function提前到當前作用域的頂部,先創建,再判斷程序的輸出

問題: 破壞了程序默認的執行順序

解決: ①傳統: 強烈建議將所有的聲明都集中在當前作用域頂部

? ? ? ②ES6: let代替var聲明變量

? ? ? ? ? ? ? let禁止在聲明之前,提前使用該變量,強制將聲明集中在當前作用域頂部創建

? ? ? ? ? ? ? 限制:不能用let反復創建相同名稱的變量

函數聲明:

?var/let 函數名=function(參數變量列表){...}?? /*用這種方式創建的函數不會被聲明提前*/

? 本質: 函數名其實僅是一個普通的變量

? ? ? ? 函數其實是保存代碼段的引用類型的對象

? ? ? ? 函數名通過函數對象的地址引用著函數對象

按值傳遞:

什么是:兩變量間賦值,或將變量傳入函數作為參數時,其實只是將原變量中的值復制一個副本給對方

結果:原始類型的值會 修改新變量,不影響原變量的值

_______________________________________________________________________________________________

2. 全局函數(了解)

什么是: ES標準中規定的,瀏覽器已經實現的,不需要任何對象(前綴.)就可直接調用的函數

比如: String()/Number()/Boolean()

? ? ? parseInt/parseFloat()

? ? ? isNaN()/encodeURI/decodeURI

反例(省略了前綴,屬于BOM): alert()/prompt()...

編碼解碼: 特指對地址欄中的url內容進行編碼和解碼

什么是編碼: 將url中多字節字符或保留字符編碼為單字節字符

? 為什么: url中不允許出現多字節字符以及和保留字符沖突的字符,否則會亂碼

? 何時: 只要url中可能包含多字節字符以及和保留字沖突的字符時,都要先編碼為單字節

什么是解碼:將編碼后的單字節字符串解碼回多字節原文

何時:只要收到的是編碼后的字符串,都要先解碼再使用

如何:編碼: var code=encodeURI(url);

? ? ?解碼: var url=decodeURI(code);

問題: 不能對保留字符編碼解碼,比如: ?: ?/

解決:編碼: var code=encodeURIComponent(url);

? ? ?解碼: var url=decodeURIComponent(code);

注意: 不會對ASCII字母和數字進行編碼,也不會對ASCII標點符號進行編碼:? - _ . ! ~ * ' ( ) 。

其他字符(比如: ;/?:@&=+$,# 這些用于分隔URI組件的標點符號),都是由一個或多個十六進制的轉義序列替換的

eval函數: 執行一段字符串格式的js表達式

eval()的作用

把字符串參數解析成js代碼并運行,并返回執行的結果

eval的作用域:

作用域在它所有的范圍內有效,但是IE8及以下指向window(全局)

解決方法:

functiona(){

? if(window.execScript){ ? ? ?? // 支持IE8及以下的版本

? ? window.execScript("var x=1");

? }else{?window.eval("var x=1"); }? ? ? ?//常用的瀏覽器都支持

? ? console.log(x);

? }

? a();

? console.log(x);

execScript與eval區別:

相同點:

execScript與eval都可以接收一個字符串,若該字符串是表達式(expression),則執行時將求得該表達式的值并返回;若該字符串是一個或多個語句(statements),則執行時將運行這些語句

不同點:

① execScript是IE瀏覽器獨有;eval則是所有瀏覽器都支持

② execScript無論是在什么作用域(global/local)內被調用,它所接受到的表達式(expression)或語句(statements)字符串都將在全局作用域內執行(global);eval則是在它被調用時所在的作用域內運行它所接受到的表達式(expression)或語句(statements)字符串

在不支持execScript函數的瀏覽器下實現在全局作用內執行字符串

function globalEval(data){

? if(data){

? ?(window.execScript || function(data){?window["eval"].call(window, data);?})(data);

? }

}

_______________________________________________________________________________________________

程序三大結構: 順序(判斷,不循環),分支和循環

1、分支結構

什么是: 讓程序根據不同的條件執行不同的操作

何時: 只要讓程序根據不同的條件執行不同的操作

如何:

1. 一個條件,一件事,滿足就執行,不滿足就不執行

? 如果操作簡單: 短路:條件&&(操作1,操作2,操作3...)

? 如果操作復雜:?

if(條件){

? 操作1;

? 操作2;

? ...

}

2. 一個條件,二件事,二選一執行:

? 如果僅兩個值二選一:

條件?值1:值2

? 如果操作簡單: 三目運算/三元運算/條件運算(三目運算符的優先級低于+)

條件?操作1:操作2 ? ? ? ? ?/*滿足條件執行并返回操作1的值,不滿足則執行并返回操作2的值*/

? 如果操作復雜:

if(條件){

? 操作1; ? ? ? ? ? ? ? ? ? ? ? /*滿足條件執行*/

}else{

? 操作2; ? ? ? ? ? ? ? ? ? ? ?/*不滿足條件執行*/

}

3. 多個條件,多件事,多選一執行(嵌套)

如果多個值,多選一: 三目運算(一般對齊)

? ? 條件1?值1:

? ? 條件2?值2:

? ? ? ...?... :

? ? 默認值 ? ? ? ? ? ? ? ? ? ? ? ? ? /*強調: 默認值不能省略*/

如果操作簡單: 三目運算

? ? 條件1?操作1:

? ? 條件2?操作2:

? ? ? ...?... :

? ? 默認操作? ? ? ? ? ? ? ? ? ? ?? /*強調:默認操作不能省略*/

如果操作復雜:if...else if結構

if(條件1){

? ? 操作1 ? ? ? ? ? ? ? ? ? ?? /*如果當前條件滿足,則不再向后執行*/

}else if(條件2){ ? ? ? ? ? ? ? ?/*如果進入條件2,暗示條件1不滿足*/

? ? 操作2

}else if(...){

? ? ...

}else{ ? ? ? ? ? ? ? ? ? ? /*如果沒有默認操作,則else可省略,即什么也不做*/

? ? 默認操作

}

簡寫:如果if(...)一句話 ? ?else(...)一句話 ? ?后面只有一句話,可省略{}(if、else仍然要寫)

特殊: 如果所有條件都是等于比較,可簡寫為

switch(表達式){ ? ? ? ? /*先計算表達式的值,用表達式的值和每個case后的值做"全等==="比較*/

? case 值1: ? ? ? ? ? ? /*如果表達式的值全等于case后的值1*/

? 操作1; ? ? ? ? ? ? ? /*就執行操作1*/

? case 值2:

? 操作2;

? ...

? default: ? ? ? ? ? ? ?/*如果所有case的值都不等于表達式的值*/

? 默認操作; ? ? ? ? ?? /*則執行默認操作*/

} ? ? ? ? ? ? ? ? ? ? ? /*強調: 最后一個default可省略*/

問題: 只要前一個case滿足條件,則后續所有case都被執行(而不會再判斷)

原因: switch是入口

解決: break;可終止當前結構繼續向后執行,并退出switch

如何:每個case之間,都要加break;

判斷一個值是否為空可以直接用if(值){ },不加等號,判斷是否為true

第四章*****************************************************************************************

2、循環loop

什么是: 讓程序反復執行相同的代碼段

何時: 只要讓程序反復執行同一段代碼

如何: 三要素:

? 1. 循環條件: 讓循環可以繼續執行的條件(只要條件滿足就反復執行循環,直到不滿足時退出循環)

? 2. 循環變量: 在循環條件中用作比較和判斷的變量

????? 從幾開始, 每次遞增/遞減幾,到幾結束

? 3. 循環體: 循環要反復執行的代碼段

????? 幾乎都要修改循環變量,直到不滿足條件;若循環條件始終為true,則循環永遠無法退出---死循環

包括: 3種:

while:

var 循環變量=初始值; ? ? ? ? ? ? /*聲明并初始化循環變量*/

while(循環條件){ ? ? ? ? ? ? ? ? ?/*當滿足循環條件時*/

? 循環體;

? 修改循環變量;

}

? 何時: 必須先滿足循環條件,才能執行循環體時

do...while:

var 循環變量=初始值;

do{

? 循環體;

? 修改循環變量;

}while(循環條件); ? ? ? ? ? ? ? ?/*當滿足循環條件時*/

? 何時: 即使條件不滿足,也至少可以執行一次時(先執行,再判斷)

while VS do...while

如果第一次循環都滿足,兩者的輸出是完全一樣的

? while: 先驗證條件后執行

? do...while: 先執行一次,再驗證條件

如果第一次條件不滿足,則while是一次都不執行,do while至少執行一次

for:

for(var 循環變量=初始值;循環條件;修改循環變量){

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? //循環條件中有,時(逗號表達式),以最后一個為準

? 循環體; ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*先執行循環體,再修改循環變量*/

}

for循環和while循環的原理是完全一樣的(就是while循環的簡化)

for vs while: 如果循環變量的變化有規律: 首先for

? ? ? ? ? ? ? 如果循環變量的變化沒有規律: 首先while

強調:JavaScript中沒有塊級作用域

放在if/else if/else/for/while中的變量,出了塊(結構),依然可用

c、c++、java等所有{}都認為是塊級作用域,塊中的變量出了塊,不能使用

解決: 讓循環中的變量不要泄露到循環外

? ? ? 用let代替var: let聲明的變量僅能在{}內使用

簡寫:var 可同時聲明并初始化多個變量,用,分隔

? ? ? 如果for循環下只有一句語句,可省略{}—————不建議,容易出歧義

? ? ? 如果for循環體中只有一句話,且很簡單時,for循環的修改循環變量中可先后執行多個短小的操作,每個操作之間用逗號(,)分隔,省略循環體并加分號(;)結束——但不能改變原來的執行順序

_______________________________________________________________________________________________

break(中斷)?VS?continue(跳過):

break: 中斷并退出當前循環

?? 何時: 當判斷條件非常復雜時,就可用死循環+break的方式靈活控制循環退出——降低循環編寫的難度

continue: 跳過本輪循環,繼續執行下一輪

?? 只要顛倒判斷條件,就可避免使用continue

強調:break不能參與到任何簡寫中,必須獨立一句

嵌套循環: 循環內,又執行了另一個循環

步驟: 1. 截取片段找規律

? ? ? 2. 用外層循環反復調用規律的公式

_______________________________________________________________________________________________

二、數組類型

什么是: 內存中連續存儲多個數據的一塊存儲空間,再起一個名字

為什么: 便于維護和查找

? ? 程序=數據結構+算法

??? 數據結構: 數據在內存中的存儲結構

??? 算法: 解決問題的步驟

??? 好的數據結構可極大提高程序的執行效率

何時: 今后只要保存多個同一類型的數據時,都必須用數組

如何: 3件事(創建、賦值、取值)

創建: 3種:

1.創建空數組2種:

?? 何時: 創建數組時,暫時不知道數組內容

? ? ? ? var arr=[]; ? ? ? ? ? ? ? ? /*[]創建數組*/

? ? ? ?var arr=new Array();

2. 創建數組同時初始化數組內容:

?? 何時: 創建數組時已知數組的內容

???????var arr=[值1,值2,...];

? ? ? ?var arr=new Array(值1,值2,...);

3. 創建n個空元素的數組(只有一種):

?? 何時: 創建數組時,只知道數組元素個數,暫時不知道數據的內容

? ? ?? var arr=new Array(n);?? //()里若只有一個數字,創建空數組,否則設置其為數組的內容

訪問:

? 元素:數據中每個數據,都稱為元素

? 下標(index): 每個元素的存儲位置的序號。默認都是數字,從0開始,連續不重復

賦值: 將數據保存到數組的某個元素中

? ? ?arr[i]=新值; ? ? ? ? ? ? ? ?/*i:下標index*/

取值: 數組中每個元素的用法和普通的變量完全一樣

? ? ? 數組也稱為一組變量的集合,起一個統一的變量名

? ? ?arr[i]

console.log(arr[i]); ? ? ? /*輸出數組下標為i的元素*/

console.dir(arr); ? ? ? ? /*查看內存中arr的結構和內容*/

dir問題:不會立刻輸出結果

? 只有手動點擊三角時,才動態查找內存中對象的最終結構,會打亂程序的輸出結果順序

解決: 如果想查看數組中間狀態的內容:

console.log(String(arr)); ? ? ? ? /*對數組拍照*/

js的數組三個不限制:

? 1. 不限制元素的數據類型

? 2. 不限制下標越界:

? ?? 賦值時越界: 不會報錯!在指定的新位置自動創建新元素保存新值(添加后,數組的元素下標不連續則稱為稀疏數組)

? ?? 取值時越界: 不會報錯! 僅返回undefined

? 3. 不限制元素個數:?在任何時候,在任何位置添加新元素

.length屬性: 記錄數組中理論上的元素個數(不一定和實際元素個數相符)

特點:.length 永遠等于最后一個數字下標+1(自動維護,不需要手動修改)

? ? ? .length 永遠指向最后一個元素的下一個新位置

.length可修改數組大小——縮容(如使arr.length=5,可獲取數組的前5個值)

用法注意:arr.length ? ? ? ? ? ? ? ? ?/*.length屬性屬于數組,不能脫離數組單獨使用*/

固定套路: 1. 獲取數組最后一個元素:arr[arr.length-1]

? ? ? ? ? 2. 獲得倒數第n個元素:arr[arr.length-n]

? ? ? ? ? 3. 末尾追加一個新元素:arr[arr.length]=新元素

? ? ? ? ? 4. 刪除數組最后一個元素(改小length) :arr.length-=1;

? ? ? ? ? 5. 刪除數組末尾倒數n個元素(改小length):arr.length-=n;

_______________________________________________________________________________________________

數組是引用類型的對象

原始類型的值: 修改新變量,不影響原變量—————按值傳遞

原始類型:基本數據類型:值直接保存在變量本地的數據類型,Number/String/Boolean/Undefined/null

? ? 原因:將原變量中的實際值復制一個副本給對方

引用類型的對象: 用新變量修改對象,等效于直接修改原對象。新舊變量都受影響(arr2=arr1)

引用類型:值無法直接保存在變量本地的復雜數據類型

? ? 原因:僅將原變量中的地址值復制給新變量,導致兩個對象共用同一個對象

? ? ? ? ? 新舊變量使用相同的地址值,引用同一個對象(地址值相同)

遍歷:

什么是: 依次對數組中每個元素執行相同的操作

何時: 只要對數組中每個元素執行相同的操作時

如何:循環

for(var i=0;i<arr.length;i++){

? ? arr[i]? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*當前元素*/

}

var i=0,len=arr.length; i<len; i++? ? ?//可使用緩存代替arr.length,減少延遲,提高性能

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內容