JS筆記

js基礎

js引入方式

  • 行內式:經過向 html 元素行內添加一些 js 代碼,如給 div 綁定點擊事件
<div onclick="alert('這是js代碼')">這是一個div</div>
複製代碼
  • 內嵌式:在 html 文檔中寫一個 script 標籤,把咱們的 js 寫在 script 標籤內
<script> alert('這是內嵌式js代碼') </script>
複製代碼
  • 外鏈式:在 html 文檔中寫一個 script 標籤,而且設置 src 屬性,src 的屬性值引用一個 js 文件資源,而 js 代碼寫在 js 文件中

使用外鏈式引入 js 文件時,script 標籤裏面不能再寫 js 代碼了,即便寫了也不會執行。javascript

<script src="js/1.js"></script>
複製代碼

不管是內嵌式仍是外鏈式,都建議把 script 標籤寫在 body 結束標籤的前面。css

1、 淺談前端發展史

第一階段:C/S (client server) -> B / S (browser server)網頁製做
技術棧:PhotoShop、HTML、CSShtml

第二階段:從靜態到動態,從後端到前端 前端開發工程師
先後端分離:
後端:完成數據的分析和業務邏輯的編寫(包含API接口編寫)
前端:網頁製做、JS交互效果、數據的交互和綁定
技術棧:JavaScript 、 Ajax(跨域技術)、jQuery ...
第三階段:從前端到全端(從PC端到移動端)
技術棧:H五、CSS三、響應式佈局開發,Zepto、Hybrid(混合app開發)微信小程序...前端

第四階段:從全端到全棧
全棧開發:先後端均可以開發(嚴格意義講,一種語言完成前段後開發)
技術棧:NODE(基於js編程語言開發服務器端程序)、Express/Koa...vue


2、關於瀏覽器的內核和引擎

Webkit(v8引擎):大部分瀏覽器
Gecko:火狐
Trident:IE
...java

W3C:萬維網聯盟,制定編程語言的規範與標準
開發者按照規範編寫代碼,瀏覽器開發商也會開發一套按照規範把代碼渲染成頁面的東西(這個東西就是內核或者引擎)node

瀏覽器內核的做用:按照必定的規範,把代碼基於GPU(顯卡)繪製出對應的圖形和頁面等;react

爲啥會出現瀏覽器兼容:
面試

  1. 部分瀏覽器會提早開發一些更好的功能,後期這些功能會被收錄到 W3C 規範中,可是在收錄以前,會存在必定的兼容性
  2. 各個瀏覽器廠商,爲了突出本身的獨特性,用其餘方法實現 W3C 規範中的功能
    ...

3、JavaScript

JS:輕量級的客戶端腳本編程語言編程

  1. 編程語言
    HTML + CSS 是標記語言
    編程語言是具有必定邏輯的,擁有本身的編程思想(面向對象【oop】、面向過程編程)
  • 面向對象
    • C++
    • JAVA
    • PHP
    • C#
    • JS
    • ...
  • 面向過程:
    • C

2.目前的 JS 已經不是客戶端語言了,基於 NODE 能夠作服務器端程序,因此 JS 是全棧編程語言

  1. 學習 JS,咱們學習它的幾部分組成
  • ECMAScript(ES):js的核心語法
  • DOM: Document Object Model文檔對象模型,提供各類API(屬性和方法)讓 JS 能夠獲取或者操做頁面中的HTML元素(DOM和元素)
  • BOM:Browser Object Model 瀏覽器對象模型,提供各類 API 讓 js 能夠操做瀏覽器

4、ECMAScript

它是 JS 的語法規範,JS 中的變量、數據類型、語法規範、操做語句,設計模式等等都是 ES 規定的;

值得注意的是 js 的註釋方式:註釋是一項備註內容,給人看的,代碼執行時會忽略註釋內容。

  • 單行註釋: // 兩個單斜線
  • 多行註釋:/多行註釋內容寫在兩個星號之間__/

5、變量(variable)

它不是具體的值,只是一個用來存儲具體值的容器或者代名詞,由於它存儲的值能夠改變,因此稱爲變量。

基於 ES 語法規範,在 JS 中建立變量有如下方式:

  • var(ES3)
  • function (ES3)建立函數(函數名也是變量,只不過存儲的值是函數類型而已)
  • let (ES6)聲明變量
  • const (ES6)建立常量(常量就是恆定不變的值,如光速就是常量)
  • import (ES6)基於ES6的模塊處處規範導出須要的信息
  • class (ES6) 基於ES6建立 類
/* * 語法: * var 變量名 = 值 * let 變量名 = 值 * const 變量名 = 值 * function 函數名 () { * // 函數體 * } */
var n = 13;
n = 15;
alert(n + 10); // => 彈出來25 此時的 N 表明15

const m = 100;
m = 200; // Uncaught TypeError: Assignment to constant variable (常量存儲的值不能被修改,可以被修改的就是變量了)
複製代碼

