JavaScript學習

1運算符  

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

賦值運算符:=,+=,-=,*=,/=,%=

比較運算符:==,!=,!==,>,<,>=,<=

===(全等於) !== (不全等於): 判斷值和數據的類型

邏輯運算符:&&,||,!

條件運算符:


字符串操作: +連接符號,


位運算符:





2變量 

var 變量名=值

var 的類型取決於值的類型 類型一個自動類型

var 類型可以動態的變換

var a = "abc"

a = 123   這是沒問題的



3數據類型

數字類型  number

字符串類型 string 空字符也是字符類型

真假類型 boolean

空類型: null什麼都沒有

未定義類型:Undefined 表示沒有定義

符合數據類型:複雜類型,array數組,object對象

查看數據的類型 Typeof  返回的是



4alert 彈出一個窗口,會暫停程序的運行



5語法規則:

1區分大小寫

2所有的符號都必須是英文狀態下的

3可以不加分號結尾,但是最好加上最好.

4單行註釋 // 多行註釋 /**/

5document.write() 輸出到頁面



6傳值

賦值傳值: 兩份數據,之間不會影響

引用傳值: 一份數據,任意一個改動值另一個都會收到影響

簡單數據是賦值傳值 var a = 10; var b = a;

複雜數據都是引用傳值: var a = {a:"你好",b:23}; var b = a


7if(條件){語句塊}  

if(條件){語句塊} else{語句塊}

if(條件){語句塊} else if(條件){語句塊} else{語句塊}



8switch

switch(值)
{
    case 值:
    {
    }
    break;
    case 10>值  前提是值是bool類型
    break
    
    default:默認
    break;
}




9while(條件){執行體}


10 for(初始值;循環條件;值每次的變化){循環體}


11函數 function 函數名(){函數體}

帶參數函數 function 函數名(名字){ 使用參數直接用名字 函數體}

帶參數的不需要加var, 

     function jia(a,b)
{
document.write(a+b);
}
jia(10,20)


參數最後一個可以有默認值

 function jia(a,b=20){}

 


12數組

同數據類型的變量放在一個集合裏

var arr=[23,24,25]

訪問第一個取值arr[0]

長度: arr.length



for(var key in 數組名){

 key就是數組的下標

}


查找數據所在索引

arr.indexOf(10)  返回10的下標  ,沒有就返回 -1



刪除某個元素 splice(開始索引,刪除個數)

var arr = [10,20,230,40,50]

比如我要刪除後面兩個

arr.splice(3,2)


排序 快速排序 自己寫一個

arr.sort(function(s1,s2){
    if(s1<s2){

        return -1;
    }

    else{

        return 1;

    }


});



隨機打亂一個數組 類似洗牌

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

arnm.sort(function(lhs,rhs){

    if(Math.random()<0.5){

        return -1;

    }

    else {

        return 1;

    }


});




13二維數組


遍歷二維數組

var arr1=[1,2,3];
var arr2=[4,5,6];
var arr3=[7,8,9];
var arr4=[arr1,arr2,arr3];
或者
var arr4=[
            [1,2,3],
            [4,5,6],
            [7,8,9] 
           ];

for(var i = 0;i<arr4.length;i++)
{
for(var j =0;j<arr4[i].length;j++)
{
document.write(arr4[i][j]+"<br/>");
}
}



14常用函數

ParseInt:取整

parseFloat: 去浮點數

NaN:not a number表示不是一個數字

isNaN: 判斷是不是數字,是返回false  如果是字符纔會返回true



15array對象

var arr = new Array(23,2,2,4) // 創建一個array對象

對象有屬性和方法


Concat()連接內容或者數組,組成新的數組 返回


Join加入某個字符n,用n來連接數組的每項組成的字符串 最後元素一個不會

arr567 = arr567.join(""); 使用這種方法,可將一個數組變成一個字符串


Pop刪除數組最後一個元素,並返回

Push加入新的內容到最後,返回新的長度

Reverse 反轉數組的順序





16 string對象 var str = "abc"  var str = new string("abc")

屬性:

length  字符串長度


方法:

charAt(n) 獲取字符串裏下標爲n的字符

也可以直接用[]下標號 取值

CharCodeAt(n) 找到索引位置上的字符串的編碼值 ASCLL

indexOf("m") 找m在字符串中第一次出現的位置 從0開始沒找到返回-1

lastIndexOf("c") 字符c在字符串中最後一次出現的位置 找到返回-1

split("n") 以字符n分割字符串爲 返回一個數組 

如果沒有這個字符 就會把所有的字符串轉爲一個數組元素.

