1. 程式人生 > >06-js中的中的面向對象 定時器

06-js中的中的面向對象 定時器

-s 常用 cti 初始化 刷新 單位 使用字符串 前端 操作

創建對象的幾種常用方式

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 二者共享同一函數

14 定時器

在js中的定時器分兩種:1、setTimeout() 2、setInterval()

1.setTimeOut()

只在指定時間後執行一次

技術分享圖片
/定時器 異步運行  
function hello(){  
alert("hello");  
}  
//使用方法名字執行方法  
var t1 = window.setTimeout(hello,1000);  
var t2 = window.setTimeout("hello()",3000);//使用字符串執行方法  
window.clearTimeout(t1);//去掉定時器
技術分享圖片

2.setInterval()

在指定時間為周期循環執行

技術分享圖片
/實時刷新  時間單位為毫秒  
setInterval(‘refreshQuery()‘,8000);   
/* 刷新查詢 */  
function refreshQuery(){  
  console.log(‘每8秒調一次‘) 
}
技術分享圖片

兩種方法根據不同的場景和業務需求擇而取之,

對於這兩個方法,需要註意的是如果要求在每隔一個固定的時間間隔後就精確地執行某動作,那麽最好使用setInterval,而如果不想由於連續調用產生互相幹擾的問題,尤其是每次函數的調用需要繁重的計算以及很長的處理時間,那麽最好使用setTimeout

06-js中的中的面向對象 定時器