1. 程式人生 > 實用技巧 >Swiper外掛超連結失效

Swiper外掛超連結失效

JavaScript概述

ECMAScript和JavaScript的關係

1996年11月,JavaScript的創造者--Netscape公司,決定將JavaScript提交給國際標準化組織ECMA,希望這門語言能夠成為國際標準。次年,ECMA釋出262號標準檔案(ECMA-262)的第一版,規定了瀏覽器指令碼語言的標準,並將這種語言稱為ECMAScript,這個版本就是1.0版。

該標準一開始就是針對JavaScript語言制定的,但是沒有稱其為JavaScript,有兩個方面的原因。一是商標,JavaScript本身已被Netscape註冊為商標。二是想體現這門語言的制定者是ECMA,而不是Netscape,這樣有利於保證這門語言的開發性和中立性。

因此ECMAScript和JavaScript的關係是,前者是後者的規格,後者是前者的一種實現。

ECMAScript的歷史

年份 名稱 描述
1997 ECMAScript 1 第一個版本
1998 ECMAScript 2 版本變更
1999 ECMAScript 3

新增正則表示式

新增try/catch

ECMAScript 4 沒有釋出
2009 ECMAScript 5

新增"strict mode"嚴格模式

新增JSON支援

2011 ECMAScript 5.1 版本變更
2015 ECMAScript 6 新增類和模組
2016 ECMAScript 7

增加指數運算子(**)

增加Array.prototype.includes

注:ES6就是指ECMAScript 6。

儘管 ECMAScript 是一個重要的標準,但它並不是 JavaScript 唯一的部分,當然,也不是唯一被標準化的部分。實際上,一個完整的 JavaScript 實現是由以下 3 個不同部分組成的:

  • 核心(ECMAScript)
  • 文件物件模型(DOM) Document object model (整合js,css,html)
  • 瀏覽器物件模型(BOM) Broswer object model(整合js和瀏覽器)

簡單地說,ECMAScript 描述了JavaScript語言本身的相關內容。

JavaScript 是指令碼語言
JavaScript 是一種輕量級的程式語言。

JavaScript 是可插入 HTML 頁面的程式設計程式碼。

JavaScript 插入 HTML 頁面後,可由所有的現代瀏覽器執行。

JavaScript 很容易學習。

JavaScript引入方式

Script標籤內寫程式碼

<script>
  // 在這裡寫你的JS程式碼
</script>

引入額外的JS檔案

<script src="myscript.js"></script>

JavaScript語言規範

註釋(註釋是程式碼之母)

// 這是單行註釋

/*
這是
多行註釋 */

結束符

JavaScript中的語句要以分號(;)為結束符。

JavaScript語言基礎

變數宣告

  1. JavaScript的變數名可以使用_,數字,字母,$組成,不能以數字開頭。
  2. 宣告變數使用var 變數名;的格式來進行宣告
var name = "Alex";
var age = 18;

注意:

變數名是區分大小寫的。

推薦使用駝峰式命名規則。

保留字不能用做變數名。

補充:

ES6新增了let命令,用於宣告變數。其用法類似於var,但是所宣告的變數只在let命令所在的程式碼塊內有效。例如:for迴圈的計數器就很適合使用let命令。

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

ES6新增const用來宣告常量。一旦宣告,其值就不能改變。

const PI = 3.1415;
PI // 3.1415

PI = 3
// TypeError: "PI" is read-only

再次補充:

abstract
boolean
byte
char
class
const
debugger
double
enum
export
extends
final
float
goto
implements
import
int
interface
long
native
package
private
protected
public
short
static
super
synchronized
throws
transient
volatile

保留字列表

JavaScript資料型別

JavaScript擁有動態型別

var x;  // 此時x是undefined
var x = 1;  // 此時x是數字
var x = "Alex"  // 此時x是字串 

數值(Number)

JavaScript不區分整型和浮點型,就只有一種數字型別。

var a = 12.34;
var b = 20;
var c = 123e5;  // 12300000
var d = 123e-5;  // 0.00123