建立變量,命名的時候要遵循一些規範

  • 嚴格區分大小寫
  • 遵循駝峯命名法:按照數字、字母、下劃線或者$來命名(數字不能做爲開頭),命名的時候基於英文單詞拼接成一個名字(第一個單詞字母小寫,其他每個有意義單詞的首字母都大寫)
  • 不能使用關鍵字和保留字:在 js 中有特殊含義的叫作關鍵字,將來均可能成爲關鍵字的叫作保留字
var n = 12;
var N = 12; // 變量 n 和變量 N 不是同一個變量
var studentInfo = 'xyz'; // 駝峯命名法

// 變量要具備語義化
add / create / insert
del (delete) / update / remove(rm)
info / detail
log
複製代碼

6、數據類型

數據類型是一門語言進行生產的材料,JS 中包含的值有如下這些類型:

  • 基本類型:
    • 數字 number
    • 字符串 string
    • 布爾 boolean
    • null
    • undefined
    • Symbol 表示一個惟一值(ES6新增)
  • 引用數據類型:
    • 對象object
      • 普通對象
      • 數組對象
      • 正則對象
      • 日期對象
      • ...
    • 函數function
// [基本數據類型]
var n = 13; // => 0 1 -13 13.2都是數字, 此時變量 n 存儲的就是一個數字;數字中有一個特殊的值:NaN(not a number),表示不是一個有效的數字,可是仍然是一個數字類型

var s = ''; // =>如 '' '13' "13" "name" "age" JS 中全部用單引號或者雙引號包裹起來的都是字符串,字符串表示的值是當前引號中包裹的值(一個字符串由零到多個字符串組成)

var b = true; // => 布爾類型只有兩個值 true 真 false 表示假

var empty = null; // => 變量 empty 表示 null 空

var notDefined = undefined; // 變量 notDefined 表示 undefined(undefined 這個單詞的意思就是未定義);

// Symbol: 用來建立一個惟一值,和誰都不會重複。下面等號右側雖然長的同樣,可是 s1 和 s2 變量表明兩個不一樣的值。
var s1 = Symbol('珠峯');
var s2 = Symbol('珠峯');

// [引用數據類型]
// => 對象
var obj = {name: '珠峯培訓', age: 9}; // => 普通對象:由大括號包裹起來,裏面包含多組屬性名和屬性值(name 和 age 叫作屬性名(又稱鍵,英文名 key),而 '珠峯培訓'/9叫作屬性值(又稱值,英文名 value),因此對象又叫作鍵值對集合或者key/value集合)
var obj2 = {}; // => 變量 obj2 表示空對象;

// => 數組
var ary = [1, 2, 3, 4, 5]; // => 數組對象:用中括號包裹起來,包含0到多項內容,每一項之間用逗號(英文逗號)分隔。
var ary2 = []; // => 變量 ary2 表示一個空數組

// => 正則:用來匹配字符串的規則
var reg = /^abc$/;  // => 兩個斜線中間的叫作元字符

