1、 基本語法
1.函數中聲明變量不使用var 就是全局變量,變量不使用var,屬於window的一個屬性
2.Js數據類型 Number,String,Array,Date
3. 調用屬性方式
4. 時間對象
5. js中array 就是java list和stack
6. 事件綁定方式2
7. window api 定時器
8. 節點概念
代碼實現:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
window.onload=function(){
// 1.函數中聲明變量不使用var 就是全局變量,變量不使用var,屬於window的一個屬性
function fn1(){
c=100;
}
fn1();
console.info(c);
// 2.Js數據類型 Number,String,Array,Date
var a1="11";
// Js進行強制類型轉化,String->Number
console.info(Number(a1)+1);
// NaN來源, 不是數字類型轉化爲NaN
console.info(Number("abc"));
// parseInt把開頭是數字的字符串轉化爲數字,如果開頭不是數字,那就是NaN
var b1= "12px";
console.info(parseInt(b1));
// 判斷類型
console.info((typeof b1)+"");
var c1= (b1 instanceof Number);
console.info(c1+"");
var d1; // undefined這個變量就是,Js中 NaN,undefined,0這個三個數false,其他的都是true
console.info(d1);
// 3. 調用屬性方式
function Person(name){
this.name=name;
}
var p2=new Person("小明");
console.info(p2.name);
console.info(p2["name"]); // 當屬性是變量的時候
// 獲取對象所有屬性 for-in語法
for(var a2 in p2){
console.info(a2,p2[a2]);
}
// 4. 時間對象
var d2=new Date();
// document.write("年:"+d2.getFullYear()+"月:"+(d2.getMonth()+1)+"日:"+d2.getDate()+"星期:"+d2.getDay()+"<br/>");
// 時間戳
// document.write("<br />"+Date.parse(new Date()));
// 5. String 和 java類似
var str2="abcdef";
console.info(str2.indexOf("a")); //搜索
console.info(str2.slice(1,2)); // [) 輸出 b
console.info(str2.substring(1,2)); // [) 輸出 b
console.info(str2.substr(1,2)); // 從1開始取2個字符 輸出 bc
console.info("match",str2.match("adbc")); //輸出匹配結果,失敗返回null
// 例子
var s2="abc.txt"; //獲取.txt前面的東西
console.info(s2.substring(0,s2.lastIndexOf(".")));
//5. js中array 就是java list和stack
var as2=new Array();
as2.push(1); //數組末尾插入,返回數組長度
console.info(as2);
var as21=[1,2];
console.info(as21);
// 把數組轉化爲字符串通過 * 連接
console.info(as21.join(","));
// sort自會通過字符串排序,自定義如果要通過整數
console.info(as21.reverse()); //倒敘
console.info("數據合併",as2.concat(as21));
// stack api
// shift: 刪除返回數組第一個元素
// pop: 刪除返回數組最有一個元素
// unshift:數組頭部插入一個或者更多元素,返回數組長度
// 中間插入元素
// 從哪一個位置刪除多少個元素,添加多少個
// 在索引爲1的地方,之後刪除1個元素,之後插入45,34
as21.splice(1,1,45,34)
console.info("splice",as21); //結果[2,45,34]
// 截取
var as212=[1,2];
console.info(as212.slice(1,2)); // [2]
// toString() 轉化爲字符串
// 6. 事件綁定方式2
var btn1= document.getElementById("btn1");
btn1.onclick=function(){
console.info(this.innerHTML);
}
// ul 下 li 時間綁定
var liArr= document.getElementById("content").getElementsByTagName("li");
for(var i=0;i<liArr.length;i++){
liArr[i].onmouseover=changColorRed;
liArr[i].onmouseout=chageBlack;
}
}
// 給ul下的li綁定事件
function changColorRed(){
this.style.color="#f00";
}
function chageBlack(){
this.style.color="#000";
}
// DOM1
// 簡單事件
function clickD(obj){
console.info(obj.innerHTML);
}
// mouse事件
function mouseD(obj){
obj.style.fontSize="20px";
}
function out(obj){
obj.style.fontSize="10px";
}
// 事件綁定方式2 ,在onload中
// 7. window api 定時器
function show(){
console.info("show....");
}
// setTimeout(show,2000);
var timeId=setInterval(show,3000);
function stopD(obj){
clearInterval(timeId);
}
function goPage(obj){
window.location.href="test.html";
}
//8. 節點概念
function nodeT(){
/**
* <div name='屬性節點'>abc</div>
* div: 元素節點
* name:屬性節點
* abc: 內容節點
* https://www.cnblogs.com/xiaoleidiv/p/3347483.html
*/
var node= document.getElementById("node1");
console.info(node.innerHTML); //內容
console.info(node.nodeName); //名稱
console.info(node.nodeType); // 類型
console.info("文本節點",node.firstChild.nodeValue,node.firstChild.nodeType);
}
</script>
</head>
<body>
<div onclick="clickD(this)">點擊一下</div>
<div id="btn1">事件方式2</div>
<div onmouseover="mouseD(this)" onmouseout="out(this)">鼠標移動上來試試</div>
<div onclick="stopD(this)">停止</div>
<!-- BOM Api
Navigator: 瀏覽器對象,獲取版本...
history: 返回上一個頁面
locaton: 跳轉到某一個頁面,在js中
window: doucument(文檔對象)
DOM Api:
document:
getElementById
getElementsByName: 名稱,返回數組注意 a[0]
getElementsByTagName: 標籤,返回數組注意 a[0]
節點概念:Node
-->
<a href="test.html">下一個頁面</a> <br/>
<a onclick="goPage(this)">跳轉到某一個頁面</a> <br/>
<a href="#" onclick="window.open('test.html','name','width=300,height=300,resizable=0')">打開窗口</a>
<div onclick="nodeT()" id="node1" style="cursor: pointer;">節點概念</div>
<ul id="content">
<li>語文</li>
<li>數學</li>
<li>英語</li>
<li>化學</li>
</ul>
</body>
</html>
2、函數對象
9. 函數與對象內存各自關係
10. js函數重載
11. 函數是一個對象,那麼可以做爲參數傳遞,函數返回值
12. 排序 案例
13. 函數參數,通過arguments獲取參數
14. 函數call apply
15. 對象,創建對象
16.Js中閉包:
17. 正則表達式
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<link rel="shortcut icon" href="#" />
<script type="text/javascript">
window.onload=function(){
/**
* 9. 函數與對象內存各自關係
*/
function f1(){
console.info("f1");
}
var f2=f1;
f2();
/**
* var f2=f1: 把函數在內存中拷貝了一份
* f1變了,不會影響f2,函數拷貝
*/
var obj={
msg:"hello",
}
var obj1= obj;
obj1.msg="jack";
console.info(obj.msg);
/**
* 對象是通過引用來賦值,修改obj1,obj的值也會被修改
* obj1、obj在棧中指向 堆中{}數據
*/
/**
* 10. js函數重載
*/
function sum1(a,b){
return a+b;
}
function sum1(a){
return a;
}
console.info(sum1(10,10)); //10
console.info(sum1(10)); //10
/**
* 輸出的結果都是10爲什麼
var sum=function(a,b){
return a+b;
}
// sum支持函數function(a,b)
var sum=function(a){
return a;
}
// sum 支持函數function(a)
// 那麼funciton(a,b)已經不存在了
// 結果:js函數的調用和函數參數沒有什麼關係,函數不存在重載
*/
/**
* 11. 函數是一個對象,那麼可以做爲參數傳遞
* 1.函數回調
* 2.函數作爲返回值
*/
function callFun(fun,arg){
return fun(arg);
}
function say(str){
alert(str);
}
//callFun(say,"hello");
//2.函數作爲返回值
function returnF(arg){
var rel= function(num){
return arg+num;
}
return rel;
}
var r1= returnF(10);
var r2= r1(20);
//alert(returnF(10)(20));
// 函數作爲返回值使用
// 12. 排序
function sortByNum(a,b){
return a-b;
}
var list=[1,16,4,3]; //可以包含字符串 "11"-1 =10 js可以自動轉化
list.sort();
console.info("默認排序",list); //js 默認數字也是按照字符串來排序
list.sort(sortByNum) // 自定義排序
console.info("之定義排序:",list);
// 測試對象,js創建對象
function Person(name,age) {
this.name = name;
this.age = age;
}
var p1 = new Person("Leno",39);
var p2 = new Person("John",23);
var p3 = new Person("BB",431);
var p4 = new Person("BB",56);
var ps = [p1,p2,p3,p4]; // 如果要使用sort函數,那麼必須要自定義規則
function sortByName(obj1,obj2){
if(obj1.name > obj2.name){
return 1;
}else if(obj1.name == obj2.name){
return 0;
}else {
return -1;
}
}
function sortByAge(obj1,obj2) {
return obj1.age-obj2.age;
}
// ps.sort(sortByName,sortByAge) // 根據多個屬性排序
// console.info(ps);
// 上面代碼問題,如果有多個屬性需要些多次,可以寫一次嗎??
// 如何實現只需要返回上面函數即可
function sortbyProperty(propertyName){
return function(obj1,obj2){
if(obj1[propertyName]>obj2[propertyName]){
return 1;
}else if(obj1[propertyName] == obj2[propertyName]){
return 0;
}else {
return -1;
}
}
}
ps.sort(sortbyProperty("name"))
function show() {
var p = document.getElementById("person");
for(var i=0;i<ps.length;i++) {
p.innerHTML+=ps[i].name+","+ps[i].age+"<br/>";
}
}
show();
/**
* 13. 函數參數,通過arguments獲取參數
* 誰調用函數,函數中this就是誰
* show(): this是 window
* person.show() this就是Person
*/
function showArgs(num){
console.info("argumnt:",arguments.length); // 函數實際傳參個數 這裏是3
console.info("length:",showArgs.length) // 函數形參個數 這裏是1
for(i=0;i<arguments.length;i++){
console.info(arguments[i]);
}
}
showArgs(2,3,4);
// arguments.callee 可以得到當前函數,避免函數名稱變化
function factorial(num){
if(num<1){
return 1;
}else{
return num*arguments.callee(num-1);
}
}
console.info("5的階乘",factorial(5));
/**
* 14. 函數call apply
*/
// 基本用法
function sumC(num1,num2){
return num1+num2;
}
/**
* 用法:參數不同 第一個參數是對象,第二個是數組|參數列表
*/
function callSumC(num1,num2){
return sumC.apply(this,arguments);
// 或者
// return sumC.apply(this,[num1,num2]);
// 或者
return sumC.call(this,num1,num2);
}
console.info("apply...call調用函數:",callSumC(3,4));
/**
* 用途1: 對象中不需要定義方法也可以調用
*/
var color="red";
function showColor(color){
console.info("showColor",color);
}
function Circle(color){
this.color=color;
this.say=function(){
console.info("I am a circle");
}
}
var c=new Circle("black");
showColor.call(c,"black"); // c中沒有定義showColor函數,通過c來調用
showColor("yellow"); // 通過window來調用
/**
* 15. 對象,創建對象
*/
// 方式1. 使用new
var man= new Object();
man.name="小明";
man.age=20;
man.say=function(){
alert("say...man");
}
//man.say();
c.say();
// 直接使用json
var man1={
name:"李四",
say:function(){
alert("say..man1");
}
}
// man1.say();
// 通過Json創建集合
var manList=[
{name:"leon",age:22},
{name:"ada",age:45}
];
for(var k=0;k<manList.length;k++){
console.info("通過json創建集合",manList[k].age+ " "+ manList[k].name);
}
}
/**
* 3.通過構造函數方式創建對象,這裏必須要用this,否則color、say屬於window
*/
function Round(color){
this.color=color;
this.say=function(){
console.info("I am a Round");
}
}
var r1= new Round("red");
var r2= new Round("blue");
r1.say();
// 問題, false ,
// 該函數在棧中this.say,每創建衣一個對象,都會存在一個方法的拷貝,如果對象很多的話,佔用空間比較大
var r_result = ( r1.say == r2.say )
console.info("結果是",r_result);
// 解決方法, 將行爲設置爲全局函數
// 問題:全局函數屬於window,不利於封裝,解決方法,原型
function Round4(color){
this.color=color;
this.say = say2;
}
function say2(){
console.info("i am a Round2");
}
var r4=new Round4("yellow");
console.info("Round4是....:",r4.say == r4.say );
/**
* Js中原型: 自定義類、繼承??? 放一下???
*/
/**
* 匿名函數和普通函數
* 函數作用域:https://blog.csdn.net/dreams_deng/article/details/102148012
*/
// 對於普通函數,可以在聲明前調用函數不會報錯,函數永遠會被最先初始化
fn1();
function fn1(){
console.info("普通函數","fn1");
}
// 如下定義函數,不會被執行,如果在聲明之前調用函數會報錯
// 這個函數開始是沒有名稱的,這個函數就是叫做匿名函數
var fn3= function(){
console.info("匿名函數","fn3");
}
fn3();
/**
* 16.Js中閉包:
* 執行compareObjectFunction 函數以後,理論上形參 prop 裏面的函數 在棧中 都會被內存釋放
* 但是 返回匿名函數,作用域擴大,內存不會被釋放
* 通過返回函數來擴大作用域的方法就是閉包
*/
function compareObjectFunction(prop){
// 這個就是匿名函數,return 返回的
return function(obj1,obj2){
if(obj1[prop]>obj2[prop]){
return 1;
}else if(obj1[prop] == obj2[prop]){
return 0;
}else {
return -1;
}
}
}
var o1={name:"any",age:34};
var o2={name:"tony",age:1};
var compare= compareObjectFunction("name");
console.info("閉包結果是:",compare(o1,o2));
/**
* 閉包帶來問題
*/
var arr=new Array();
for(var i=0;i<10;i++){
arr[i]=function(){
return i;
}
}
// 輸入傳遞內容都是10
// 此事通過閉包來調用函數,當輸出i的時候會去上一級作用域中查找,這個時候ii已經是10,所以會連續輸出10個10
for(var k=0;k<arr.length;k++){
console.info("閉包問題1",k+" "+arr[k]());
}
// 上面問題解決方法,把i 和函數 都保存到數組中
var arr5=new Array();
for(var i=0;i<10;i++){
var tf=function(num){
// 調用該函數的時候回去上一級作用域中查找,tf一直都在
arr5[num]=function(){
return num;
}
}
// 調用函數
tf(i);
}
for(var k=0;k<arr5.length;k++){
console.info("解決閉包問題:",arr5[k]());
}
/**
* 新問題:回調函數中的this
*/
var name1="weixing";
var weiF= {
name1:"qq",
showMsg:function(){
return function(){
return this.name1;
}
}
}
/**
* 調用weiF.showMsg()的時候,這個函數作用域已經結束了,
* 函數結束之前this指向weiF, 之後指向window
*/
console.info("對象中閉包中this",weiF.showMsg()());
// 解決
var weiF= {
name1:"qq",
showMsg:function(){
var that=this;
return function(){
return that.name1;
}
}
}
console.info("對象中閉包中that:",weiF.showMsg()());
/**
* js中沒有塊作用域:
* 這個變量在window下定義,給windowt添加變量
*/
for(var i=0;i<10;i++){
}
// alert(i); // 輸出的結果是10
// 解決
// 在還引入多個js文件的時候,變量污染混亂
// 每個人開發的代碼放入下面
(function(){
}())
// js中如何封裝使用變量
function Person(){
this.setName=function(value){
name=value;
}
this.getName=function(){
return name;
}
}
var ppp = new Person("aa");
ppp.setName("bb");
console.info("js中屬性封裝",ppp.getName());
/**
* 17. 正則表達式
* 擴充已經存在類的原型,去除前後空格
* 複習:
* /s /d /D /w /S
* [] {}
* * + ? ^ $
* /g /i
*/
String.prototype.trim=function(){
return this.replace(/(^\s+)|(\s+$)/g,"");
}
/**
* 去除所有空格
*/
String.prototype.trimAll=function(){
return this.replace(/\s+/g,"");
}
var hh="A 憨憨 ";
console.info("擴充原型:",hh.trim());
console.info("去除所有空格",hh.trimAll());
</script>
</head>
<body>
<div id="person"></div>
</body>
</html>