還有一種NaN,表示不是一個數字(Not a Number)。

常用方法:

parseInt("123")  // 返回123
parseInt("ABC")  // 返回NaN,NaN屬性是代表非數字值的特殊值。該屬性用於指示某個值不是數字。
parseFloat("123.456")  // 返回123.456

字串(String)

var a = "Hello"
var b = "world;
var c = a + b; 
console.log(c);  // 得到Helloworld

常用方法:

方法 說明
.length 返回長度
.trim() 移除空白
.trimLeft() 移除左邊的空白
.trimRight() 移除右邊的空白
.charAt(n) 返回第n個字元
.concat(value, ...) 拼接
.indexOf(substring, start) 子序列位置
.substring(from, to) 根據索引獲取子序列
.slice(start, end) 切片
.toLowerCase() 小寫
.toUpperCase() 大寫
.split(delimiter, limit) 分割

拼接字串一般使用“+”

string.slice(start, stop)和string.substring(start, stop):

兩者的相同點:
如果start等於end,返回空字串
如果stop引數省略,則取到字串末
如果某個引數超過string的長度,這個引數會被替換為string的長度

substirng()的特點:
如果 start > stop ,start和stop將被交換
如果引數是負數或者不是數字,將會被0替換

silce()的特點:
如果 start > stop 不會交換兩者
如果start小於0,則切割從字串末尾往前數的第abs(start)個的字元開始(包括該位置的字元)
如果stop小於0,則切割在從字串末尾往前數的第abs(stop)個字元結束(不包含該位置字元)

slice和substring的區別

補充:

ES6中引入了模板字串。模板字串(template string)是增強版的字串,用反引號(`)標識。它可以當做普通字串使用,也可以用來定義多行字串,或者在字串中嵌入變數。

// 普通字串
`這是普通字串!`
// 多行文字
`這是多行的
文字`
// 字串中嵌入變數
var name = "q1mi", time = "today";
`Hello ${name}, how are you ${time}?`

注意:

如果模板字串中需要使用反引號,則在其前面要用反斜槓轉義。

JSHint啟用ES6語法支援:/* jshint esversion: 6 */

布林值(Boolean)

區別於Python,true和false都是小寫。

var a = true;
var b = false;

""(空字串)、0、null、undefined、NaN都是false。

null和undefined

  • null表示值是空,一般在需要指定或清空一個變數時才會使用,如 name=null;
  • undefined表示當宣告一個變數但未初始化時,該變數的預設值是undefined。還有就是函式無明確的返回值時,返回的也是undefined。

null表示變數的值是空,undefined則表示只聲明瞭變數,但還沒有賦值。

還不明白,上圖吧!

物件(Object)

JavaScript 中的所有事物都是物件:字串、數值、陣列、函式...此外,JavaScript 允許自定義物件。

JavaScript 提供多個內建物件,比如 String、Date、Array 等等。

物件只是帶有屬性和方法的特殊資料型別。

陣列

陣列物件的作用是:使用單獨的變數名來儲存一系列的值。類似於Python中的列表。

var a = [123, "ABC"];
console.log(a[1]);  // 輸出"ABC"

常用方法:

方法 說明
.length 陣列的大小
.push(ele) 尾部追加元素
.pop() 獲取尾部的元素
.unshift(ele) 頭部插入元素
.shift() 頭部移除元素
.slice(start, end) 切片
.reverse() 反轉
.join(seq) 將陣列元素連線成字串
.concat(val, ...) 連線陣列
.sort() 排序
.forEach() 將陣列的每個元素傳遞給回撥函式
.splice() 刪除元素,並向陣列新增新元素。
.map() 返回一個數組元素呼叫函式處理後的值的新陣列

關於sort()需要注意:

如果呼叫該方法時沒有使用引數,將按字母順序對陣列中的元素進行排序,說得更精確點,是按照字元編碼的順序進行排序。要實現這一點,首先應把陣列的元素都轉換成字串(如有必要),以便進行比較。

如果想按照其他標準進行排序,就需要提供比較函式,該函式要比較兩個值,然後返回一個用於說明這兩個值的相對順序的數字。比較函式應該具有兩個引數 a 和 b,其返回值如下:

若 a 小於 b,在排序後的陣列中 a 應該出現在 b 之前,則返回一個小於 0 的值。
若 a 等於 b,則返回 0。
若 a 大於 b,則返回一個大於 0 的值。

示例:

function sortNumber(a,b){
    return a - b
}
var arr1 = [11, 100, 22, 55, 33, 44]
arr1.sort(sortNumber)

關於遍歷陣列中的元素,可以使用下面的方式:

var a = [10, 20, 30, 40];
for (var i=0;i<a.length;i++) {
  console.log(a[i]);
}

forEach()

語法:

forEach(function(currentValue, index, arr), thisValue)

引數:

引數描述
function(currentValue, index, arr) 必需。 陣列中每個元素需要呼叫的函式。
函式引數:
引數描述
currentValue 必需。當前元素
index 可選。當前元素的索引值。
arr 可選。當前元素所屬的陣列物件。
thisValue 可選。傳遞給函式的值一般用 "this" 值。
如果這個引數為空, "undefined" 會傳遞給 "this" 值

splice()

語法:

splice(index,howmany,item1,.....,itemX)

引數:

引數描述
index 必需。規定從何處新增/刪除元素。
該引數是開始插入和(或)刪除的陣列元素的下標,必須是數字。
howmany 必需。規定應該刪除多少元素。必須是數字,但可以是 "0"。
如果未規定此引數,則刪除從 index 開始到原陣列結尾的所有元素。
item1, ...,itemX 可選。要新增到陣列的新元素

map()

語法:

map(function(currentValue,index,arr), thisValue)

引數:

引數描述
function(currentValue, index,arr) 必須。函式,陣列中的每個元素都會執行這個函式
函式引數:
引數描述
currentValue 必須。當前元素的值
index 可選。當期元素的索引值
arr 可選。當期元素屬於的陣列物件
thisValue 可選。物件作為該執行回撥時使用,傳遞給函式,用作 "this" 的值。
如果省略了 thisValue ,"this" 的值為 "undefined"

補充:

ES6新引入了一種新的原始資料型別(Symbol),表示獨一無二的值。它是JavaScript語言的第7種資料型別。

型別查詢

typeof "abc"  // "string"
typeof null  // "object"
typeof true  // "boolean"
typeof 123 // "number"

typeof是一個一元運算子(就像++,--,!,- 等一元運算子),不是一個函式,也不是一個語句。

對變數或值呼叫 typeof 運算子將返回下列值之一:

  • undefined - 如果變數是 Undefined 型別的
  • boolean - 如果變數是 Boolean 型別的
  • number - 如果變數是 Number 型別的
  • string - 如果變數是 String 型別的
  • object - 如果變數是一種引用型別或 Null 型別的

運算子

算數運算子

+ - * / % ++ --

比較運算子

> >= < <= != == === !==

注意:

1 == “1”  // true
1 === "1"  // false

邏輯運算子

&& || !

賦值運算子

= += -= *= /=

流程控制

if-else

var a = 10;
if (a > 5){
  console.log("yes");
}else {
  console.log("no");
}

if-else if-else

var a = 10;
if (a > 5){
  console.log("a > 5");
}else if (a < 5) {
  console.log("a < 5");
}else {
  console.log("a = 5");
}

switch

var day = new Date().getDay();
switch (day) {
  case 0:
  console.log("Sunday");
  break;
  case 1:
  console.log("Monday");
  break;
default:
  console.log("...")
}

switch中的case子句通常都會加break語句,否則程式會繼續執行後續case中的語句。

for

for (var i=0;i<10;i++) {
  console.log(i);
}

while

var i = 0;
while (i < 10) {
  console.log(i);
  i++;
}

三元運算

var a = 1;
var b = 2;
var c = a > b ? a : b

函式

函式定義

JavaScript中的函式和Python中的非常類似,只是定義方式有點區別。

// 普通函式定義
function f1() {
  console.log("Hello world!");
}

// 帶引數的函式
function f2(a, b) {
  console.log(arguments);  // 內建的arguments物件
  console.log(arguments.length);
  console.log(a, b);
}

// 帶返回值的函式
function sum(a, b){
  return a + b;
}
sum(1, 2);  // 呼叫函式

// 匿名函式方式
var sum = function(a, b){
  return a + b;
}
sum(1, 2);

// 立即執行函式
(function(a, b){
  return a + b;
})(1, 2);

補充:

ES6中允許使用“箭頭”(=>)定義函式。

var f = v => v;
// 等同於
var f = function(v){
  return v;
}

如果箭頭函式不需要引數或需要多個引數,就是用圓括號代表引數部分:

var f = () => 5;
// 等同於
var f = function(){return 5};

var sum = (num1, num2) => num1 + num2;
// 等同於
var sum = function(num1, num2){
  return num1 + num2;
}

函式中的arguments引數

function add(a,b){
  console.log(a+b);
  console.log(arguments.length)
}

add(1,2)

輸出:

3
2

注意:

函式只能返回一個值,如果要返回多個值,只能將其放在陣列或物件中返回。

函式的全域性變數和區域性變數

區域性變數

在JavaScript函式內部宣告的變數(使用 var)是區域性變數,所以只能在函式內部訪問它(該變數的作用域是函式內部)。只要函式執行完畢,本地變數就會被刪除。

全域性變數:

在函式外宣告的變數是全域性變數,網頁上的所有指令碼和函式都能訪問它。

變數生存週期:

JavaScript變數的生命期從它們被宣告的時間開始。

區域性變數會在函式執行以後被刪除。

全域性變數會在頁面關閉後被刪除。

作用域

首先在函式內部查詢變數,找不到則到外層函式查詢,逐步找到最外層。

幾個例子:

1.

var city = "BeiJing";
function f() {
  var city = "ShangHai";
  function inner(){
    var city = "ShenZhen";
    console.log(city);
  }
  inner();
}

f();  //輸出結果是?

2.

var city = "BeiJing";
function Bar() {
  console.log(city);
}
function f() {
  var city = "ShangHai";
  return Bar;
}
var ret = f();
ret();  // 列印結果是?

3.閉包

var city = "BeiJing";
function f(){
    var city = "ShangHai";
    function inner(){
        console.log(city);
    }
    return inner;
}
var ret = f();
ret();

詞法分析(嘗試理解)

JavaScript中在呼叫函式的那一瞬間,會先進行詞法分析。

詞法分析的過程:

當函式呼叫的前一瞬間,會先形成一個啟用物件:Avtive Object(AO),並會分析以下3個方面:

1:函式引數,如果有,則將此引數賦值給AO,且值為undefined。如果沒有,則不做任何操作。
2:函式區域性變數,如果AO上有同名的值,則不做任何操作。如果沒有,則將此變數賦值給AO,並且值為undefined。
3:函式宣告,如果AO上有,則會將AO上的物件覆蓋。如果沒有,則不做任何操作。

函式內部無論是使用引數還是使用區域性變數都到AO上找。

看兩個例子:

var age = 18;
function foo(){
  console.log(age);
  var age = 22;
  console.log(age);
}
foo();  // 問:執行foo()之後的結果是?

第二題:

var age = 18;
function foo(){
  console.log(age);
  var age = 22;
  console.log(age);
  function age(){
    console.log("呵呵");
  }
  console.log(age);
}
foo();  // 執行後的結果是?

詞法分析過程:
1、分析引數,有一個引數,形成一個 AO.age=undefine;
2、分析變數宣告,有一個 var age, 發現 AO 上面已經有一個 AO.age,因此不做任何處理
3、分析函式宣告,有一個 function age(){...} 宣告, 則把原有的 age 覆蓋成 AO.age=function(){...};

最終,AO上的屬性只有一個age,並且值為一個函式宣告

執行過程:
注意:執行過程中所有的值都是從AO物件上去尋找

1、執行第一個 console.log(age) 時,此時的 AO.age 是一個函式,所以第一個輸出的一個函式
2、這句 var age=22; 是對 AO.age 的屬性賦值, 此時AO.age=22 ,所以在第二個輸出的是 2
3、同理第三個輸出的還是22, 因為中間再沒有改變age值的語句了

答案解析

內建物件和方法

JavaScript中的所有事物都是物件:字串、數字、陣列、日期,等等。在JavaScript中,物件是擁有屬性和方法的資料。

我們在學習基本資料型別的時候已經帶大家瞭解了,JavaScript中的Number物件、String物件、Array物件等。

注意var s1 = "abc"和var s2 = new String("abc")的區別:typeof s1 --> string而 typeof s2 --> Object

自定義物件

JavaScript的物件(Object)本質上是鍵值對的集合(Hash結構),但是隻能用字串作為鍵。

var a = {"name": "Alex", "age": 18};
console.log(a.name);
console.log(a["age"]);

遍歷物件中的內容:

var a = {"name": "Alex", "age": 18};
for (var i in a){
  console.log(i, a[i]);
}

事情並沒有那麼簡單...

建立物件:

var person=new Object();  // 建立一個person物件
person.name="Alex";  // person物件的name屬性
person.age=18;  // person物件的age屬性

注意:

ES6中提供了Map資料結構。它類似於物件,也是鍵值對的集合,但是“鍵”的範圍不限於字串,各種型別的值(包括物件)都可以當做鍵。

也就是說,Object結構提供了“字串--值”的對應,Map結構提供了“值--值”的對應,是一種更完善的Hash結構實現。

var m = new Map();
var o = {p: "Hello World"}

m.set(o, "content"}
m.get(o) // "content"

m.has(o) // true
m.delete(o) // true
m.has(o) // false

map

擴充套件:

// 父類建構函式
var Car = function (loc) {
this.loc = loc;
};

// 父類方法
Car.prototype.move = function () {
this.loc ++;
};

// 子類建構函式
var Van = function (loc) {
Car.call(this, loc);
};

// 繼承父類的方法
Van.prototype = Object.create(Car.prototype);
// 修復 constructor
Van.prototype.constructor = Van;
// 擴充套件方法
Van.prototype.grab = function () {
/* ... */
};

JavaScript面向物件之繼承

Date物件

建立Date物件

//方法1:不指定引數
var d1 = new Date();
console.log(d1.toLocaleString());
//方法2:引數為日期字串
var d2 = new Date("2004/3/20 11:12");
console.log(d2.toLocaleString());
var d3 = new Date("04/03/20 11:12");
console.log(d3.toLocaleString());
//方法3:引數為毫秒數
var d3 = new Date(5000);
console.log(d3.toLocaleString());
console.log(d3.toUTCString());

//方法4:引數為年月日小時分鐘秒毫秒
var d4 = new Date(2004,2,20,11,12,0,300);
console.log(d4.toLocaleString());  //毫秒並不直接顯示

Date物件的方法:

var d = new Date(); 
//getDate()                 獲取日
//getDay ()                 獲取星期
//getMonth ()               獲取月(0-11)
//getFullYear ()            獲取完整年份
//getHours ()               獲取小時
//getMinutes ()             獲取分鐘
//getSeconds ()             獲取秒
//getMilliseconds ()        獲取毫秒
//getTime ()                返回累計毫秒數(從1970/1/1午夜)

練習:

編寫程式碼,將當前日期按“2017-12-27 11:11 星期三”格式輸出。

詳細Date物件方法:點我

JSON物件

var str1 = '{"name": "Alex", "age": 18}';
var obj1 = {"name": "Alex", "age": 18};
// JSON字串轉換成物件
var obj = JSON.parse(str1); 
// 物件轉換成JSON字串
var str = JSON.stringify(obj1);

RegExp物件

//RegExp物件

//建立正則物件方式1
// 引數1 正則表示式(不能有空格)
// 引數2 匹配模式:常用g(全域性匹配;找到所有匹配,而不是在第一個匹配後停止)和i(忽略大小寫)

// 使用者名稱只能是英文字母、數字和_,並且首字母必須是英文字母。長度最短不能少於6位 最長不能超過12位。

// 建立RegExp物件方式(逗號後面不要加空格)
var reg1 = new RegExp("^[a-zA-Z][a-zA-Z0-9_]{5,11}$");

// 匹配響應的字串
var s1 = "bc123";

//RegExp物件的test方法,測試一個字串是否符合對應的正則規則,返回值是true或false。
reg1.test(s1); // true

// 建立方式2
// /填寫正則表示式/匹配模式(逗號後面不要加空格)
var reg2 = /^[a-zA-Z][a-zA-Z0-9_]{5,11}$/;

reg2.test(s1); // true


// String物件與正則結合的4個方法
var s2 = "hello world";

s2.match(/o/g); // ["o", "o"] 查詢字串中 符合正則 的內容
s2.search(/h/g); // 0 查詢字串中符合正則表示式的內容位置
s2.split(/o/g); // ["hell", " w", "rld"] 按照正則表示式對字串進行切割
s2.replace(/o/g, "s"); // "hells wsrld" 對字串按照正則進行替換

// 關於匹配模式:g和i的簡單示例
var s1 = "name:Alex age:18";

s1.replace(/a/, "哈哈哈"); // "n哈哈哈me:Alex age:18"
s1.replace(/a/g, "哈哈哈"); // "n哈哈哈me:Alex 哈哈哈ge:18" 全域性匹配
s1.replace(/a/gi, "哈哈哈"); // "n哈哈哈me:哈哈哈lex 哈哈哈ge:18" 不區分大小寫


// 注意事項1:
// 如果regExpObject帶有全域性標誌g,test()函式不是從字串的開頭開始查詢,而是從屬性regExpObject.lastIndex所指定的索引處開始查詢。
// 該屬性值預設為0,所以第一次仍然是從字串的開頭查詢。
// 當找到一個匹配時,test()函式會將regExpObject.lastIndex的值改為字串中本次匹配內容的最後一個字元的下一個索引位置。
// 當再次執行test()函式時,將會從該索引位置處開始查詢,從而找到下一個匹配。
// 因此,當我們使用test()函式執行了一次匹配之後,如果想要重新使用test()函式從頭開始查詢,則需要手動將regExpObject.lastIndex的值重置為 0。
// 如果test()函式再也找不到可以匹配的文字時,該函式會自動把regExpObject.lastIndex屬性重置為 0。

var reg3 = /foo/g;
// 此時 regex.lastIndex=0
reg3.test('foo'); // 返回true
// 此時 regex.lastIndex=3
reg3.test('xxxfoo'); // 還是返回true
// 所以我們在使用test()方法校驗一個字串是否完全匹配時,一定要加上^和$符號。

// 注意事項2(說出來你可能不信系列):
// 當我們不加引數呼叫RegExpObj.test()方法時, 相當於執行RegExpObj.test("undefined"), 並且/undefined/.test()預設返回true。
var reg4 = /^undefined$/;
reg4.test(); // 返回true
reg4.test(undefined); // 返回true
reg4.test("undefined"); // 返回true

RegExp相關

擴充套件閱讀

Math物件

abs(x) 返回數的絕對值。
exp(x) 返回 e 的指數。
floor(x) 對數進行下舍入。
log(x) 返回數的自然對數(底為e)。
max(x,y) 返回 x 和 y 中的最高值。
min(x,y) 返回 x 和 y 中的最低值。
pow(x,y) 返回 x 的 y 次冪。
random() 返回 0 ~ 1 之間的隨機數。
round(x) 把數四捨五入為最接近的整數。
sin(x) 返回數的正弦。
sqrt(x) 返回數的平方根。
tan(x) 返回角的正切。

Math