// => 函數:須要屢次重複使用的代碼或者有特定功能的代碼能夠封裝成一個函數;
function fn () {// => 函數體}
// function 叫作關鍵字,用於聲明函數變量
// fn 叫作函數名,函數名也須要知足變量聲明的條件(本質上函數名也是變量名,只不過這個變量名錶明的是一個函數數據類型的值)
// () 【聲明函數時】fn後面的這個小括號表示的是形參入口
// {} 寫在函數中的 {} 表示函數體,這裏面寫須要執行的代碼

// ....
複製代碼

7、JS代碼運行及經常使用輸出方式

  • alert方法(函數): 在瀏覽器中經過彈窗的方式輸出(瀏覽器提示框)
var num = 12;
alert(num); // alert() 讀做:alert方法執行【寫在方法名後面的「()」讀做 「執行」 ,就是把alert函數裏面的代碼執行一遍】。把想輸出的東西放在小括號裏;

var course = '珠峯培訓js基礎課程';
alert(course);
複製代碼
  • console.log方法:在瀏覽器控制檯輸出日誌。console是瀏覽器的開發者工具的一個頁卡(在瀏覽器中按下F12按鍵【部分電腦須要按下Fn和F12】)
// console.log() 讀做 console.log 方法執行,把想要輸出的變量或者內容放在小括號裏。
var name = '珠峯培訓-馬賓';
console.log(name);
複製代碼
  • innerHTML/innerText屬性; 修改元素中的 HTML 或者文本;
var box = document.getElementById('box'); // => 在document(整個HTML文檔中)下面查找 id 爲 box 的元素。

// 語法:元素對象.innerHTML/innerText = '想要顯示的內容'; 【想要顯示的內容必須是一個字符串類型的值】
box.innerHTML = '<h1>珠峯培訓js基礎課程第一週</h1>';
box.innerText = '<h1>珠峯培訓js基礎課程第一週</h1>';

// box.innerHTML/box.innerText = '字符串' 讀做:將 box 的 innerHTML 或 innerText 修改成 '字符串'

// => 咱們發現一樣是包在字符串裏面的內容,經過 innerHTML 的方式瀏覽器會將<h1>識別成 HTML 內容;可是 innerText 不能識別,而是你字符串裏面寫什麼,頁面就輸出什麼;
複製代碼

8、有效數字檢測、數據類型轉換、數據類型檢測

有效數字檢測

  1. 有效數字檢測 isNaN() 方法;非有效數字:NaN(not a number)

isNaN(須要檢測的值):檢測當前是不是一個有效數字,若是是一個有效數字,isNaN執行後就會獲得一個 false,不然 isNaN 執行後獲得一個 true;(咱們獲得的這個 false 或者 true 稱爲 isNaN 函數的返回值【就「結果」的意思】)
語法:isNaN(須要檢測的值)

var num = 12;
 var result1 = isNaN(12); // -> 檢測 num 變量存儲的值是否爲非有效數字,12是數字,因此 isNaN 執行後獲得一個 false;
 var result2 = isNaN('13'); // -> false
 var result3 = isNaN('珠峯'); // -> true 由於漢字不是數字
 var result4 = isNaN(false); // -> false
 var result5 = isNaN(null); // -> false;
 var result6 = isNaN(undefined); // -> true
 var result7 = isNaN({name: '珠峯培訓'}); // -> true
 var result8 = isNaN([12, 23]); // -> true
 var result9 = isNaN([12]); // -> false
 var result10 = isNaN(/^$/); // -> true
 var result11 = isNaN(function () {}); // -> true
複製代碼

思考:爲啥小括號裏的不是數字也能獲得結果?這是isNaN的檢測機制:

一、首先驗證當前要檢測的值是否爲數字類型的,若是不是,瀏覽器會默認的把值轉換爲數字類型

把非數字類型的值轉換爲數字:
- 其餘基本類型轉換爲數字:內部隱式調用Number方法

Number(須要轉換的值); 是強制轉換
[字符串轉數字]:若是字符串裏面都是數字,那麼返回這個數字,若是有非數字的因素會返回NaN.
    Number('13') // -> 13
    Number('13px') // NaN 字符串中 px 不是數字
    Number('13.5') // 13.5 能夠識別小數點
[布爾值轉數字]
Number(true); // -> 1
Number(false); // -> 0

[nullundefined轉數字]
Number(null); // 0
Number(undefined); // NaN
複製代碼
  • 引用數據類型轉數字:先調用引用數據類型值的 toString 方法將引用數據類型轉化爲字符串,而後再將字符串轉換爲數字。
[對象轉數字]
Number({}) // NaN; 其內部機制:({}).toString() -> '[object Object]' -> Number('[object Object]') -> NaN

[數組轉數字]
Number([12, 23]) // NaN; 內部機制:[12, 23].toString() -> '12, 23' -> Number('12, 23') -> NaN

[正則]
Number(/^\d$/) // NaN; 內部機制:/^\d$/.toString() -> '/^\d$/' -> Number('/^\d$/') -> NaN
複製代碼

二、當前檢測的值已是數字類型,是有效數字就獲得一個 false,不是就會獲得一個 true;(在數字類型中只有 NaN 不是有效數字,其他的都是有效數字)
Number(1); // false
Number(NaN); // true

三、NaN 的比較

NaN == NaN // 返回 false;( == 是比較運算符,一個等號是賦值)
這是由於什麼呢?由於 NaN 只是表示非數字,字符串 'a' 是非數字,'張三'也是非數字。可是 a 和 張三不相等。

if (Number(num) == NaN) {
    // if 是 js 中用來作判斷的語言結構,小括號裏表示條件,若是條件成立就執行花括號裏面的代碼
    alert('珠峯10年,專一前端');
}

// 上面花括號裏面的代碼永遠不會執行,由於 Number 方法獲得的結果只有兩種狀況,要麼是數字,要麼是 NaN。若是獲得一個數字,數字和 NaN 不相等,若是是 NaN,NaN 和 NaN 也不相等。
複製代碼

數據類型轉換(parseInt、parseFloat方法)

做用和 Number 方法類似,都是把非數字類型值轉換爲數字,區別在於 Number 方法是強制轉換,即要求被轉字符串中必須都是數字,若是不知足這一條件直接獲得 NaN,而 parseInt 和 parseFloat 則是非強制轉換。

parseInt:把一個字符串中的整數解析出來
parseFloat:把一個字符串中整數和小數包含小數點都解析出來

parseInt('13.5') // 13
parseFloat('13.5') // 13.5

parseInt('width: 13.5px'); // NaN
parseFloat('width: 13.5px'); // NaN

注意:不管是 parseInt 仍是 parseFloat 都是從字符串的最左邊開始查找有效數字,直到遇到第一個非有效數字字符就中止查找,若是第一個就不是有效數字,那麼直接回返回 NaN,而且中止查找。

數據類型檢測:

檢測數據類型一共有四種方式:

  • typeof
  • instanceof
  • constructor
  • Object.prototype.toString.call()

咱們這裏先講 typeof 運算符

語法:typeof 被檢測的值返回被檢測值的數據類型;

console.log(typeof 1); // number
console.log(typeof 'zhufengpeixun'); // string
console.log(typeof true); // boolean
console.log(typeof null); // object
console.log(typeof undefined); // undefined
console.log(typeof {}); // object
console.log(typeof []); // object
console.log(typeof /^/); // object

// 思考?typeof 運算符的返回值是個什麼數據類型?
var result = typeof 1;
console.log(typeof result); // string

// 面試題
console.log(typeof typeof 1); // string
複製代碼

typeof 是有侷限性的,檢測基本數據類型時,typeof 檢測 null 會返回 object,由於 null 是空對象指針。同時,typeof 檢測引用數據類型時,不能具體區分是哪種對象數據類型(對象、數組、正則等)只會統一返回object。

2-js基礎教程

1、普通對象

js中的普通對象:無序的鍵值對集合。

  • 由大括號包裹起來的{key: value}
  • 由零到多組屬性名和屬性值(鍵值對)組成。屬性名能夠是數字、字母、或者下劃線等,而且屬性名都是字符串類型的。

屬性是用來描述當前對象特徵的,屬性名是當前對象具有的特徵,屬性值是這個特徵的描述,一組屬性名和屬性值成爲一組鍵值對

聲明對象

var feTraining = {
    name: '珠峯培訓',
    age: 9,
    characters: '專一前端10年',
    9: 'age'
}
複製代碼

對象的操做:鍵值對的增刪改查

  • 獲取對象的某個屬性的值
    • 對象.屬性名
    • 對象['屬性名']
console.log(feTraining.name);
console.log(feTraining['name']);
var str = 'age';
console.log(feTraining[str]); // 9
複製代碼

若是用. 後面的屬性名不用寫引號,若是使用[],屬性名須要用字符串包裹
若是屬性名是數字,只能使用 []
方括號裏面還能夠寫變量或者表達式
若是獲取一個對象不存在的屬性,會獲得一個 undefined

  • 增長/修改
    js 對象中的屬性名是不容許重複的,是惟一的
    如給一個對象的屬性賦值,有兩種狀況:
    • 若是對象以前不存在這個屬性,那麼就是給這個對象增長一個屬性,值是等號右側的值
    • 若是對象以前已經存在這個屬性了,再賦值就是修改對象中的這個屬性的值
feTraining.courses = 'JS高級+vue+react+node'; // feTraining 以前不存在 courses 這個屬性,因此是增長;
console.log(feTraining);

feTraining.name = 'Everest Training'; // feTraining 以前就存在 name 屬性,因此是修改
console.log(feTraining);
複製代碼
  • 刪除

  • 完全刪除:把對象的屬性名和屬性值都刪除。 delete obj['name']

  • 軟刪除:將對象的某個屬性的值賦值爲null。 obj.name = null

delete feTraining.age;
console.log(feTraining);

feTraining.courses = null;
console.log(feTraining); // course 屬性名還在,只是值爲 null 了
複製代碼

思考?

var obj = {
    name: '珠峯培訓',
    age: 10
};
obj.name // '珠峯培訓'
obj['name'] // '珠峯培訓'
obj[name] ?? => name 和 'name'有什麼區別?'name' 表示的是一個字符串,而 name 表示一個變量名
複製代碼

對象中的屬性名都是字符串類型的


2、數組對象

數組是【有序】的鍵值對集合;可是數組的鍵是瀏覽器設置的,不須要咱們手動設置,而且鍵都是從0開始的數字,咱們稱數字屬性名爲【索引】。數組的第一項的對應的索引是0,第二項對應的索引是1,以此類推,第n項對應的索引是 n - 1。

var ary = [12, 23]; // ? 12和23是都是屬性值,屬性名呢?
console.log(ary); // 從控制檯能夠發現是有鍵的,而且鍵都是數字

數組的操做

數組的鍵是數字,因此只能用方括號的方式獲取、修改,並且寫在方括號裏面的屬性名不須要用引號包裹;

var ary = [12, 23];
console.log(ary[0]);
console.log(ary.0); // 報錯
console.log(ary[1]);
console.log(ary[2]); // 訪問一個數組不存在的索引,會獲得一個 undefined
複製代碼

3、基本數據類型和引用數據類型的區別

var a = 12;
var b = a;
b = 13;
console.log(a); // 12
console.log(b); // 13

var obj1 = {
  name: '珠峯',
  age: 10
};
var obj2 = obj1;
obj2.age = 100;
console.log(obj1.age); // 100
console.log(obj2.age); // 100
複製代碼

爲何會有這種狀況?

基本數據類型(也叫作值類型)的操做,直接操做就是這個值,意思就是說變量自己就表明這個值。因此: var b = a;  a存儲12這個值,而後聲明一個變量 b,而後讓b = a,就是讓b = 12。這樣和 var b = 12本質上沒有任何區別;

引用數據類型都是存放在堆內存空間中的,同時這個堆內存空間有一個十六進制的內存地址(例如aaafff000)。咱們在聲明一個變量存儲引用數據類型時,不是直接把對象賦值給變量,而是把對象的堆內存地址賦值給變量。因此 obj1 拿到的知識這個堆內存地址 aaafff000;
因此引用數據類型的操做不是直接操做的值,而是操做它的引用數據類型的堆內存地址。因此var obj2 = obj1; 只是把 obj1 表明的堆內存地址賦值給了變量 obj2。
因此 obj2.age = 100;是經過 obj2 的堆內存地址找到堆內存地址中的存儲的 age 的值,把它修改爲100。同時,咱們訪問 obj1.age 時也是先經過 obj1 存儲的堆內存地址找到內存空間,而後從裏面把屬性age的值取到,此時這個內存空間中的值已經修改爲100了。因此obj.age 也是100

4、布爾類型、布爾運算

布爾類型值只有兩個值,true 和 false;布爾運算用來測試真假值,即運算結果是真的仍是假的,一般結合 js 的判斷語句(if/switch-case/三元表達式)使用。

其餘數據類型和布爾值進行轉換

  • Boolean方法

語法:Boolean(須要轉換的值) ;獲得轉換後的規則

var boo = Boolean(1);
var boo2 = Boolean(0);
console.log(boo, boo2); // true false
複製代碼
  • !運算符(取反運算符)true 取反就是 false,而 false 取反就是 true

運算符是有固定功能的關鍵字或者符號。它經過操做值也能夠獲得返回結果,與方法不一樣的是運算符不須要小括號。
語法:!須要取反的值 ;獲得取反後的布爾值。其內部機制是先把其餘數據類型轉換成布爾值,而後再取反。
轉換規律:在 js 中只有 0/NaN/空字符串''/null/undefined 這5個值轉換成布爾值是 false,其他的都是 true。

var str = '珠峯培訓,10年專一前端';
var result = !str;
// 內部運做機制:
// 第一步先將str轉換成布爾值,str不屬於那5個值,因此 Boolean(str) => true
// 而後再取反,true 取反 => false
console.log(result); // false
複製代碼
  • !! 運算符 等效於 Boolean 方法

語法:!!須要轉換的值;

var num1 = !!1;
var num2 = !!0;
console.log(num1, num2); // true false

console.log(!!{}); // true
console.log(!![]); // true
console.log(!!{name: 'zhufeng'}); // true
複製代碼

5、null 和 undefined

null 空對象指針;不佔內存,通俗理解就是人爲的手動先賦值爲 null,後面程序中咱們會再給它賦值爲其餘值;

undefined 未定義。多數狀況是某些瀏覽器內置機制設置的默認值,聲明一個變量不賦值,這個變量的默認值就是undefined


6、js中的判斷語句

判斷語句是流程控制的重要語句,其做用是當知足某些條件時才能執行某些代碼

一、if/else if/else

// 單獨使用if
if (條件) {
  // 瀏覽器會對條件進行布爾運算,即求出條件時 true 仍是 false。條件爲 true 時,即條件成立的時候纔會執行這個花括號裏面的代碼
}

// 兩種狀況,結合 else
if (條件) {
  // 條件爲 true 時
} else {
  // 不知足條件的時候要執行的代碼
}

// 多種狀況,結合 else if
if (條件1) {
  // 條件1爲 true 時
} else if (條件2) {
  // 條件2爲 true 的時候要執行的代碼
} else {
  // 上面條件都不知足條件的時候要執行的代碼
}
複製代碼

示例:

var num = 6;
if (num > 6) {
  num++; // => num = num + 1; 在自身上累加一個
} else if (num >= 10) {
  num--;
} else {
  num+=2
}
console.log(num);
複製代碼

只要有一個條件成立,後面無論是否還有成立的條件,都不會在執行了

var num = 10;
if (num > 5) {
  num += 2;
} else if (num > 8) {
  // 雖然 num 知足大於8,可是再上面已經執行過num>5的代碼,因此這裏不會執行
  num += 3;
} else {
  num += 4;
}
console.log(num); // 12
複製代碼

二、條件怎麼寫?

if (條件) 條件最終須要的是一個布爾值,而後根據是 true 仍是 false 來判斷條件是否成立。若是條件裏面寫的是能夠返回布爾值的表達式,那麼就利用這個表達式的返回結果;若是不是返回布爾值,那麼瀏覽器會自動把它轉換成布爾值,而後用轉換出來的結果判斷條件是否成成立

常見比較運算符:比較運算符都會返回布爾值

  • 大於(>), a > b, 當 a 大於 b 時返回 true,不然返回 false
  • 大於等於(>=), a >= b ,當 a 大於等於 b 時返回 true,不然返回 false
  • 小於(<),a < b
  • 小於等於(<=)
  • 不等於(!=)、
  • 等於(相對比較== 或者 絕對比較===)
    • == 是相對比較,只要兩邊的值相同就行,不比較類型,如 1 == '1' 返回 true
    • === 是絕對比較,兩邊值相同還不夠,還要比較類型。1 === '1' 返回 false,由於1是 number,而'1'是 string,類型不一樣
console.log(1 > 0); // true
console.log(1 < 0); // false
console.log(1 == '1'); // true
console.log(1 === '1'); // false
複製代碼

條件常見形式:

  • 使用比較運算符,直接返回布爾值
  • 若是是數學表達式,那麼會先運算求值,而後再把運算出來的結果轉換成布爾值。

在js中,+ - * / % 都是數學運算,除 + 之外,其他的運算符在運算時,若是遇到非數字類型的值,首先會轉成數字類型(Number),而後再進行運算

if ('3px' + 3) {
  // + 操做符在兩邊都是數字時纔是加法運算符,若是有一個不是數字,那麼加好就是字符串拼接。
  // 因此 '3px' + 3的結果是字符串'3px3',而字符串 '3px3'轉換成布爾值之後是true,因此條件成立
}

if ('3px' - 3) {
  // - 會調用Number()方法把'3px'轉成數字,Number('3px') -> NaN,而NaN - 3 -> NaN,而NaN轉成布爾值是false,因此條件不成立
}
複製代碼
  • 其餘狀況,均會把條件轉成布爾值。

練習

var num = parseInt('width: 35.5px');
if (num == 35.5) {
  alert(0);
} else if (num == 35) {
  alert(1);
} else if (num == NaN) {
  alert(2);
} else if (typeof num == 'number') {
  alert(3);
} else {
  alert(4);
}
複製代碼

二、三元運算符

語法: 條件 ? 成立要作的事情 : 不成立要作的事情
至關於簡單的 if else判斷
而且三元運算符是有返回值的,當條件成立時三元運算符返回條件成立時的值,不成立時返回不成立的值。

  • 通常狀況
var num = 12;
if (num < 10) {
  num++;
} else {
  num--;
}

// 改寫成三元運算符

num > 10 ? num++ : num--;
複製代碼
  • 特殊狀況:
    • 若是三元運算符中條件成立或者不成立時不須要任何操做,咱們用null/undefined/ void 0佔位
// num > 10就++,不然啥也不作

num > 10 ? num++ : null;
num > 10 ? num++ : undefined;
num > 10 ? num++ : void 0;
複製代碼
- 若是在條件成立(或不成立)時有多條語句,須要用小括號括起來,每條語句;
複製代碼
var num = 10;
num >= 10 ? (num++, num*=2) : null;
複製代碼

三、switch case

語法:

switch (變量或者表達式) {
  case1:
    變量或者表達式的值是值1的時候執行的代碼;
    break;
  case2:
     變量或者表達式的值是值2的時候執行的代碼;
     break;
  ...
  case 值n:
    變量或者表達式的值是值1的時候執行的代碼;
    break;
  default:
    以上狀況都不知足時,至關於else
}
複製代碼

switch case應用於變量(表達式)在不一樣值的狀況下的不一樣操做,每一種 case 結束後都須要加break(break是結束整個判斷);

var num = 12;
if (num == 10) {
  num++;
} else if (num == 5) {
  num--;
} else {
  num = 0;
}

// 改寫成 switch case
switch (num) {
  case 10:
    num++;
    break;
  case 5:
    num--;
    break;
  default:
    num = 0;
}
複製代碼

注意:switch case 中每個 case 的比較都是基於 === 絕對相等來完成判斷的。即 10 === '10' 是 false。真實項目中經常使用絕對比較。

3-js基礎教程

1、邏輯運算符 || 和 &&

一、 || 表示或者,二者中有一個爲 true,就返回 true

if (0 || 1) {
  console.log('true')
}
if (0 || false) {
  console.log('false')
}
if (true || 0) {
  console.log(true);
}
複製代碼

2 && 是而且,兩個值中必須兩個都是 true,才返回 true

if (0 && 1) {
  console.log(1, '0 && 1')
}
if (0 && false) {
  console.log(2, '0 && false')
}
if (true && 0) {
  console.log(3, 'true && 0');
}
複製代碼

3. || 和 && 也是有返回值的,

  • || 若是第一個爲 true 就返回第一個,若是第一個不爲 true 就返回第二個
var r1 = 1 || 0;
console.log(r1);
var r2 = 0 || false;
複製代碼
  • && 若是第一個爲 true 返回第二個,若是第一個爲 false 返回第一個
var r3 = 1 && 0;
var r4 = false && 0;
console.log(r3);
console.log(r4);
複製代碼

2、==和===的區別

== 在比較時等號左右兩側數據類型不一樣時會先轉成相同數據類型,再比較

  1. == 是相對比較; === 是絕對比較
  • 1.1 字符串 == 數字 ;字符串轉換成數字
console.log(1 == '1'); // true
複製代碼
  • 1.2 布爾值 == 數字; 布爾值轉成數字
console.log(1 == true); // true;
複製代碼
  • 1.3 布爾值 == 字符串; 布爾值轉數字,字符串也轉成數字,而後進行比較;
console.log(false == '0'); // true
複製代碼
  • 1.4 null == undefined // true, null 和 undefined 和其餘數據類型比較都是false
  • 1.5 對象 == 對象; 比較的是空間地址,地址相同返回true
console.log({} == {}); // false
複製代碼
  • 1.6 對象 == 字符串; 對象轉成字符串,而後和字符串比較
console.log({} == '[object Object]'); // true
複製代碼
  • 1.7 對象 == 布爾值;對象先轉成字符串,再轉數字,布爾值也轉成數字,在比較這兩個數字
console.log({} == true); // false
console.log([] == false); // true
複製代碼
  • 1.8 對象 == 數字;對象先轉成字符串,而後再轉成數字
console.log({} == 1); // false
console.log([] == 0); // true
複製代碼
  • 特殊:NaN 和 NaN 永遠不相等
console.log(NaN == NaN); // NaN 和 NaN 永遠不相等
複製代碼

3、for循環

for 循環 (for loop) 語句:按照必定的規律,重複去作某一件事情,此時就須要使用循環語句.

var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];

