JavaScript基礎四
1.13 Js中的面向對象
1.13.1 創建對象的幾種常用方式
1.使用Object或對象字面量創建對象
2.工廠模式創建對象
3.構造函數模式創建對象
4.原型模式創建對象
1.使用Object或對象字面量創建對象
JS中最基本創建對象的方式:
var student = new Object(); student.name = "easy"; student.age = "20";
這樣,一個student對象就創建完畢,擁有2個屬性name
以及age
,分別賦值為"easy"
和20
。
如果你嫌這種方法有一種封裝性不良的感覺。來一個對象字面量方式創建對象。
var sutdent = { name : "easy", age : 20 };
這樣看起來似乎就完美了。但是馬上我們就會發現一個十分尖銳的問題:當我們要創建同類的student1,student2,…,studentn時,我們不得不將以上的代碼重復n次....
var sutdent1 = {
name : "easy1",
age : 20
};
var sutdent2 = {
name : "easy2",
age : 20
};
...
var sutdentn = {
name : "easyn",
age : 20
};
有個提問?能不能像工廠車間那樣,有一個車床就不斷生產出對象呢?我們看”工廠模式”。
2.工廠模式創建對象
JS中沒有類的概念,那麽我們不妨就使用一種函數將以上對象創建過程封裝起來以便於重復調用,同時可以給出特定接口來初始化對象
function createStudent(name, age) { var obj = new Object(); obj.name = name; obj.age = age; return obj; } var student1 = createStudent("easy1", 20); var student2 = createStudent("easy2", 20); ... var studentn = createStudent("easyn", 20);
這樣一來我們就可以通過createStudent函數源源不斷地”生產”對象了。看起來已經高枕無憂了,但貪婪的人類總有不滿足於現狀的天性:我們不僅希望”產品”的生產可以像工廠車間一般源源不斷,我們還想知道生產的產品究竟是哪一種類型的。
比如說,我們同時又定義了”生產”水果對象的createFruit()函數:
function createFruit(name, color) {
var obj = new Object();
obj.name = name;
obj.color = color;
return obj;
}
var v1 = createStudent("easy1", 20);
var v2 = createFruit("apple", "green");
對於以上代碼創建的對象v1、v2,我們用instanceof操作符去檢測,他們統統都是Object類型。我們的當然不滿足於此,我們希望v1是Student類型的,而v2是Fruit類型的。為了實現這個目標,我們可以用自定義構造函數的方法來創建對象
3.構造函數模式創建對象
在上面創建Object這樣的原生對象的時候,我們就使用過其構造函數:
var obj = new Object();
在創建原生數組Array類型對象時也使用過其構造函數:
var arr = new Array(10); //構造一個初始長度為10的數組對象
在進行自定義構造函數創建對象之前,我們首先了解一下構造函數
和普通函數
有什麽區別。
1、實際上並不存在創建構造函數的特殊語法,其與普通函數唯一的區別在於調用方法。對於任意函數,使用new操作符調用,那麽它就是構造函數;不使用new操作符調用,那麽它就是普通函數。
2、按照慣例,我們約定構造函數名以大寫字母開頭,普通函數以小寫字母開頭,這樣有利於顯性區分二者。例如上面的new Array(),new Object()。
3、使用new操作符調用構造函數時,會經歷(1)創建一個新對象;(2)將構造函數作用域賦給新對象(使this指向該新對象);(3)執行構造函數代碼;(4)返回新對象;4個階段。
ok,了解了構造函數
和普通函數
的區別之後,我們使用構造函數將工廠模式
的函數重寫,並添加一個方法屬性:
function Student(name, age) {
this.name = name;
this.age = age;
this.alertName = function(){
alert(this.name)
};
}
function Fruit(name, color) {
this.name = name;
this.color = color;
this.alertName = function(){
alert(this.name)
};
}
這樣我們再分別創建Student和Fruit的對象:
var v1 = new Student("easy", 20); var v2 = new Fruit("apple", "green");
這時我們再來用instanceof操作符來檢測以上對象類型就可以區分出Student以及Fruit了:
alert(v1 instanceof Student); //true
alert(v2 instanceof Student); //false
alert(v1 instanceof Fruit); //false
alert(v2 instanceof Fruit); //true
alert(v1 instanceof Object); //true 任何對象均繼承自Object
alert(v2 instanceof Object); //true 任何對象均繼承自Object
這樣我們就解決了工廠模式
無法區分對象類型的尷尬。那麽使用構造方法來創建對象是否已經完美了呢?使用構造器函數通常在js中我們來創建對象。
我們會發現Student和Fruit對象中共有同樣的方法,當我們進行調用的時候這無疑是內存的消耗。
我們完全可以在執行該函數的時候再這樣做,辦法是將對象方法移到構造函數外部:
function Student(name, age) {
this.name = name;
this.age = age;
this.alertName = alertName;
}
function alertName() {
alert(this.name);
}
var stu1 = new Student("easy1", 20);
var stu2 = new Student("easy2", 20);
在調用stu1.alertName()時,this對象才被綁定到stu1上。
我們通過將alertName()函數定義為全局函數,這樣對象中的alertName屬性則被設置為指向該全局函數的指針。由此stu1和stu2共享了該全局函數,解決了內存浪費的問題
但是,通過全局函數的方式解決對象內部共享的問題,終究不像一個好的解決方法。如果這樣定義的全局函數多了,我們想要將自定義對象封裝的初衷便幾乎無法實現了。更好的方案是通過原型對象模式來解決。
4.原型的模式創建對象
原型鏈甚至原型繼承,是整個JS中最難的一部分也是最不好理解的一部分,在這裏由於我們課程定位的原因,如果對js有興趣的同學,可以去查閱一下相關JS原型的一些知識點。更加有助於你以後前端JS的面試。
function Student() {
this.name = ‘easy‘;
this.age = 20;
}
Student.prototype.alertName = function(){
alert(this.name);
};
var stu1 = new Student();
var stu2 = new Student();
stu1.alertName(); //easy
stu2.alertName(); //easy
alert(stu1.alertName == stu2.alertName); //true 二者共享同一函數
1.14 定時器
在js中的定時器分兩種:1、setTimeout() 2、setInterval()
1.14.1 setTimeOut()
只在指定時間後執行一次
/定時器 異步運行
function hello(){
alert("hello");
}
//使用方法名字執行方法
var t1 = window.setTimeout(hello,1000);
var t2 = window.setTimeout("hello()",3000);//使用字符串執行方法
window.clearTimeout(t1);//去掉定時器
1.14.2 setInterval()
在指定時間為周期循環執行
/實時刷新 時間單位為毫秒
setInterval(‘refreshQuery()‘,8000);
/* 刷新查詢 */
function refreshQuery(){
console.log(‘每8秒調一次‘)
}
兩種方法根據不同的場景和業務需求擇而取之,
對於這兩個方法,需要註意的是如果要求在每隔一個固定的時間間隔後就精確地執行某動作,那麽最好使用setInterval,而如果不想由於連續調用產生互相幹擾的問題,尤其是每次函數的調用需要繁重的計算以及很長的處理時間,那麽最好使用setTimeout
1.15 BOM
JavaScript基礎分為三個部分:
-
ECMAScript:JavaScript的語法標準。包括變量、表達式、運算符、函數、if語句、for語句等。
-
DOM:文檔對象模型,操作網頁上的元素的API。比如讓盒子移動、變色、輪播圖等。
-
BOM:瀏覽器對象模型,操作瀏覽器部分功能的API。比如讓瀏覽器自動滾動。
1.15.1 什麽是BOM
BOM:Browser Object Model,瀏覽器對象模型。
BOM的結構圖:
從上圖也可以看出:
-
window對象是BOM的頂層(核心)對象,所有對象都是通過它延伸出來的,也可以稱為window的子對象。
-
DOM是BOM的一部分。
window對象:
-
window對象是JavaScript中的頂級對象。
-
全局變量、自定義函數也是window對象的屬性和方法。
-
window對象下的屬性和方法調用時,可以省略window。
下面講一下 BOM 的常見內置方法和內置對象。
1.15.2 彈出系統對話框
比如說,alert(1)
是window.alert(1)
的簡寫,因為它是window的子方法。
系統對話框有三種:
alert(); //不同瀏覽器中的外觀是不一樣的 confirm(); //兼容不好 prompt(); //不推薦使用
1.15.3 打開窗口、關閉窗口
1、打開窗口:
window.open(url,target)
參數解釋:
-
url:要打開的地址。
-
target:新窗口的位置。可以是:
_blank
、_self
、_parent
父框架。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <!--行間的js中的open() window不能省略--> <button onclick="window.open(‘https://www.luffycity.com/‘)">路飛學城</button> <button>打開百度</button> <button onclick="window.close()">關閉</button> <button>關閉</button> </body> <script type="text/javascript"> var oBtn = document.getElementsByTagName(‘button‘)[1]; var closeBtn = document.getElementsByTagName(‘button‘)[3]; oBtn.onclick = function(){ //open(‘https://www.baidu.com‘) //打開空白頁面 open(‘about:blank‘,"_self") } closeBtn.onclick = function(){ if(confirm("是否關閉?")){ close(); } } </script> </html>
1.15.4 location對象
window.location
可以簡寫成location。location相當於瀏覽器地址欄,可以將url解析成獨立的片段。
location對象的屬性
-
href:跳轉
-
hash 返回url中#後面的內容,包含#
-
host 主機名,包括端口
-
hostname 主機名
-
pathname url中的路徑部分
-
protocol 協議 一般是http、https
-
search 查詢字符串
location.href屬性舉例:
舉例1:點擊盒子時,進行跳轉。
<body> <div>smyhvae</div> <script> var div = document.getElementsByTagName("div")[0]; div.onclick = function () { location.href = "http://www.baidu.com"; //點擊div時,跳轉到指定鏈接 // window.open("http://www.baidu.com","_blank"); //方式二 } </script> </body>
舉例2:5秒後自動跳轉到百度。
有時候,當我們訪問一個不存在的網頁時,會提示5秒後自動跳轉到指定頁面,此時就可以用到location。舉例:
<script> setTimeout(function () { location.href = "http://www.baidu.com"; }, 5000); </script>
location對象的方法
location.reload():重新加載
setTimeout(function(){
//3秒之後讓網頁整個刷新
window.location.reload();
},3000)
1.15.5 navigator對象
window.navigator 的一些屬性可以獲取客戶端的一些信息。
-
userAgent:系統,瀏覽器)
-
platform:瀏覽器支持的系統,win/mac/linux
例子:
console.log(navigator.userAgent);
console.log(navigator.platform);
1.15.6 history對象
1、後退:
-
history.back()
-
history.go(-1):0是刷新
2、前進:
-
history.forward()
-
history.go(1)
用的不多。因為瀏覽器中已經自帶了這些功能的按鈕:
1.16 client、offset、scroll 系列
1.16.1 client
代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> .box{ width: 200px; height: 200px; position: absolute; border: 10px solid red; /*margin: 10px 0px 0px 0px;*/ padding: 80px; } </style> </head> <body> <div class="box"> 哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈
哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈 </div> </body> <script type="text/javascript"> /* * clientTop 內容區域到邊框頂部的距離 ,說白了,就是邊框的高度 * clientLeft 內容區域到邊框左部的距離,說白了就是邊框的亂度 * clientWidth 內容區域+左右padding 可視寬度 * clientHeight 內容區域+ 上下padding 可視高度 * */ var oBox = document.getElementsByClassName(‘box‘)[0]; console.log(oBox.clientTop); console.log(oBox.clientLeft); console.log(oBox.clientWidth); console.log(oBox.clientHeight); </script> </html>
屏幕的可視區域
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> </body> <script type="text/javascript"> // 屏幕的可視區域 window.onload = function(){ // document.documentElement 獲取的是html標簽 console.log(document.documentElement.clientWidth); console.log(document.documentElement.clientHeight); // 窗口大小發生變化時,會調用此方法 window.onresize = function(){ console.log(document.documentElement.clientWidth); console.log(document.documentElement.clientHeight); } } </script> </html>
1.16.2 offset
代碼如下,註釋都挺清楚的
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> *{ padding: 0; margin: 0; } </style> </head> <body style="height: 2000px"> <div> <div class="wrap" style=" width: 300px;height: 300px;background-color: green"> <div id="box" style="width: 200px;height: 200px;border: 5px solid red;position:
absolute;top:50px;left: 30px;"> </div> </div> </div> </body> <script type="text/javascript"> window.onload = function(){ var box = document.getElementById(‘box‘) /* offsetWidth占位寬 內容+padding+border offsetHeight占位高 * offsetTop: 如果盒子沒有設置定位 到body的頂部的距離,如果盒子設置定位,那麽是以父輩為基準的top值 * offsetLeft: 如果盒子沒有設置定位 到body的左部的距離,如果盒子設置定位,那麽是以父輩為基準的left值 * */ console.log(box.offsetTop) console.log(box.offsetLeft) console.log(box.offsetWidth) console.log(box.offsetHeight) } </script> </html>
1.16.3 scroll
代碼如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> *{padding: 0;margin: 0;} </style> </head> <body style="width: 2000px;height: 2000px;"> <div style="height: 200px;background-color: red;"></div> <div style="height: 200px;background-color: green;"></div> <div style="height: 200px;background-color: yellow;"></div> <div style="height: 200px;background-color: blue;"></div> <div style="height: 200px;background-color: gray;"></div> <div id = ‘scroll‘ style="width: 200px;height: 200px;border: 1px solid red;overflow: auto;padding:
10px;margin: 5px 0px 0px 0px;"> <p>路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城 路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城
路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城 路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城
路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城 路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城
路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城路飛學城 </p> </div> </body> <script type="text/javascript"> window.onload = function(){ //實施監聽滾動事件 window.onscroll = function(){ // console.log(1111) // console.log(‘上‘+document.documentElement.scrollTop) // console.log(‘左‘+document.documentElement.scrollLeft) // console.log(‘寬‘+document.documentElement.scrollWidth) // console.log(‘高‘+document.documentElement.scrollHeight) } var s = document.getElementById(‘scroll‘); s.onscroll = function(){ // scrollHeight : 內容的高度+padding 不包含邊框 console.log(‘上‘+s.scrollTop) console.log(‘左‘+s.scrollLeft) console.log(‘寬‘+s.scrollWidth) console.log(‘高‘+s.scrollHeight) } } </script> </html>
JavaScript基礎四