js蝴蝶學習筆記(正在開始學習中)
第2章:語法
2.5語句
switch語句
<script>
var b="B";
switch (b)
{
case "a":
alert("a");
break;
case "B":
alert("B");
break;
default:
alert("沒有找到");
break;
}
</script>
while語句
<script> var a=1; var sum=0; while(a<5){ sum=sum+a; a++; } alert(sum); </script>
do while語句
<script>
var a=1;
var sum=0;
do{
sum=sum+a;
a++;
}
while(a<5);
alert(sum);
</script>
for語句
<script>
var sum=0;
for(var i=0;i<5;i++){
sum=sum+i;
}
alert(sum);
</script>
for in語句
<script> var x; var mycars = new Array();//使用關鍵詞 new 來建立陣列物件 mycars[0] = "first"; mycars[1]="second"; mycars[2]="third"; for(x in mycars){ document.write(mycars[x]+"<br/>"); } </script>
try/catch/finally 語句
<p>請輸入 5 到 10 之間的數:</p> <input id="demo" type="text"> <button type="button" onclick="myFunction()">檢測輸入</button> <p id="message"></p> <script> function myFunction(){ var message=document.getElementById("message"); message.innerHTML=""; var x=document.getElementById("demo").value; try{ if(x=="") throw "為空"; if(isNaN(x)) throw "不是一個數字"; if(x>10) throw "太大"; if(x<5) throw "太小"; } //異常通過 catch 語句捕獲,並輸出自定義資訊: catch(err){ message.innerHTML="輸入的值"+err; } // finally 語句無論 try 和 catch 執行結果如何都會執行: finally{ document.getElementById("demo").value=""; } } </script>
2.6表示式
如果第一個運算數的值為假,那麼運算子&&產生第一個運算數的值。否則,它產生第二個運算數的值。
如果第一個運算數的值為假,那麼運算子||產生後一個運算數的值。否則,它產生第一個運算數的值。
第3章:物件
物件字面量
var zhangsan={
sex:"男",
age:"23",
hobby:{
sports:"run",
idol:"鄭爽"
}
city:{
place:"上海",
weather:"rain"
}
};
檢索
兩種檢索方式
zhangsan["sex"] //"男"
zhangsan.hobby.sports //"run"
如果檢索不存在的成員元素
zhangsan["name"] //undefined
zhangsan.job //undefined
||運算子可以用來填充預設值
var name = zhangsan["name"] || "(張三)";
var job = zhangsan.job || "student";
嘗試檢索一個undefined值將會導致TypeError異常。這可以通過&&運算子來避免錯誤
zhangsan.equipment //undefined
zhangsan.equipment.model //throw "TypeError"
zhangsan.equipment && zhangsan.equipment.model //undefined
更新
物件中的值可以通過賦值語句來更新。如果屬性名已經存在於物件中,那麼這個屬性將被替換
zhangsan["age"]="25";
如果物件之前並沒有擁有過那個屬性名,那麼該屬性就被擴充到該物件中
zhangsan["name"]="zhangsan";
zhangsan.nickname="lucky";
zhangsan.family={
sister:"two"
};
zhangsan.status="student";
引用
物件通過引用來傳遞。它們永遠不會被拷貝:
var x=zhangsan;
x.nickname="lucky";
var nick=zhangsan.nickname;//因為x和zhangsan是指向同一個物件的引用,所以nick為"lucky";
var a={},b={},c={};//a、b和c每個都引用一個不同的空物件
a=b=c={};//a、b和c每個都引用同一個空物件
原型物件
Person原型物件定義了公共的say方法,雖然此舉在構造例項之後出現,但是因為原型方法在呼叫之前已經宣告,因此之後的每個例項將都擁有該方法。原型物件的用途是為每個例項物件儲存共享的方法和屬性,原型物件僅有一份。所以:person,say==new Person().say
function Person(){
this.name="zhangsan";
}
var person = new Person();
Person.prototype.say=function(){
console.log("hello"+this.name);
};
person.say();
陣列的兩種賦值形式
屬性名出現的順序是不確定的,如果想要確保屬性以特定的順序出現,最好的辦法就是完全避免使用for in,而是建立一個數組,在其中以正確的順序包含屬性名。
var arr = new Array();
arr[0] = "first";
arr[1] = "second";
arr[2] = "third";
for(var x in arr){
document.write(x+":"+arr[x]+"<br/>");
}
var workers = [
"zhngsan",
"lisi",
"wangwu"
];
for(var i=0;i<workers.length;i++){
document.write(i+":"+workers[i]+"<br/>");
}
刪除
var zhangsan={
sex:"男",
age:"25",
nickname:"lucky"
}
delete zhangsan.nickname;
document.write(zhangsan.nickname);
減少全域性變數汙染,最小化使用全域性變數的一個方法是在你的應用中只建立唯一一個全域性變數
var student = {};
student.name = {
"first-name":"zhong",
"last-name":"meijun"
};
student.information={
number:30,
name:"一(1)班",
courses:{
one:"語文",
two:"數學",
three:"英語"
},
grades:{
one:"98",
two:"99",
three:"100"
}
};
document.write(student.information.number);
方法呼叫模式
var myObject = {
value:0,
increment:function(inc){
this.value+=typeof inc ==="number"?inc:1;//if(typeof inc === "number"){inc}else{1}
}
};
myObject.increment();
document.write(myObject.value);//1
myObject.increment(2);
document.write("<br/>");
document.write(myObject.value);//3
函式呼叫模式
當一個函式並非一個物件的屬性時,那麼它就是被當做一個函式來呼叫.對於普通的函式呼叫來說,函式的返回值就是呼叫表示式的值
// function add(x,y){
// return x+y;
// }
// var sum=add(3,4);
// console.log(sum);//7
使用函式呼叫模式呼叫函式時,非嚴格模式下,this被繫結到全域性物件;
// function add(x,y){
// console.log(this);//window
// }
// add();
嚴格模式下,this是undefined
// function add(x,y){
// "use strict";
// console.log(this);//undefined
// }
// add();
所以"this"可以用來判斷當前是否是嚴格模式
var strict = (function(){return !this;}());
因為函式呼叫模式的函式中的this繫結到全域性物件,所以會發生全域性屬性被重寫的現象
var a=0;
function fn(){
this.a=1;
}
fn();
console.log(this,this.a,a);//window,1,1
解決方法:給該方法定義一個變數並給他賦值this,那麼你餓不函式就可以通過那個變數訪問到this.
var b=0;
function fn2(){
var that=this;//解決方法
taht.b=1;
console.log(that,that.b,b);//window,1,1
}
fn();
console.log(this,this.b,b)//window,0,0
建構函式呼叫模式,如果函式或者方法被呼叫之前帶有關鍵字new,它就構成建構函式呼叫
function fn(){
this.a=1;
}
var obj = new fn();
console.log(obj.a);//1
如果建構函式呼叫在圓括號內包含一組實參列表,先計算這些實參表示式,然後傳入函式內
function fn(x){
this.a=x;
};
var obj = new fn(2);
console.log(obj.a);//2
如果建構函式沒有形參,js建構函式呼叫的語法時允許省略實參列表和圓括號的,凡是沒有形參的建構函式呼叫都可以省略圓括號
var o = new Object();等價於var o = new Object;
apply方法讓我們構建一個引數陣列並用其去呼叫函式.它也允許我們選擇this的值。
apply方法接收兩個引數。第一個是將被繫結給this的值。第二個就是一個引數陣列。
構造一個包含兩個數字的陣列,並將它們相加。
var obj={};
var array=[1,2];
function sum(x,y){
return x+y;
}
console.log(sum.call(obj,1,2));//3
console.log(sum.apply(obj,[1,2]));//3
console.log(sum.apply(null,array));//3
思考:這四種函式呼叫的方法,什麼時候選擇那種比較合適呢?它們各自的優劣勢?
引數
function add(x,y){//形參
return x+y;
}
add(3,4);//實參
Arguments (實參)物件
由於js允許函式有不定數目的引數,所以需要一種機制,可以在函式體內部讀取所有引數。這就是arguments物件的由來
arguments物件包含了函式執行時的所有引數,arguments[0]就是第一個引數,arguments[1]就是第二個引數,以此類推。這個物件只有在函式體內部,才可以使用。
var f = function(one){
console.log(arguments[0]);//1
console.log(arguments[1]);//2
console.log(arguments[2]);//3
}
f(1,2,3);
function add(x){
console.log(arguments[0],arguments[1],arguments[2]);//4 5 6
return x+1;
}
add(4,5,6);
arguments物件的length屬性顯示實參的個數,函式的length屬性顯示形參的個數
function add(x,y){
console.log(arguments.length);//3
return x+1;
}
add(1,2,3);
console.log(add.length);//2
形參只是提供便利,但不是必需的
function add2(){
return arguments[0]+arguments[1];
}
console.log(add2(1,2));//3
和陣列的關係
需要注意的是,雖然arguments很像陣列,但它是一個物件。陣列專有的方法(比如slice和forEach),不能在arguments物件上直接使用。
如果要讓arguments物件使用陣列方法,真正的解決方法是將arguments轉為真正的陣列.
下面是兩種常用的轉換方法:slice方法和逐一填入新陣列.
var args = Array.prototype.slice.call(arguments);
//或者
var args = [];
for(var i=0;i<arguments.length;i++){
args.push(arguments[i]);
}
callee屬性
arguments物件有一個名為callee的屬性,該屬性是一個指標,指向擁有這個arguments物件的函式
function fn(num){
if(num<=1){
return 1;
}else{
return num*fn(num-1);
}
}
console.log(fn(5));
上面這個函式的執行與函式名緊緊耦合在了一起,可以用arguments.callee消除函式解耦
function fn(num){
if(num<=1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
console.log(fn(5));
但在嚴格模式下,訪問這個屬性會丟擲TypeError錯誤
這時,可以用具名的函式表示式
var fn2 = function fn(num){
if(num<=1){
return 1;
}else{
return num*fn(num-1)
}
};
console.log(fn2(5));
異常
當查出非正常的事故,程式應該丟擲一個異常
var add = function (a,b){
if(typeof a!=="number" || typeof b!=="number"){
throw{
name:"TypeError",
message:"add needs numbers"
};
}
return a+b;
}
add("nu","nu2");//會按照我們的設定報錯
throw語句中斷函式的執行,它應該丟擲一個exception物件,該物件包含可識別異常型別的name屬性和一個描述性的message屬性,你也可以新增其他的屬性。
該exception 物件將被傳遞到一個try語句的catch從句;
構造一個try_it函式,用不正確的方式呼叫之前的add函式
var try_it=function(){
try{
add("seven");
}catch(e){
document.write(e.name+":"+e.message);
}
}
try_it();
學習心得
這幾天學習了語法(包括空白、識別符號、數字、字串、語句、表示式、字面量、函式);物件(包括物件字面量、檢索、更新、引用、原型、反射、列舉、刪除、減少全域性變數汙染);函式(包括函式物件、函式字面量、呼叫、引數、返回、異常)
在語法這一章
空白:就是我們在寫js程式碼時,用空格將各個字元分割開來,例如var a=0;a和var之間需要用空格隔開
識別符號:是我們自己定義的變數名、函式名、陣列名...識別符號可以是任意順序的大寫字母、數字、下劃線和美元符號,但識別符號不能以數字開頭,不能是js中保留關鍵字。
數字:Math物件
字串:被包圍在單引號或雙引號之間
語句:while語句,for語句,do while語句,for in語句,if語句
下列的值為假(false,null,undefined,空字串’ ’,數字0,數字NaN),其他都為真
表示式:如果第一個運算數的值為假,那麼運算子&&產生第一個運算數的值。否則,它產生第二個運算數的值。
如果第一個運算數的值為假,那麼運算子||產生後一個運算數的值。否則,它產生第一個運算數的值。
函式宣告:
可以定義命名的函式變數,而無需給變數賦值。 例如:function bar(){return 3;}
函式表示式:
通過函式表示式定義的函式可以是命名的,也可以是匿名的。函式表示式不能以”function”開頭(下面自呼叫的例子要用括號將其括起來).
例如:var a=function(){return 3;}
字面量:5這是一個值,且唯一,可以用五,five表示,15是value,後面的都是字面量
函式:
在物件這一章
物件字面量:包圍在一對花括號中的零或多個”名/值”
var zhangsan={
age:25,
city:”上海”
}
檢索:可以使用[]和.的表示法,建議使用.更緊湊
例如:zhangsan[age] zhangsan.city
更新:物件中的值可以通過賦值語句來更新,如果屬性名已經存在於物件中,那麼這個屬性的值將被替換。如果之前並沒有那個屬性名,那麼該屬性將被擴充到物件中。
zhangsan.city=“江西”
引用:var x=s;x.name=“1”;var n=s.name最後結果是”1”
原型:下面的Person為原型物件
function Person(){this.name=“zhangsan”;}
var person=new Person();
Person.prototype.say=function(){console.log(this.name);};
person.say();
陣列的兩種賦值形式:
var arr=new Array();
arr[…]=…;
第二種:
var arr={
sex:”男”,
age:25
}
刪除:delete
第四章:函式
函式字面量:
var add=function(a,b){
return a+b}
四種呼叫模式:方法呼叫模式、函式呼叫模式、構造器呼叫模式、Apply呼叫模式
方法呼叫模式:當一個函式被儲存為物件的一個屬性時,我們稱之它為該物件的一個方法,那麼this被繫結到該物件上
var myObject={
name:”myObject”,
incremnet:function(a,b){return a+b;}
}
alert(myObject.increment(1,2))
函式呼叫模式:當一個函式並非一個物件的屬性時,那麼它就是被當做一個函式來呼叫
建構函式呼叫模式:如果函式或者方法被呼叫之前帶有關鍵字new,它就構成建構函式呼叫
apply方法:讓我們構建一個引數陣列並用其去呼叫函式,它允許我們選擇this的值
引數:實參和形參
異常:自定義報錯語句
給型別增加方法:通過給object.prototype新增方法來使得該方法對所有物件可用
遞迴
遞迴函式會直接或間接地呼叫自身的一種函式,它將一個問題分解成一組相似的子問題,呼叫自身去解決他的子問題
var hanni = function (disc,src,aux,dst){
if(disc > 0){
hanni(disc-1,src,dst,aux);
console.log("Move disc"+disc+"from"+src+"to"+dst);
hanni(disc-1,aux,src,dst);
}
}
hanni(3,"Src","Aux","Dst");
簡單遞迴
var fn=function(n){
if(n==1){return 1;}else{
return n*fn(n-1);
}
};
document.writeln(fn(5));
var obj1={
num:5,
fun:function(x){
if(x==1){return 1}
else{
return x*this.fun(x-1);
}
}
}
document.writeln(obj1.fun(5));
當一個函式返回它內部定義的一個函式時,就產生了一個閉包,閉包不但包括被返回的函式,還包括這個函式的定義緩解
var obj1 = function(){
var count=0;
var func = function(){
count++;
return count;
}
return func;
}
var obj = obj1();
console.log(obj());//1
console.log(obj());//2
console.log(obj());//3
接下來這個例子幫助我們更好的理解
var obj2 = function(){
var count2 = 0;
var func2 = function(){
count2++;
return count2;
}
return func2;
}
var counter1 = obj2();
var counter2 = obj2();
console.log(counter1());//1
console.log(counter2());//1
console.log(counter1());//2
console.log(counter2());//2
console.log(counter1());//3
console.log(counter2());//3
回撥:相當於打電話給別人,留下了號碼,讓別人回電話
回撥函式是一段可執行的程式碼段,它作為一個引數傳遞給其他的程式碼,其作用是在需要的時候方便呼叫這段(回撥函式)程式碼。
function add(num1,num2,callback){
var sum=num1+num2;
callback(sum);
}
function print(num){
console.log(num)
}
add(1,2,print);//3
級聯:後面再看,現在不理解
套用
var add1 = add.curry(1);
document.writeln(add1(6));//7
記憶
var fibonacci = function(){
var memo=[0,1];
var fib = function(n){
var result = memo[n];
if(typeof result !== "number"){
result = fib(n-1)+fib(n-2);
memo[n]=result;
}
return result;
}
return fib;
}();
第5章:繼承
5.2物件說明符
var myObject = maker(a,b,c,d,e);
//推薦如下方法寫
var myObject = maker({
first:a,
last:b,
state:c,
city:d,
place:e
});
第六章:陣列
6.1陣列字面量
var empty={};
var numbers=[
"zero","one","two"
]
console.log(empty[1])//undefined
console.log(numbers[1])//one
console.log(empty.length)//undefined
console.log(numbers.length)//3
//物件字面量
var number_object={
"0":"zero",
"1":"one",
"2":"two"
};
6.2長度
var myArray=[];
console.log(myArray.length);//0
//length屬性的值式這個陣列的最大整數屬性名加上1.它不一定等於數組裡的屬性的個數:
myArray[1000000]=true;
console.log(myArray.length);//1000001,myArray只包含一個屬性
//可以直接設定length的值,而把length設小將導致所有下標大於等於新length的屬性被刪除
var numbers=["one","two","three","four","five"]
numbers.length=3;
for(var i=0;i<numbers.length;i++){
console.log(numbers[i]);//"one","two","three"
}
//通過把下標指定為一個數組的當前length,可以附加一個新元素到該陣列的尾部
numbers[numbers.length]="four";
for(i=0;i<numbers.length;i++){
console.log(numbers[i]);//"one","two","three","four"
}
//有時用push方法可以更方便地完成同樣的事情:
numbers.push("addnew");
for(i=0;i<numbers.length;i++){
console.log(numbers[i]);//"one","two","three","four","addnew"
}
第七章:正則表示式
7.1一個例子:匹配Url
var parse_ur1=/^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
//^字元表示這個字串的開始,它是一個標記,用來防止exec跳過不像URL的字首
var url = "http://www.ora.com:80/goodparts?q#fragment";
var result = parse_ur1.exec(url);//exec() 方法用於檢索字串中的正則表示式的匹配。
var names=["url","scheme","slash","host","port","path","query","hash"];
var blanks = " ";
var i;
for(i = 0; i < names.length; i++){
document.writeln(names[i]+":"+blanks.substring(names[i].length)+result[i]+"<br/>");//substring() 方法用於提取字串中介於兩個指定下標之間的字元
}
//blanks.substring(names[i].length)表示截取出對應names[i].length的空格長度
7.2另一個例子:匹配數字
var parse_number = /^-?\d+(?:\.\d*)?(?:e[+\-]?\d+)?$/i;
var test = function(num){
document.writeln(parse_number.test(num));
}
test("1");//true
第八章:方法
//join(separator) 把一個數組構造成一個字串
var a = ["a","b","c"];
var b = a.join(",");//用""空字串,可以實現無間隔的連線
console.log(b);//a,b,c
//pop() 移除陣列中的最後一個元素並返回該元素,如果空返回undefined
var c = a.pop();
console.log(a);//["a","b"]
console.log(c);//c
//push() 將一個或多個引數附加到一個數組的尾部
var d = a.push(b,"true");
console.log(c);//["a","b","a,b,c","true"]
console.log(d);//4
//reverse() 反轉陣列中的元素的順序
var e = a.reverse();
console.log(a);//["true","a,b,c","b","a"]
console.log(e);//["true","a,b,c","b","a"]
//shift() 移除陣列中的第一個元素並返回該元素,如果空返回undefined
var f = a.shift();
console.log(a);//["a,b,c","b","a"]
console.log(f);//true
//slice(start,end) 從起始位置複製到結束位置
var g = a.slice(0,1);
console.log(a);//["a,b,c","b","a"]
console.log(g);//["a,b,c"]
//sort(comparefn) 對陣列中的內容進行適當的排序.它不能正確地給一組數字排序
var h = [4,8,15,16];
h.sort();
console.log(h);//[15,16,4,8];
//使用自己的比較函式來替換預設的比較函式,比較數字的大小順序
h.sort(function (a,b){
return a-b;
});
console.log(h);//[4,8,15,16];
//給字串排序
var i = ["aa","bb","a",4,8,15,16,23,42];
i.sort(function(a,b){
if(a===b){return 0;}
if(typeof a === typeof b){
return a<b?-1:1;
}
return typeof a<typeof b ? -1:1;
});
console.log(i);//[4,8,15,16,23,42,"a","aa","bb"]
//unshift(item...) 將item新增到陣列的尾部
var j = ["a","b"];
var k = j.unshift("?","@");
console.log(j);//["?", "@", "a", "b"]
console.log(k);//4
後面幾章基本上不用怎麼看,只用大概瞭解就行了。
目前對第四章-------4.13級聯----------57頁;第四章-------4.15記憶----------59頁
第五章整章,
這些不太理解。還有apply方法什麼的,也不太理解