/* [ 0: 1, 1: 2, 2: 3, ... 11: 12 length: 12 // length屬性的值表示數組有多少項 ] */

// 把數組裏面的每一項都輸出出來:

console.log(ary[0]);
console.log(ary[1]);
console.log(ary[2]);
console.log(ary[3]);
console.log(ary[4]);
console.log(ary[5]);
console.log(ary[6]);
console.log(ary[7]);
console.log(ary[8]);
console.log(ary[9]);
console.log(ary[10]);
console.log(ary[11]);
複製代碼

? 思考:咱們發現上面的代碼中除了方括號中索引不一樣,其餘的代碼都是相同的。
這個時候要是有一個變量i,而後讓:
第一次時i=0,
第二次i=1,
第三次i=2,
...
依次類推,每一次幫咱們給i加上1,那麼到什麼就不加了呢,由於i的最大索引是length-1,因此當i大於length-1以後就再也不加了。
而後咱們把代碼中的索引換成i就能夠了 console.log(ary[i]);

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

  // 第一次循環: i = 0 i < 12 因此 ary[i] 是 ary[0]
  // 第二次循環: i = 1 i < 12 因此 ary[i] 是 ary[1]
  // ...
  // i = 12 i < 12 => false 再也不執行循環體,循環結束,
  console.log(ary[i]);
}
console.log(i); // 在for的小括號裏聲明的變量能夠在外面使用
複製代碼

