資料類型
- String 字元串
- Number 數值
- Boolean 布爾值
- Null 空值
- Undefined 未定義
- Object 對象
- 其中String Number Boolean Null Undefined屬于基本資料類型
- 而Object屬于引用資料類型
String字元串
- 在JS中字元串需要使用引号引起來
- 使用雙引号或單引号都可以,但是不要混着用
- 引号不能嵌套,雙引号不能放雙引号,單引号不能放單引号
var str = 'hello';
str = '我說:"今天天氣真不錯!"';
number 數字類型
- 整數和浮點數(小數)
- JS中可以表示的數字的最大值
- 1.7976931348623157e+308
- Number.MAX_VALUE
- Number.MIN_VALUE 大于0的最小值
- 5e-324
- 如果使用Number表示的數字超過了最大值,則會傳回一個
- Infinity 表示正無窮
- -Infinity 表示負無窮
- 使用typeof檢查Infinity也會傳回number
- NaN 是一個特殊的數字,表示Not A Number
- 使用typeof檢查一個NaN也會傳回number
- 可以使用一個運算符 typeof 來檢查一個變量的類型
- 文法:typeof 變量
- 檢查字元串時,會傳回string
- 檢查數值時,會傳回number
var b = "123";
console.log(typeof b);
Boolean
- 布爾值隻有兩個,主要用來做邏輯判斷
- true 表示真
- false 表示假使用typeof檢查一個布爾值時,會傳回boolean
var bool = false;
console.log(typeof bool);
console.log(bool);
null
- Null(空值)類型的值隻有一個,就是null
- null這個值專門用來表示一個為空的對象
- 使用typeof檢查一個null值時,會傳回object
undefined
- Undefined(未定義)類型的值隻有一個,就undefind
- 當聲明一個變量,但是并不給變量指派時,它的值就是undefined
- 使用typeof檢查一個undefined時也會傳回undefined
轉義字元
- 在字元串中我們可以使用\作為轉義字元,當表示一些特殊符号時可以使用\進行轉義
- \ " 表示 "
- \' 表示 '
- \n 表示換行
- \t 制表符
- \ 表示\
強制類型轉換
- 指将一個資料類型強制轉換為其他的資料類型
- 類型轉換主要指,将其他的資料類型,轉換為
- String Number Boolean
将其他的資料類型轉換為String
- 方式一:
- 調用被轉換資料類型的toString()方法
- 該方法不會影響到原變量,它會将轉換的結果傳回
- 但是注意:null和undefined這兩個值沒有toString()方法,
- 如果調用他們的方法,會報錯
- 方式二:
- 調用String()函數,并将被轉換的資料作為參數傳遞給函數
- 使用String()函數做強制類型轉換時,
- 對于Number和Boolean實際上就是調用的toString()方法
- 但是對于null和undefined,就不會調用toString()方法
- 它會将 null 直接轉換為 "null"
- 将 undefined 直接轉換為 "undefined"
var a = 123;
//調用a的toString()方法
//調用xxx的yyy()方法,就是xxx.yyy()
a = a.toString();
a = true;
a = a.toString();
a = null;
//a = a.toString(); //報錯
a = undefined;
//a = a.toString(); //報錯
a = 123;
//調用String()函數,來将a轉換為字元串
a = String(a);
a = null;
a = String(a);
a = undefined;
a = String(a);
console.log(typeof a);
console.log(a);
強制轉換number
- 轉換方式一:
- 1.如果是純數字的字元串,則直接将其轉換為數字
- 2.如果字元串中有非數字的内容,則轉換為NaN
- 3.如果字元串是一個空串或者是一個全是空格的字元串,則轉換為0
- 布爾 --> 數字
- true 轉成 1
- false 轉成 0
- null --> 數字 0
- undefined --> 數字 NaN
- 使用Number()函數
- 字元串 --> 數字
- 轉換方式二:
- 這種方式專門用來對付字元串
- parseInt() 把一個字元串轉換為一個整數
- parseFloat() 把一個字元串轉換為一個浮點數
var a = "123";
//調用Number()函數來将a轉換為Number類型
a = Number(a);
a = false;
a = Number(a); 0
a = null;
a = Number(a); 0
a = undefined;
a = Number(a); nan
a = "123567a567px";
//調用parseInt()函數将a轉換為Number
/*
* parseInt()可以将一個字元串中的有效的整數内容去出來,
* 然後轉換為Number
*/
a = parseInt(a);
/*
* parseFloat()作用和parseInt()類似,不同的是它可以獲得有效的小數
*/
a = "123.456.789px";
a = parseFloat(a);
/*
* 如果對非String使用parseInt()或parseFloat()
* 它會先将其轉換為String然後在操作
*/
a = true;
a = parseInt(a);
a = 198.23;
a = parseInt(a);
console.log(typeof a);
console.log(a);
強制轉換布爾
- 使用Boolean()函數
- 除了空串,其餘的都是true
- null和undefined都會轉換為false
- 對象也會轉換為true
- 數字 ---> 布爾
- 除了0和NaN,其餘的都是true
- 字元串 ---> 布爾
var a = 123; //true
a = -123; //true
a = 0; //false
a = Infinity; //true
a = NaN; //false
//調用Boolean()函數來将a轉換為布爾值
a = Boolean(a);
a = " ";
a = Boolean(a);
a = null; //false
a = Boolean(a);
a = undefined; //false
a = Boolean(a);
其他進制數字
- 如果需要表示16進制的數字,則需要以0x開頭
- 如果需要表示8進制的數字,則需要以0開頭
- 如果要要表示2進制的數字,則需要以0b開頭
- 但是不是所有的浏覽器都支援
//十六進制
a = 0x10;
a = 0xff;
a = 0xCafe;
//八進制數字
a = 070;
//二進制數字
//a = 0b10;
//向"070"這種字元串,有些浏覽器會當成8進制解析,有些會當成10進制解析
a = "070";
//可以在parseInt()中傳遞一個第二個參數,來指定數字的進制
a = parseInt(a,10);
- 對象的分類:
- 由開發人員自己建立的對象
- 由JS的運作環境提供的對象,目前來講主要指由浏覽器提供的對象
- 比如 BOM DOM
- 由ES标準中定義的對象,在任何的ES的實作中都可以使用
- 比如:Math String Number Boolean Function Object....
- 1.内建對象
- 2.宿主對象
- 3.自定義對象
建立對象
- 1.使用new關鍵字調用的函數,是構造函數constructor
- 構造函數是專門用來建立對象的函數
- 使用typeof檢查一個對象時,會傳回object
var obj = new Object();
- 2.使用對象字面量來建立一個對象
var obj = {};
- 使用對象字面量,可以在建立對象時,直接指定對象中的屬性
- 文法:{屬性名:屬性值,屬性名:屬性值....}
var obj2 = {
name:"豬八戒",
age:13,
gender:"男",
test:{name:"沙僧"}
};
- 3.使用工廠方法建立對象
- 通過該方法可以大批量的建立對象
function createPerson(name , age ,gender){
//建立一個新的對象
var obj = new Object();
//向對象中添加屬性
obj.name = name;
obj.age = age;
obj.gender = gender;
obj.sayName = function(){
alert(this.name);
};
//将新的對象傳回
return obj;
}
var obj2 = createPerson("豬八戒",28,"男");
var obj3 = createPerson("白骨精",16,"女");
var obj4 = createPerson("蜘蛛精",18,"女");
在對象中儲存的值稱為屬性
- 向對象添加屬性
- 文法:對象.屬性名 = 屬性值;
- 向obj中添加一個name屬性obj.name = "孫悟空";
- 向obj中添加一個age屬性obj.age = 18;
- 文法:對象["屬性名"] = 屬性值
- obj["123"] = 789; obj["nihao"] = "你好";
讀取對象中的屬性
- 文法:對象.屬性名
- 如果讀取對象中沒有的屬性,不會報錯而是會傳回undefined
console.log(obj.gender);
- 文法:對象["屬性名"]
obj["gender"]
修改對象的屬性值
- 文法:對象.屬性名 = 新值
obj.name = "tom";
删除對象的屬性
- 文法:delete 對象.屬性名
delete obj.name;
in 運算符
- 通過該運算符可以檢查一個對象中是否含有指定的屬性
- 如果有則傳回true,沒有則傳回false
- 文法:"屬性名" in 對象
console.log("name" in obj);
函數 function
- 函數也是一個對象
- 函數中可以封裝一些功能(代碼),在需要時可以執行這些功能(代碼)
- 函數中可以儲存一些代碼在需要的時候調用
- 使用typeof檢查一個函數對象時,會返function
1.使用 函數聲明 來建立一個函數
- 文法:function 函數名([形參1,形參2...形參N]){ 語句...}
function fun2(){
console.log("這是我的第二個函數~~~");
alert("哈哈哈哈哈");
document.write("~~~~(>_<)~~~~");
}
//調用fun2
fun2();
使用 函數表達式 來建立一個函數
var 函數名 = function([形參1,形參2...形參N]){
語句....
}
var fun3 = function(){
console.log("我是匿名函數中封裝的代碼");
};
fun3();
傳回值
- return 來設定函數的傳回值文法:
- return 值
- 函數中return後的語句都不會執行
function sum(a , b , c){
var d = a + b + c;
return d;
}
//調用函數
//變量result的值就是函數的執行結果
//函數傳回什麼result的值就是什麼
var result = sum(4,7,8);
立即執行函數
- 函數定義完,立即被調用,這種函數叫做立即執行函數
- 立即執行函數往往隻會執行一次
(function(){
alert("我是一個匿名函數~~~");
})()
(function(a,b){
console.log("a = "+a);
console.log("b = "+b);
})(123,456)
函數也可以稱為對象的屬性,
- 如果一個函數作為一個對象的屬性儲存,
- 那麼我們稱這個函數時這個對象的方法
- 調用這個函數就說調用對象的方法(method)
var obj2 = {
name:"豬八戒",
age:18,
sayName:function(){
console.log(obj2.name);
}
};
obj2.sayName();
枚舉對象中的屬性
- 使用for ... in 語句
- 文法:for(var 變量 in 對象){ }
- for...in語句 對象中有幾個屬性,循環體就會執行幾次
- 每次執行時,會将對象中的一個屬性的名字指派給變量
var obj = {
name:"孫悟空",
age:18,
gender:"男",
address:"花果山"
};
for(var n in obj){
console.log("屬性名:"+n);
console.log("屬性值:"+obj[n]);
}
作用域
- 作用域指一個變量的作用的範圍
1.全局作用域
- 直接編寫在script标簽中的JS代碼,都在全局作用域
- 全局作用域在頁面打開時建立,在頁面關閉時銷毀
- 在全局作用域中有一個全局對象window,它代表的是一個浏覽器的視窗,它由浏覽器建立我們可以直接使用
- 在全局作用域中:
- 建立的變量都會作為window對象的屬性儲存
- 建立的函數都會作為window對象的方法儲存
- 全局作用域中的變量都是全局變量,在頁面的任意的部分都可以通路的到
var a = 10;
var b = 20;
//var c = "hello";
//console.log(window.c);
function fun(){
console.log("我是fun函數");
}
//window.fun();
//window.alert("hello");
2.函數作用域
- 調用函數時建立函數作用域,函數執行完畢以後,函數作用域銷毀
- 每調用一次函數就會建立一個新的函數作用域,他們之間是互相獨立的
- 在函數作用域中可以通路到全局作用域的變量
- 在全局作用域中無法通路到函數作用域的變量
- 當在函數作用域操作一個變量時,它會先在自身作用域中尋找,如果有就直接使用
- 如果沒有則向上一級作用域中尋找,直到找到全局作用域
- 如果全局作用域中依然沒有找到,則會報錯ReferenceError
- 在函數中要通路全局變量可以使用window對象
//建立一個變量
var a = 10;
function fun(){
var a = "我是fun函數中的變量a";
var b = 20;
//console.log("a = "+a);
function fun2(){
console.log("a = "+window.a);
}
fun2();
}
變量的聲明提前
- 使用var關鍵字聲明的變量,會在所有的代碼執行之前被聲明(但是不會指派),
- 但是如果聲明變量時不适用var關鍵字,則變量不會被聲明提前
- console.log("a = "+a);var a = 123;
函數的聲明提前
- 使用函數聲明形式建立的函數 function 函數(){}
- 它會在所有的代碼執行之前就被建立,是以我們可以在函數聲明前來調用函數
- 使用函數表達式建立的函數,不會被聲明提前,是以不能在聲明前調用
//fun();
//函數聲明,會被提前建立
function fun(){
console.log("我是一個fun函數");
}
//函數表達式,不會被提前建立
var fun2 = function(){
console.log("我是fun2函數");
};
fun2();
- 在函數中,不适用var聲明的變量都會成為全局變量
function fun5(){
//console.log("c = "+c);
//c = 10;
//d沒有使用var關鍵字,則會設定為全局變量
d = 100;
}
this(函數的上下文對象)
- 解析器在調用函數每次都會向函數内部傳遞進一個隐含的參數,
- 這個隐含的參數就是this,this指向的是一個對象,
- 這個對象我們稱為函數執行的 上下文對象,
- 根據函數的調用方式的不同,this會指向不同的對象
- 1.以函數的形式調用時,this永遠都是window
- 2.以方法的形式調用時,this就是調用方法的那個對象
- 3.當以構造函數的形式調用時,this就是新建立的那個對象
- 4.使用call和apply調用時,this是指定的那個對象
function fun(){
//console.log("a = "+a+", b = "+b);
console.log(this.name);
}
//fun();
//建立一個對象
var obj = {
name:"孫悟空",
sayName:fun
};
var obj2 = {
name:"沙和尚",
sayName:fun
};
//console.log(obj.sayName == fun);
var name = "全局的name屬性";
//obj.sayName();
//以函數形式調用,this是window
//fun();
//以方法的形式調用,this是調用方法的對象
//obj.sayName();
obj2.sayName();
arguments(封裝實參的對象)
- arguments是一個類數組對象,它也可以通過索引來操作資料,也可以擷取長度
- 在調用函數時,我們所傳遞的實參都會在arguments中儲存
- arguments.length可以用來擷取實參的長度
- arguments[0] 表示第一個實參
- 它裡邊有一個屬性叫做callee,這個屬性對應一個函數對象,就是目前正在指向的函數的對象
function fun(a,b){
//console.log(arguments instanceof Array);
//console.log(Array.isArray(arguments));
//console.log(arguments[1]);
//console.log(arguments.length);
console.log(arguments.callee == fun);
}
fun("hello",true);
構造函數
- 構造函數和普通函數的差別就是調用方式的不同普通函數是直接調用,而構造函數需要使用new關鍵字來調用
- 構造函數的執行流程:1.立刻建立一個新的對象2.将建立的對象設定為函數中this,在構造函數中可以使用this來引用建立的對象3.逐行執行函數中的代碼4.将建立的對象作為傳回值傳回
function Person(name , age , gender){
this.name = name;
this.age = age;
this.gender = gender;
this.sayName = function(){
alert(this.name);
};
}
function Dog(){
}
var per = new Person("孫悟空",18,"男");
var per2 = new Person("玉兔精",16,"女");
var per3 = new Person("奔波霸",38,"男");
var dog = new Dog();
- 使用instanceof可以檢查一個對象是否是一個類的執行個體文法: 對象 instanceof 構造函數如果是,則傳回true,否則傳回false
console.log(per instanceof Person);
原型 prototype
- 我們所建立的每一個函數,解析器都會向函數中添加一個屬性prototype
- 這個屬性對應着一個對象,這個對象就是我們所謂的原型對象
- 當函數以構造函數的形式調用時,它所建立的對象中都會有一個隐含的屬性,
- 指向該構造函數的原型對象,我們可以通過
- __proto__來通路該屬性
function MyClass(){
}
//向MyClass的原型中添加屬性a
MyClass.prototype.a = 123;
//向MyClass的原型中添加一個方法
MyClass.prototype.sayHello = function(){
alert("hello");
};
var mc = new MyClass();
var mc2 = new MyClass();
//向mc中添加a屬性
mc.a = "我是mc中的a";
//console.log(mc2.a);
mc.sayHello();
- 原型對象也是對象,是以它也有原型,
- 當我們使用一個對象的屬性或方法時,會現在自身中尋找,
- 自身中如果有,則直接使用
- 如果沒有則去原型對象中尋找,如果原型對象中有,則使用,
- 如果沒有則去原型的原型中尋找,直到找到Object對象的原型,
- Object對象的原型沒有原型,如果在Object原型中依然沒有找到,則傳回undefined
console.log(mc.__proto__.hasOwnProperty("hasOwnProperty"));
console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
console.log(mc.__proto__.__proto__.__proto__);
console.log(mc.hello);
console.log(mc.__proto__.__proto__.__proto__)
- 當我們直接在頁面中列印一個對象時,事件上是輸出的對象的toString()方法的傳回值
- 如果我們希望在輸出對象時不輸出[object Object],可以為對象添加一個toString()方法
function Person(name , age , gender){
this.name = name;
this.age = age;
this.gender = gender;
}
//修改Person原型的toString
Person.prototype.toString = function(){
return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]";
};
//建立一個Person執行個體
var per = new Person("孫悟空",18,"男");
var per2 = new Person("豬八戒",28,"男");
//Person[name=孫悟空,age=18,gender=男]
/*per.toString = function(){
return "Person[name="+this.name+",age="+this.age+",gender="+this.gender+"]";
};*/
var result = per.toString();
//console.log("result = " + result);
//console.log(per.__proto__.__proto__.hasOwnProperty("toString"));
console.log(per2);
console.log(per);
垃圾回收
- 就像人生活的時間長了會産生垃圾一樣,程式運作過程中也會産生垃圾
- 這些垃圾積攢過多以後,會導緻程式運作的速度過慢,
- 是以我們需要一個垃圾回收的機制,來處理程式運作過程中産生垃圾
- 當一個對象沒有任何的變量或屬性對它進行引用,此時我們将永遠無法操作該對象,
- 此時這種對象就是一個垃圾,這種對象過多會占用大量的記憶體空間,導緻程式運作變慢,是以這種垃圾必須進行清理。
- 在JS中擁有自動的垃圾回收機制,會自動将這些垃圾對象從記憶體中銷毀,我們不需要也不能進行垃圾回收的操作
- 我們需要做的隻是要将不再使用的對象設定null即可
var obj = new Object();
//對對象進行各種操作。。。。
obj = null;
call()和apply()
- 這兩個方法都是函數對象的方法,需要通過函數對象來調用
- 當對函數調用call()和apply()都會調用函數執行
- 在調用call()和apply()可以将一個對象指定為第一個參數此時這個對象将會成為函數執行時的this
- call()方法可以将實參在對象之後依次傳遞
- apply()方法需要将實參封裝到一個數組中統一傳遞
function fun(a,b) {
console.log("a = "+a);
console.log("b = "+b);
//alert(this);
}
var obj = {
name: "obj",
sayName:function(){
alert(this.name);
}
};
//fun.call(obj,2,3);
fun.apply(obj,[2,3]);
var obj2 = {
name: "obj2"
};
/*fun.apply();
fun.call();
fun();*/
//fun.call(obj);
//fun.apply(obj);
//fun();
//obj.sayName.apply(obj2);
添加類
addClass(box,"b2");
移除類
removeClass(box,"b2");
檢查obj中是否含有cn
hasClass(obj , cn)
toggleClass可以用來切換一個類
function toggleClass(obj , cn){
//判斷obj中是否含有cn
if(hasClass(obj , cn)){
//有,則删除
removeClass(obj , cn);
}else{
//沒有,則添加
addClass(obj , cn);
}
}
删除一個元素中的指定的class屬性
function removeClass(obj , cn){
//建立一個正規表達式
var reg = new RegExp("\\b"+cn+"\\b");
//删除class
obj.className = obj.className.replace(reg , "");
}
添加指定的class屬性值
function addClass(obj , cn){
//檢查obj中是否含有cn
if(!hasClass(obj , cn)){
obj.className += " "+cn;
}
}
判斷一個元素中是否含有指定的class屬性值
function hasClass(obj , cn){
//判斷obj中有沒有cn class
//建立一個正規表達式
//var reg = /\bb2\b/;
var reg = new RegExp("\\b"+cn+"\\b");
return reg.test(obj.className);
}
流程控制語句
- JS中的程式是從上到下一行一行執行的
- 通過流程控制語句可以控制程式執行流程,
- 使程式可以根據一定的條件來選擇執行
- 語句的分類:
- 1.條件判斷語句
- 2.條件分支語句
- 3.循環語句
1.條件判斷語句 (if)
- 使用條件判斷語句可以在執行某個語句之前進行判斷,
- 如果條件成立才會執行語句,條件不成立則語句不執行。
文法一:
if(條件表達式){ 語句...}
if(a > 10 && a <= 20){
alert("a大于10,并且 a小于等于20");
}
- if語句在執行時,會先對條件表達式進行求值判斷,
- 如果條件表達式的值為true,則執行if後的語句,
- 如果條件表達式的值為false,則不會執行if後的語句。
- if語句隻能控制緊随其後的那個語句,
- 如果希望if語句可以控制多條語句,可以将這些語句統一放到代碼塊中
文法二:
if(條件表達式){ 語句...}else{ 語句...}
- if...else...語句
- 當該語句執行時,會先對if後的條件表達式進行求值判斷,
- 如果該值為true,則執行if後的語句
- 如果該值為false,則執行else後的語句
if(age >= 60){
alert("你已經退休了~~");
}else{
alert("你還沒退休~~~");
}
文法三:
- if(條件表達式){
- 語句...
- }else if(條件表達式){
- }else{
- }
- if...else if...else
- 當該語句執行時,會從上到下依次對條件表達式進行求值判斷
- 如果值為true,則執行目前語句。
- 如果值為false,則繼續向下判斷。
- 如果所有的條件都不滿足,則執行最後一個else後的語句
- 該語句中,隻會有一個代碼塊被執行,一旦代碼塊執行了,則直接結束語句
if(age > 17 && age <= 30){
alert("你已經成年了");
}else if(age > 30 && age <= 60){
alert("你已經中年了");
}else if(age > 60 && age <= 80){
alert("你已經退休了");
}else{
alert("你歲數挺大的了~~");
}
switch
- 文法:switch(條件表達式){case 表達式: 語句... break;case 表達式: 語句... break;default: 語句... break;}
- 執行流程:
- 在執行時會依次将case後的表達式的值和switch後的條件表達式的值進行全等比較,
- 如果比較結果為true,則從目前case處開始執行代碼。
- 目前case後的所有的代碼都會執行,我們可以在case的後邊跟着一個break關鍵字,
- 這樣可以確定隻會執行目前case後的語句,而不會執行其他的case
- 如果比較結果為false,則繼續向下比較
- 如果所有的比較結果都為false,則隻執行default後的語句
- switch...case..語句
var num = 3;
switch(num){
case 1:
console.log("壹");
//使用break可以來退出switch語句
break;
case 2:
console.log("貳");
break;
case 3:
console.log("叁");
break;
default:
console.log("非法數字~~");
break;
}
2. 循環語句
while循環
- 文法:while(條件表達式){ 語句...}
- while語句在執行時,
- 先對條件表達式進行求值判斷,
- 如果值為true,則執行循環體,
- 循環體執行完畢以後,繼續對表達式進行判斷
- 如果為true,則繼續執行循環體,以此類推
- 如果值為false,則終止循環
do...while循環
- 文法:
- do{
- }while(條件表達式)
- do...while語句在執行時,會先執行循環體,
- 循環體執行完畢以後,在對while後的條件表達式進行判斷,
- 如果結果為true,則繼續執行循環體,執行完畢繼續判斷以此類推
- 如果結果為false,則終止循環
var i = 11;
while(i <= 10){
//3.定義一個更新表達式,每次更新初始化變量
document.write(i++ +"<br />")
do{
document.write(i++ +"<br />");
}while(i <= 10)
for循環
- for循環的文法:for(①初始化表達式;②條件表達式;④更新表達式){ ③語句...}
- for循環的執行流程:
- ①執行初始化表達式,初始化變量(初始化表達式隻會執行一次)
- ②執行條件表達式,判斷是否執行循環。
- 如果為true,則執行循環③
- 如果為false,終止循環
- ④執行更新表達式,更新表達式執行完畢繼續重複②
for(var i = 0 ; i < 10 ; i++ ){
alert(i);
}
- for循環中的三個部分都可以省略,也可以寫在外部如果在for循環中不寫任何的表達式,隻寫兩個;此時循環是一個死循環會一直執行下去,慎用 for(;;){ alert("hello"); }
break
- break關鍵字可以用來退出switch或循環語句
- 不能在if語句中使用break和continue
- break關鍵字,會立即終止離他最近的那個循環語句
for(var i=0 ; i<5 ; i++){
console.log("@外層循環"+i)
for(var j=0 ; j<5; j++){
break;
console.log("内層循環:"+j);
}
- 可以為循環語句建立一個label,來辨別目前的循環
- label:循環語句
- 使用break語句時,可以在break後跟着一個label,
- 這樣break将會結束指定的循環,而不是最近的
outer:
for(var i=0 ; i<5 ; i++){
console.log("@外層循環"+i)
for(var j=0 ; j<5; j++){
break outer;
console.log("内層循環:"+j);
}
}
continue
- continue關鍵字可以用來跳過當次循環
- 同樣continue也是預設隻會對離他最近的循環循環起作用
for(var i=0 ; i<5 ; i++){
if(i==2){
continue;
}
console.log(i);
}
事件
- onmousemove
- 該事件将會在滑鼠在元素中移動時被觸發
解決事件對象的相容性問題
event = event || window.event;
坐标
- clientX可以擷取滑鼠指針的水準坐标
- cilentY可以擷取滑鼠指針的垂直坐标
- var x = event.clientX; var y = event.clientY;
- pageX和pageY可以擷取滑鼠相對于目前頁面的坐标
事件的冒泡(Bubble)
- 冒泡指的就是事件的向上傳導,當後代元素上的事件被觸發時,其祖先元素的相同僚件也會被觸發
- 将事件對象的cancelBubble設定為true,即可取消冒泡
- event.cancelBubble = true;
事件的委派
- 指将事件統一綁定給元素的共同的祖先元素,這樣當後代元素上的事件觸發時,會一直冒泡到祖先元素進而通過祖先元素的響應函數來處理事件。
- 事件委派是利用了冒泡,通過委派可以減少事件綁定的次數,提高程式的性能
- target
- event中的target表示的觸發事件的對象
window.onload = function(){
var u1 = document.getElementById("u1");
//點選按鈕以後添加超連結
var btn01 = document.getElementById("btn01");
btn01.onclick = function(){
//建立一個li
var li = document.createElement("li");
li.innerHTML = "<a href='javascript:;' class='link'>建立的超連結</a>";
//将li添加到ul中
u1.appendChild(li);
};
/*
* 為每一個超連結都綁定一個單擊響應函數
* 這裡我們為每一個超連結都綁定了一個單擊響應函數,這種操作比較麻煩,
* 而且這些操作隻能為已有的超連結設定事件,而新添加的超連結必須重新綁定
*/
//擷取所有的a
var allA = document.getElementsByTagName("a");
//為ul綁定一個單擊響應函數
u1.onclick = function(event){
event = event || window.event;
if(event.target.className == "link"){
alert("我是ul的單擊響應函數");
}
};
};
事件綁定
- btn01.onclick = function(){ alert(2); };
- 對象.事件 = 函數 的形式綁定響應函數
- btn01.addEventListener("click",function(){ alert(1); },false);
- 參數:1.事件的字元串,不要on2.回調函數,當事件觸發時該函數會被調用3.是否在捕獲階段觸發事件,需要一個布爾值,一般都傳false
- addEventListener() 這個方法也可以為元素綁定響應函數
- addEventListener()中的this,是綁定事件的對象
- 相容多個浏覽器
-
function bind(obj , eventStr , callback){
if(obj.addEventListener){
//大部分浏覽器相容的方式
obj.addEventListener(eventStr , callback , false);
/*
* this是誰由調用方式決定
* callback.call(obj)
*/
//IE8及以下
obj.attachEvent("on"+eventStr , function(){
//在匿名函數中調用回調函數
callback.call(obj);
});
事件的傳播
- 1.捕獲階段
- 在捕獲階段時從最外層的祖先元素,向目标元素進行事件的捕獲,但是預設此時不會觸發事件
- 2.目标階段
- 事件捕獲到目标元素,捕獲結束開始在目标元素上觸發事件
- 3.冒泡階段
- 事件從目标元素向他的祖先元素傳遞,依次觸發祖先元素上的事件
- 希望在捕獲階段就觸發事件,可以将addEventListener()的第三個參數設定為true
function bind(obj , eventStr , callback){
if(obj.addEventListener){
//大部分浏覽器相容的方式
obj.addEventListener(eventStr , callback , true);
}else{
/*
* this是誰由調用方式決定
* callback.call(obj)
*/
//IE8及以下
obj.attachEvent("on"+eventStr , function(){
//在匿名函數中調用回調函數
callback.call(obj);
});
}
}
滾動的事件
- onmousewheel滑鼠滾輪滾動的事件
- 火狐需要使用 DOMMouseScroll 來綁定滾動事件
- event.wheelDelta 可以擷取滑鼠滾輪滾動的方向
- 火狐中使用event.detail來擷取滾動的方向
//判斷滑鼠滾輪滾動的方向
if(event.wheelDelta > 0 || event.detail < 0){
//向上滾,box1變短
box1.style.height = box1.clientHeight - 10 + "px";
}else{
//向下滾,box1變長
box1.style.height = box1.clientHeight + 10 + "px";
}
鍵盤事件
- onkeydown 按鍵被按下
- onkeyup 按鍵被松開
- keyCode 來擷取按鍵的編碼
- altKey ctrlKey shiftKey
- 這個三個用來判斷alt ctrl 和 shift是否被按下
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
<script type="text/javascript">
//使div可以根據不同的方向鍵向不同的方向移動
/*
* 按左鍵,div向左移
* 按右鍵,div向右移
* 。。。
*/
window.onload = function(){
//為document綁定一個按鍵按下的事件
document.onkeydown = function(event){
event = event || window.event;
//定義一個變量,來表示移動的速度
var speed = 10;
//當使用者按了ctrl以後,速度加快
if(event.ctrlKey){
speed = 500;
}
/*
* 37 左
* 38 上
* 39 右
* 40 下
*/
switch(event.keyCode){
case 37:
//alert("向左"); left值減小
box1.style.left = box1.offsetLeft - speed + "px";
break;
case 39:
//alert("向右");
box1.style.left = box1.offsetLeft + speed + "px";
break;
case 38:
//alert("向上");
box1.style.top = box1.offsetTop - speed + "px";
break;
case 40:
//alert("向下");
box1.style.top = box1.offsetTop + speed + "px";
break;
}
};
};
</script>
</head>
<body>
<div id="box1"></div>
</body>
</html>
字元串
- 建立一個字元串
- var str = "Hello Atguigu";
length屬性
- 可以用來擷取字元串的長度
console.log(str.length);
charAt()
- 可以傳回字元串中指定位置的字元
- 根據索引擷取指定的字元
str = "中Hello Atguigu";
var result = str.charAt(6);
charCodeAt()
- 擷取指定位置字元的字元編碼(Unicode編碼)
result = str.charCodeAt(0);
String.formCharCode()
- 可以根據字元編碼去擷取字元
result = String.fromCharCode(0x2692);
indexof()
- 該方法可以檢索一個字元串中是否含有指定内容
- 如果字元串中含有該内容,則會傳回其第一次出現的索引
- 如果沒有找到指定的内容,則傳回-1
- 可以指定一個第二個參數,指定開始查找的位置
lastIndexOf();
- 該方法的用法和indexOf()一樣,
- 不同的是indexOf是從前往後找,
- 而lastIndexOf是從後往前找
- 也可以指定開始查找的位置
str = "hello hatguigu";
result = str.indexOf("h",1);
result = str.lastIndexOf("h",5);
slice()
- 可以從字元串中截取指定的内容
- 不會影響原字元串,而是将截取到内容傳回參數:
- 第一個,開始位置的索引(包括開始位置)
- 第二個,結束位置的索引(不包括結束位置)
- 如果省略第二個參數,則會截取到後邊所有的也可以傳遞一個負數作為參數,負數的話将會從後邊計算
str = "abcdefghijk";
result = str.slice(1,4);
result = str.slice(1,-1);
substring()
- 可以用來截取一個字元串,可以slice()類似參數:
- 第一個:開始截取位置的索引(包括開始位置)
- 第二個:結束位置的索引(不包括結束位置)
- 不同的是這個方法不能接受負值作為參數,如果傳遞了一個負值,則預設使用0而且他還自動調整參數的位置,如果第二個參數小于第一個,則自動交換
result = str.substring(0,1);
substr()
- 用來截取字元串參數:
- 1.截取開始位置的索引
- 2.截取的長度
str = "abcdefg";
result = str.substr(3,2);
split()
可以将一個字元串拆分為一個數組
參數:
需要一個字元串作為參數,将會根據該字元串去拆分數組
str = "abcbcdefghij";
result = str.split("d");
- 如果傳遞一個空串作為參數,則會将每個字元都拆分為數組中的一個元素
result = str.split("");
toUpperCase()
- 将一個字元串轉換為大寫并傳回
toLowerCase()
- 将一個字元串轉換為小寫并傳回
數組(Array)
建立數組對象
1.構造函數建立數組
var arr = new Array();
var arr2 = new Array(10,20,30);
- 使用typeof檢查一個數組時,會傳回objectconsole.log(typeof arr);
2.使用字面量來建立數組
var arr = [];
- 字面量建立數組時,可以在建立時就指定數組中的元素
var arr = [1,2,3,4,5,10];
向數組中添加元素
- 文法:數組[索引] = 值
arr[0] = 10; arr[1] = 33; arr[2] = 22; arr[3] = 44;
讀取數組中的元素
- 文法:數組[索引]
console.log(arr[3]);
擷取數組的長度
- 文法:數組.length
- 連續的數組,使用length可以擷取到數組的長度(元素的個數)
- 非連續的數組,使用length會擷取到數組的最大的索引+1
console.log(arr.length);
修改length
- 如果修改的length大于原長度,則多出部分會空出來
- 如果修改的length小于原長度,則多出的元素會被删除
arr.length = 10;
向數組的最後一個位置添加元素
arr[arr.length] = 70;
//建立一個數組數組中隻有一個元素10
arr = [10];
//建立一個長度為10的數組
arr2 = new Array(10);
//console.log(arr2.length);
//數組中的元素可以是任意的資料類型
arr = ["hello",1,true,null,undefined];
//也可以是對象
var obj = {name:"孫悟空"};
arr[arr.length] = obj;
arr = [{name:"孫悟空"},{name:"沙和尚"},{name:"豬八戒"}];
//也可以是一個函數
arr = [function(){alert(1)},function(){alert(2)}];
//console.log(arr);
//arr[0]();
//數組中也可以放數組,如下這種數組我們稱為二維數組
arr = [[1,2,3],[3,4,5],[5,6,7]];
console.log(arr[1]);
var arr = ["孫悟空","豬八戒","沙和尚"]
push()
- 該方法可以向數組的末尾添加一個或多個元素,并傳回數組的新的長度
var result = arr.push("唐僧","蜘蛛精","白骨精","玉兔精");
pop()
- 該方法可以删除數組的最後一個元素,并将被删除的元素作為傳回值傳回
result = arr.pop();
unshift()
- 向數組開頭添加一個或多個元素,并傳回新的數組長度
arr.unshift("牛魔王","二郎神");
shift()
- 可以删除數組的第一個元素,并将被删除的元素作為傳回值傳回
result = arr.shift();
周遊
for(var i=0 ; i<arr.length ; i++){
console.log(arr[i]);
}
forEach()
- 需要一個函數作為參數
- 第一個參數,就是目前正在周遊的元素
- 第二個參數,就是目前正在周遊的元素的索引
- 第三個參數,就是正在周遊的數組
arr.forEach(function(value , index , obj){
console.log(value);
});
- 從數組提取指定元素
- 不會改變元素數組,而是将截取到的元素封裝到一個新數組中傳回
- -1 倒數第一個
- -2 倒數第二個
- 索引可以傳遞一個負值,如果傳遞一個負值,則從後往前計算
- 1.截取開始的位置的索引,包含開始索引
- 2.截取結束的位置的索引,不包含結束索引
- 參數:
var result = arr.slice(1,4);
splice()
- 删除數組中的指定元素
- splice()會影響到原數組,會将指定元素從原數組中删除
- 将被删除的元素作為傳回值傳回
- 第一個,表示開始位置的索引
- 第二個,表示删除的數量
- 第三個及以後。。可以傳遞一些新的元素,這些元素将會自動插入到開始位置索引前邊
var result = arr.splice(3,0,"牛魔王","鐵扇公主","紅孩兒");
var arr = ["孫悟空","豬八戒","沙和尚"]; var arr2 = ["白骨精","玉兔精","蜘蛛精"]; var arr3 = ["二郎神","太上老君","玉皇大帝"];
concat()
- 連接配接兩個或多個數組,并将新的數組傳回
- 不會對原數組産生影響
var result = arr.concat(arr2,arr3,"牛魔王","鐵扇公主");
join()
- 将數組轉換為一個字元串
- 不會對原數組産生影響,而是将轉換後的字元串作為結果傳回
arr = ["孫悟空","豬八戒","沙和尚","唐僧"];
result = arr.join("@-@");
reverse()
- 反轉數組(前邊的去後邊,後邊的去前邊)
- 直接修改原數組
arr.reverse();
sort()
- 對數組中的元素進行排序
- 也會影響原數組,預設會按照Unicode編碼進行排序
arr.sort();
我們可以在sort()添加一個回調函數,來指定排序規則,
回調函數中需要定義兩個形參,
浏覽器将會分别使用數組中的元素作為實參去調用回調函數
使用哪個元素調用不确定,但是肯定的是在數組中a一定在b前邊
浏覽器會根據回調函數的傳回值來決定元素的順序,
如果傳回一個大于0的值,則元素會交換位置
如果傳回一個小于0的值,則元素位置不變
如果傳回一個0,則認為兩個元素相等,也不交換位置
如果需要升序排列,則傳回 a-b
如果需要降序排列,則傳回b-a
arr = [5,4,2,1,3,6,8,7];
arr.sort(function(a,b){
//前邊的大
/*if(a > b){
return -1;
}else if(a < b){
return 1;
}else{
return 0;
}*/
//升序排列
//return a - b;
//降序排列
return b - a;
});
算術運算符
- 當對非Number類型的值進行運算時,會将這些值轉換為Number然後在運算
- 任何值和NaN做運算都得NaN
+
- +可以對兩個值進行加法運算,并将結果傳回
- 如果對兩個字元串進行加法運算,則會做拼串 會将兩個字元串拼接為一個字元串,并傳回
- 任何的值和字元串做加法運算,都會先轉換為字元串,然後再和字元串做拼串的操作
-
- 可以對兩個值進行減法運算,并将結果傳回
*
- 可以對兩個值進行乘法運算
/
- / 可以對兩個值進行除法運算
%
- % 取模運算(取餘數)
result = a + 1;
result = 456 + 789;
result = true + 1;
result = true + false;
result = 2 + null;
result = 2 + NaN;
一進制運算符
- 正号
- 正号不會對數字産生任何影響
正規表達式
建立正規表達式的對象
- var 變量 = new RegExp("正規表達式","比對模式");
- i 忽略大小寫
- g 全局比對模式
- 在構造函數中可以傳遞一個比對模式作為第二個參數
test()
使用這個方法可以用來檢查一個字元串是否符合正規表達式的規則,
如果符合則傳回true,否則傳回false
var str = "a";
var result = reg.test(str);
字面量來建立正規表達式
- var 變量 = /正規表達式/比對模式
var reg = /a/i;
建立一個正規表達式,檢查一個字元串中是否有a或b
- 使用 | 表示或者的意思
reg = /a|b|c/;
[]裡的内容也是或的關系
[ab] == a|b
[a-z] 任意小寫字母
[A-Z] 任意大寫字母
[A-z] 任意字母
[0-9] 任意數字
[^ ] 除了
量詞
* - 通過量詞可以設定一個内容出現的次數
* - 量詞隻對它前邊的一個内容起作用
* - {n} 正好出現n次
* - {m,n} 出現m-n次
* - {m,} m次以上
* - + 至少一個,相當于{1,}
* - * 0個或多個,相當于{0,}
* - ? 0個或1個,相當于{0,1}
var reg = /a{3}/;
//ababab
reg = /(ab){3}/;
reg = /b{3}/;
reg = /ab{1,3}c/;
reg = /ab{3,}c/;
reg = /ab+c/;
reg = /ab*c/;
reg = /ab?c/;
^ 表示開頭
$ 表示結尾
reg = /^a/; //比對開頭的a
reg = /a$/; //比對結尾的a
. 表示任意字元
- 在正規表達式中使用\作為轉義字元 . 來表示. \ 表示\
\w 任意字母、數字、_ [A-z0-9]\W除了字母、數字、 A-z0-9_ \d 任意的數字 [0-9]\D除了數字 0-9 \s空格\S除了空格 \b 單詞邊界\B除了單詞邊界
電子郵件
var emailReg = /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/;