split("") 可以把字符串 每個元素切割成 數組


substr(n,m):截取字符串: 把字符串從n開始的地方截取m個字符

如果只有一個參數n,默認就從n開始截取到最後


substring(n,m)截取字符串:把字符串從n的位置開始截取到m的位置,

注意能夠取到n但是去不到m

toLowerCase() 把字符串中的字符轉換成小寫toUpperCase轉大寫





17 Math 對象

Math.pow(n,m) 求n的m次方

Math.abs(n)求n的絕對值

Math.round(n)求n的四捨五入值

Math.floor(n) 求n的向下取整的值,不大於n的最大整數

Math.ceil(n) 求n的向上取整的值,不小於n的最小整數

Math.random()獲得一個0到1之間的隨機數,注意:能取到0,但不不能取到1

Math.random()*20  求0到20之間的隨機數 

Math.random()*10+10  求10到20之間的隨機數 

也就是最小10最大20,同時減去10(0,10)然後總體+10

求30-60之間的隨機數:

首先30-30 60-30(0,30)然後整體+30

Math.random()*30+30

50 100隨機數 都減去50(0*50) 整體加50

Math.random()*50+50

Math.PI 圓周率



Math.floor 方法實例 數值向下取整 就是:小與或等於他的最大整數


該方法與 Math.ceil 方法正好相反。


1
2
3
4
5
6
<script language="JavaScript">
document.write( Math.floor(0.35) + "<br />" );
document.write( Math.floor(10) + "<br />" );
document.write( Math.floor(-10) + "<br />" );
document.write( Math.floor(-10.1) );
</script>

運行該例子,輸出:

0
10
-10
-11



18 JS特殊字符


單引號和雙引號:只是用字符和字符串這兩個沒有區別

如果雙引號中包括雙引號需要用\"轉義

單引號也是一樣的

如果要用反斜槓'\\'


\轉義字符  document.write("他說:\"aaa,bbb,ccc,hggg\""+"<br/>");

\r回車   

\r換行





19 Date 對象

構造方法:

new Date(); //創建當前時間日期對象

new Date("1999/9/9 6:6:6") 創建一個指定的時間

new Date("1999,9,9,6,6,6") 創建一個指定的時間日期對象

new Date(2343523445632)  創建一個從1970年開始的1-1-凌晨0點開始,

以毫秒爲單位, 但現在的時間  單位是毫秒。

toLocalString() 以當前本地格式顯示

getFullYear()  獲取年份

getMonth()   獲取月份
getDate()    獲取日期

getHours()    獲取小時

getMinutes()    獲取分鐘數

getSeconds()    獲取秒數

getMilliSeconds() 毫秒

getDay()   獲取星期


setFullYear(n) 設置年份

setMonth()   設置月份
setDate()    設置日期

setHours()    設置小時

setMinutes()   設置分鐘數

setSeconds()   設置秒數

setMilliSeconds() 設置毫秒





20 Object對象

var obj = {name:"小明",age:24,taiji:function(){},zuofan:function(alert("做飯")){]};

裏面有屬性 有方法

使用對象

obj.name 取值

//調用方法

obk.zuofan();


HTML和JS交互 通過id獲取這個標籤

HTML:對象.HTML屬性=值

CSS: 對象.style.CSS 屬性=值


document.getElementById(標籤id) 獲取之後 Js就可以使用這個標籤的屬性和方法了

Onclick  點擊

Onmouseiver  鼠標放上

Onmouseout   鼠標離開.


function fn(){
var obj = document.getElementById("d1");
obj.style.background = "red";
}
function fm(){
var obj = document.getElementById("d1");
obj.style.background = "blue";
}
</script>

<body>
<div id="d1" onmouseover="fn()" onmouseout="fm()">
這是DIV
<div/>







21 事件

鼠標事件:

Onclick:點擊

OMouseover:鼠標放上

Onmouseout:鼠標離開

ONdblclick:雙擊事件

Onmousedown:鼠標按下

Onmouseup:鼠標擡起

Onmousemove: 鼠標移動


表單事件:

onfocuss:獲得焦點

onblur:失去焦點

onsubmit:提交事件

onchange:當發生改變的時候

onreset: 重置事件



鍵盤事件:
onkeyup:  鍵盤擡起

onkeydowm: 鍵盤按下

onkeypress:鍵盤按下一次



窗口事件:onload事件

頁面加載完成之後立刻執行的事件。





21 DOM對象 當網頁被加載時,瀏覽器會創建頁面的文檔對象模型(Document Object Model)