for 循環語法

  1. 定義初始值 var i = 0
  2. 設定循環成立的條件 i < ary.length(若是條件成立執行循環,不成立則結束循環)
  3. 條件成立會執行循環體中的內容(循環體就是花括號中的代碼)
  4. 執行累加 i++

var i = 0; 和i++ 能夠不放到括號裏,可是你寫在括號裏的這個變量和寫在外面是同樣的,在循環裏i++更改的就是外面聲明的這個i;

var k = 0;
for (;k < 5;) {
  console.log(k);
  k++;
}
console.log(k); // 在外面的k也被更改了,已經變成了5
複製代碼

倒着輸出一個數組

  • 把i的初始值設置爲ary.length - 1,而後條件是 i >=0 ; i--;
var ary = [12, 23, 34];
for (var i = ary.length - 1; i >= 0; i--) {
  console.log(ary[i]);
}
複製代碼

輸入數組中的奇偶項

// 輸出數組中的奇數項
// 偶數:可以被2整除的數字叫作偶數(整除:被除數除以餘數商是整數且餘數爲0)
// 奇數:不能被2整除的數字

for (var j = 0; j < ary.length; j++) {
  if (j % 2 === 0) {
    // % 是取模運算符 ,就是取餘數
    // 0 % 2 餘數是0
    // 1 % 2 餘數是1
    // 3 % 2 餘數是1
    // 4 % 2 餘數是0
    console.log(ary[j]);
  }
}
複製代碼

理解 break和 continue

  • continue 跳出某一輪的循環,繼續後面的循環
for (var i = 0; i < 10; i++) {
	if (i === 5) {
		continue; // 跳出i=5的那一次循環。結束本輪循環(循環體中的continue後面的代碼將再也不執行,繼續執行下一輪循環)
	}
	console.log(i)
}
複製代碼
  • break 結束整個循環
for (var i = 0; i < 10; i++) {
	if (i === 5) {
		break; // 結束i=5及之後全部的循環。break是強制結束整個循環,不作任何處理,同時循環體中的break後面的代碼也不會執行了
	}
	console.log(i)
}
複製代碼

4、for in 循環

for in循環
for in 循環是專門用來遍歷對象的,能夠把對象裏面的屬性一個一個的遍歷出來。
注意:for in只能遍歷對象的可枚舉屬性。通常瀏覽器默認添加的都是不可枚舉的屬性。例如__proto**__**

var obj = {
  name: '珠峯',
  age: 10
};

for (var k in obj) {
  // k 表明每次遍歷時的屬性名
  console.log('k ', k);
  console.log('obj[k]', obj[k]);
}
複製代碼

5、獲取DOM對象

DOM對象:咱們經過 js 的相關和 html 方法獲取到的 html 文檔中的元素

  1. document.getElementById()