5_3@8`0%0HYT$JZIS{_LG}G.png

通過這些對象 去修改或者獲取元素對應的內容




22 DOM操作HTML

JavaScript能改變頁面中所有HTML的元素

JavaScript能夠改變頁面中所有的HTML屬性

JavaScript能夠改變頁面中所有的CSS樣式

JavaScript能夠對頁面中所有的事件作出反應


document.getElementById("id號")


//通過元素名獲取

<p>aaa</p>

<p>bbb</p>

他默認獲得的就是第一個元素的對象

document.getElementsByTagName("p")






23異常捕獲

try{

    放可能會發生異常的代碼

}catch(err){
   發生異常在這裏處理 err就是錯誤信息

}
自定義錯誤  使用throw拋出

try{

如 if(字符串 == "")  我們不想要空字符串

{    

    throw "字符串不能爲空";

}

}catch(err)

{

    這時候 err輸出的就是 字符串不能爲空
}





24 使用函數來定義對象,然後創建新的對象

創建一個object對象 並且爲對象的屬性賦值
poe = new Object()
poe.age = 10
poe.name = "a"

還有另外一種也可以
poe = {age:"10",name:"hahaha"};

document.write("age:"+poe.age)
document.write("name:"+poe.name)

使用函數來創建  


function peop(name,age){
this._name = name;
this._age = age;
this._print = function prints(){
document.write("age:"+this._age+"name:"+this._name);
}
}
peopa = new peop("zhangsan","10")
peopa._print()




25事件詳解

HTML事件處理  

這是一個Button標籤
<button id="btn1">按鈕</button>
<script>
    var btn = document.getElementById("btn1")
    btn.onClick = function(){  函數體代碼  }  點擊這個按鈕會執行這個

</script>

    //如果是這種情況 
    var btn = document.getElementById("btn1")
    btn.onclick = function(){ alert("a")}  這個事件會被覆蓋
   btn.onclick = function(){ alert("b")}   這個事件會執行


這是DOM2級事件處理

addEventListener("事件名","事件處理函數","布爾值")

true事件捕獲,false事件冒泡  這個版本暫時忽略

使用removeEventListener()移除一個事件


var btn = document.getElementById("btn1")
    btn:addEventListener("click",da1)
btn:addEventListener("click",da2)
function da1(){alert("我是事件1")}
function da2(){alert("我是事件2")}  這個事件會依次執行
刪除一個事件
btn:removeEventListener("click",da1)


使用type屬性可獲取事件類型 比如  click  mouseover
target獲取事件目標

stopPropagation() 阻止事件冒泡



26Window對象

innerHeight 瀏覽器內部高度

innerWidth  瀏覽器內部寬度




26 可以設定一個時間間隔來執行代碼 

1setlnterval()間隔 單位毫秒數,不停的執行指定的代碼

clearlnterval()用來停止setlnterval方法的函數代碼

2setTimeout()暫停指定的毫秒數後指定的代碼

clearTimeout 停止執行settimeout方法的代碼


我們每隔1秒 去調用獲取事件

var mytime = setInterval(function(){
 gettime();
},1000)
function gettime(){
var d = new Date();
var t = d.toLocaleTimeString();
document.getElementById("timew").innerHTML=t;
}




26 Location 對象 window.location用來獲取當前頁面的地址(URL)



27 Screen對象

screen.avaliWidth 可用屏幕寬度

screen.availHeigth 可用屏幕高度

screen.heigth  屏幕高度

screen.width  屏幕寬度





28 面向對象





29 prototype

在JavaScript中prototype是實現面向對象的重要機制

每個函數就是一個對象(function)函數對象都有一個子對象,prototype對象,類是

以函數的形式來定義的,prototype表示改函數的圓形,也表示一個類成員的集合





30 function 來模擬類

function Peo(){
}
Peo.prototype.shuo = function(){
alert("說話");
}
實例化
var p = new Peo()
p.shuo()   調用類方法


屬性
Peo.prototype.age 

這個function Peo就相當於構造函數  這樣可以給內部屬性賦值
function Peo(age){
	this._age = age
}

var p = new Peo(30)
alert(p._age)    這裏輸出的就是30



31 類的繼承

function Stu(){
}
繼承自 上面的Peo 
Stu.prototype = new Peo();
調用父類的函數
var s = new Stu();

子類重名 覆蓋父類方法
Peo.prototype.shuo = function(){
	alert("說不出話");
}


如果還想調用父類的方法
var superFunc = Stu.prototype.shuo;
superFunc.call(this);

父類的先構造 然後 子類再構造


成員函數可以直接使用成員屬性

Peo.prototype.shuo = function(){

	alert("說話"+this._age);
}



閉包是外部不能訪問這個對象裏的變量

var n = 10            這個變量可以在任意地方使用
function Peo(age){
this._age = age
alert("父類"+this._age);
}
Peo.prototype.shuo = function(){
alert("說話"+this._age);

}

alert(n) 成功輸出

但是我們可以把他包起來
(function(){
var n = 10
function Peo(age){

	this._age = age
	alert("父類"+this._age);

}

Peo.prototype.shuo = function(){

	alert("說話"+this._age);
}

}());


這樣外部就不能訪問他了


這時候外部不能訪問了,在麼辦呢? 

這裏就要面向對象的封裝了

window.Peo = Peo 使用window對象來記錄這個變量
然後就可以直接使用Peo了









另一種方法 來使用面向對象

首先還是創建一個function


function Per(){
//創建一個空的對象
var _this = {}
_this.shuohua = function(){alert("說話");}
//返回這個對象
return _this;
}


繼承

function ter(){
var _this = Per();
return _this;
}


創建對象 並調用方法

var t = new ter()
t.shuohua();


重寫父類方法

function ter(){
var _this = Per();
_this.shuohua = function(){
alert("不說話");
}
return _this;
}



如果還是要調用父類的方法

function ter(){
var _this = Per();
var superFunc = _this.shuohua;
superFunc.call(this);
_this.shuohua = function(){
alert("不說話");
}
return _this;
}


有參構造和屬性

function Per(name){
//創建一個空的對象
var _this = {}
_this.names = name;
_this.shuohua = function(){
alert("說話");
}
//返回這個對象
return _this;
}

封裝起來


(function(){
function Per(name){
//創建一個空的對象
var _this = {}
_this.names = name;
_this.shuohua = function(){
alert(_this.names+"說話");
}
//返回這個對象
return _this;
}
window.Per = Per;
}());








32代碼模塊

1js裏面代碼可以放在不同的文件裏,稱爲代碼模塊

2一個模塊需要引用其他模塊代碼的時候需要使用require

3require 如果是第一次調用,那麼就加載執行腳本

每個代碼模塊由  module.exports 導出的對象

每次require的時候, 都返回module.exports


假如有一生成隨機數的js文件 裏面的代碼是

var utils = {
random_int:function(start,end){
var num = start+(end-start)*Math.random();
num = Math.floor(index);
return num;
}
};

每個模塊都有一個module.exports 
這時候module.exports 指向的是這個utils
module.exports = utils;


在其他文件裏導入使用

導入代碼 並用變量保存返回值

這裏會判斷是不是第一次執行,如果是第一次他會把js代碼全部加載上來

並執行者整個js文件。然後返回module.exports

如果不是第一次require 那麼就直接返回module.exports



var utls = require("utils")
調用模塊方法
var num = utls.vrandom_int(10,20)


module.exports可以到處表,可以導出數組,還可以導出函數對象









33 this

顯示的傳遞實例, 但參數第一個參數就是this

function test(name,age){
this.name = name;
this.age = age;
}


var xiaoming = {};
test.call(xiaoming,"xiaoming",20);
console.log(xiaoming);

上面輸出的是{name:"xiaoming",age:20}

this就是類似參數似得,可以顯示的傳遞this

上面xiaoming傳到參數裏,其實他就是那個this


通過函數對象.call(對象實例,參數) 這個this指向的就是那個實例





隱式的傳遞實例   其中this就是 xiaohong

他就是將xiaohong作爲this 傳給了這個函數方法

var xiaohong = {
name:"xiaohong",
testfunc = function(){
console.log(this);
}
}
xiaohong.testfunc();

輸出:{name:"xiaohong",testfunc:[Function:test_func]}





還有一種就是強制傳遞this

var func = function(){
console.log(this);
}.bind(xiaohong); 
func();

因爲上面綁定了xiaohong  所以他執行的時候會強制將xiaohong作爲this




bind在原來的對象基礎上,產生了一個新的函數對象

func = func.bind(xiaohong)
func()




也就是會產生一個新的函數對象,這兩個對象指向同一個代碼段,

但是他們有一個this是不同的,這個this就是他綁定的




如果即綁定了this, 又隱式的傳遞this呢

強制綁定優先級高級 隱式傳遞

var xiaohong = {
    name: "xiaohong",
    test_func:function(){
        console.log(this);
    }.bind(4)
};

xiaohong.test_func()
這裏輸出的就是4   因爲他強制綁定了是4




如果用call顯示傳遞 那麼他調用的還是xiaohong 不會輸出4 因爲強制綁定高於他們

var func = function(){
    console.log(this);
}:

func = func.bind(xiaohong);
func();
func.call(4);//顯示傳遞



我們看到 func_test2 他強制綁定了5 那你無論隱式或顯示傳遞他 都是5

var xiaohong = {
name:"xiaohong",
func_test:function(){
console.log(this);
},
func_test2:function(){
console.log(this);
}.bind(5),
}

xiaohong.func_test2()   隱式 最後一個還是5

xiaohong.func_test2.call(20)顯式  輸出還是5


總結一下就是強制綁定this,優先級比其他的都高

顯示call傳遞this高於 





詳解面向對象



函數對象
function person(name,age){
//類成員
this.name = name;
this.age = age;
}
//類方法 
person.prototype.test_func = function(){
console.log("name"+this.name+"  age"+this.age);
}
//實例化對象
var p = new person("小明",20);
p.test_func();


prototype是什麼?

每一個函數對象都會有一個prototype變量, 指向這個對象。

var func_temp = function(){};

console.log(func_temp.prototype) 

這裏輸出的:func_temp{} 

沒錯就是一個空的對象,由於他是一個對象,有了這個那就可以來擴充這個對象key:value

func_temp.prototype.test_func= function(){}



new函數做了什麼?

var data = new func_temp();

第一步:他是把一個空的表給data  var data = {};

第二步:在data裏面加key:valye  key是__protp__  value是 prototype這個對象的賦值 潛賦值

第三步:把這個data作爲實例,this傳給後面的函數

第四步:調用這個函數func_temp 並把data作爲this傳遞

console.log(data.__proto__)
console.log(person.prototype)

上面兩個輸出的都是一樣的 

{test_func:[Function]}

{test_func:[Function]}

所以這兩個func對象都是指向 同一個引用,也就是代碼是用一份,但是他們是兩個表.



__proto__是被隱藏的.


調用方法的時候做了什麼事情呢?

把data 作爲this傳遞給data的__proto__ 這個對象裏面的函數.

data.test_func()

data.__proto__.test_func.call(data);  

上面兩個效果是一樣的,意思是隱式把data作爲this傳遞給__proto__的方法

第二個是顯示的把data作爲this傳遞給__proto__的方法



如果這個key 執行新的value 方法呢?

p.test_func = function(){

console.log("new test_func",this);

}

p.test_func();

這時候上面執行的就是指向的這個新的函數


他首先會在這個實例p的表裏面搜索,有沒有這樣的對象,

如果沒有在到對象的__proto__裏面去搜索。有了之後吧這個實例

作爲this,然後傳遞給這個函數對象.





繼承

var Man = function(){}


//這種做法是不對的,因爲這樣他們是指向同一個對象

Man.prototype = 父類.prototype;

如果這時候要擴展Man的方法的時候, 父類的方法跟着改了。


使用這種方法來複制 原來的 是一個潛拷貝

var super = function(){};

super.prototype =  父類.prototype;

Man.prototype = nwe Super(); //這樣子類複製的是super這個的prototype

這時候new出來的是新的實例,  這時候Man就可以擴展方法了。


如果這時候 Man修改key = 同名函數就是會把 父類的覆蓋掉

如果沒有同名函數 就是擴展這個類。



編寫一個class方法 來定義一個雷,讓他繼承基類

//函數對象 模擬類

function Class(param){
var new_class = function(){};
//這裏就表示有基類 就直接繼承
if(param.extend){
var supers = function(){};
supers.prototype = param.extend.prototype;
new_class.prototype = new supers();
}
//遍歷參數
for(var key in param){
if(key == "extend"){
continue;//這個參數處理過了
}
//把所有參數的函數 加到這裏面來
new_class.prototype[key] = param[key];
}
return new_class;
}
//把這些函數 屬性作爲參數傳遞進去
var Student2 = Class({
extend:person, //設置基類
set_class: function(class_num){
this.classs = class_num;
},
set_grade:function(grade){
this.grade = grade;
},
});
//實例化
var s = new Student2();
//調用
s.set_class(10); 
s.set_grade(2);




發佈一個作業 屬性面向對象:

1熟練的使用require與module.exports;

2熟悉瞭解new與構造函數

3熟悉掌握this,與bind(this),function.call(實例,參數.)

4熟悉掌握js繼承原理

5編寫一個person類,這個類在player.js文件,  

然後編寫一個player類 放在player.js裏面, 繼承了person

 在外部實例化player對象

 在person中編寫一個函數get_name.使用player的實例調用









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章