經過 ID 獲取頁面中的元素對象 getElementById()方法

語法:document.getElementById('idbox');
參數:元素id, 'box'就是參數
返回值(函數執行事後的結果):若是獲取到,就是獲取到的 DOM 元素對象,若是獲取不到就是 null;

  • 解析:
    1. document 是根據 ID 查找的上下文,document 表明的是整個 HTML 文檔(就是 html 標籤自身及包裹的全部內容),getElementById 的上下文只能是 document
    2. 經過getElementById獲取的元素是一個對象數據類型的值(裏面包含了不少的內置屬性,這些屬性都是描述這個對象的)
  • DOM對象的屬性: 3. className: 存儲的是字符串類型(string),表明的是當前元素的樣式類名 4. id: 存儲的是一個字符串類型(string),當前元素的ID名 5. innerHTML:字符串 存儲的當前元素中全部的內容(包含標籤,而且標籤以字符串形式存在) 6. innerText: 存儲當前元素中全部的文本內容(沒有元素標籤) 7. onclick: 鼠標點擊事件 元素的點擊事件屬性,基於這個屬性,咱們能夠給元素綁定點擊事件 8. onmouseover: 鼠標劃過事件 9. onmouseout: 鼠標劃出事件 10. style 存儲當前元素的全部的【行內樣式】值(獲取和操做的都只能是寫在標籤上的行內樣式,寫在樣式表中的樣式,沒法經過這個屬性獲取到);
var box = document.getElementById('box');
console.log(box);
複製代碼
  1. getElementsByTagName()

經過標籤名獲取【元素對象集合】

  • 解析:
    1. 語法:context.getElementsByTagName('標籤名')
    2. 參數:標籤名字符串
    3. 返回值:從 context 下面查到的指定標籤名 DOM 元素對象組成的集合;這個集合中的每一項都是 DOM 元素對象;
    4. context 不是寫死的,是咱們指定的上下文。你想獲取那個元素下面的指定標籤元素集合,哪一個元素就是上下文
var listContainer = document.getElementById('container');
var liList = listContainer.getElementsByTagName('li'); // 此時 listContainer 就是上下文

console.log(liList);
console.log(liList[0]);
console.log(liList[1]);
console.log(liList[2]);
liList[0].style.backgroundColor = 'red';
複製代碼
  • 解析:
    1. 獲取的是一個元素結合(HTMLCollection),元素集合也是一個對象數據類型的,結合和數組很是相似(數字做爲索引,length表明長度),但它不是數組,而是叫作類數組。
    2. 和數組操做同樣,經過[索引]的方式能夠取出類數組的每一項。liList[0]獲取的是第一項。
    3. liList.length 表示集合中li的數量
    4. 集合中的每一項都是元素對象,咱們能夠獲取或者修改它的元素屬性,如style、innerHTML、innerText
    5. 結合索引、length能夠經過for循環把集合中的每一項獲取出來。

? 思考 ? DOM對象也是對象,那麼咱們能夠向操做普通對象那樣操做它嗎?好比說添加一個屬性,或者修改某個屬性?
DOM對象也是對象,咱們也能夠向操做對象的方式同樣操做DOM對象

for (var i = 0; i < liList.length; i++) {
	var cur = liList[i];
	cur.myIndex = i; // 經過自定義屬性存儲這個元素在元素集合中的索引
	console.log(cur);
}
複製代碼

6、隔行變色

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>珠峯-隔行變色</title>
	<style> * { margin: 0; padding: 0; } ul, li { list-style: none; } .li-wrapper { margin: 30px auto; border: 1px solid #00b38a; width: 500px; } .li-wrapper li { height: 50px; line-height: 50px; text-align: center; border-bottom: 1px darkblue dashed; } </style>
</head>
<body>
<ul id="liWrapper" class="li-wrapper">
	<li>1item1</li>
	<li>2item2</li>
	<li>3item3</li>
	<li>4item4</li>
	<li>5item5</li>
	<li>6item6</li>
	<li>7item7</li>
	<li>8item8</li>
	<li>9item9</li>
	<li>10item10</li>
</ul>

<script src="js/6-changeColor.js"></script>
</body>
</html>
複製代碼
// 1. => 獲取元素 liWrapper 下的 li

var liWrapper = document.getElementById('liWrapper');
var liList = liWrapper.getElementsByTagName('li');
for (let i = 0; i < liList.length; i++) {
	// 循環遍歷元素對象,而後取出每一項
	if (i % 2 === 0) {
		// 若是是 i 是偶數
		liList[i].style.backgroundColor = 'pink';
	} else {
		// 不然 i 是奇數
		liList[i].style.backgroundColor = 'yellow';
	}
}
複製代碼
相關文章
相關標籤/搜索