㈠構造函數
創建一個構造函數,專門用來創建Person對象的
構造函數就是一個普通的函數,創建方式和普通函數沒有區別,
不同的是構造函數習慣上首字母大寫
構造函數和普通函數的區別就是調用方式的不同
普通函數是直接調用,而構造函數需要使用new關鍵字來調用
示例:創建一個構造函數
function Person(){ alert(this); } var per = new Person(); console.log(per);
瀏覽器中顯示為:
㈡構造函數的執行流程
1.立刻創建一個新的對象
2.將新建的對象設置為函數中this,在構造函數中可以使用this來引用新建的對象
3.逐行執行函數中的代碼
4.將新建的對象作為返回值返回
具體示例如下:
function Person(name , age , gender){ this.name = name; this.age = age; this.gender = gender; this.sayName = function(){ alert(this.name); }; } var per = new Person("孫悟空",18,"男"); var per2 = new Person("玉兔精",16,"女"); var per3 = new Person("奔波霸",38,"男"); console.log(per); console.log(per2); console.log(per3);
結果顯示如下:
㈢類與類的實例
使用同一個構造函數創建的對象,我們稱為一類對象,也將一個構造函數稱為一個類。
我們將通過一個構造函數創建的對象,稱為是該類的實例
具體示例:再創建一個Dog的函數
function Person(name , age , gender){ this.name = name; this.age = age; this.gender = gender; this.sayName = function(){ alert(this.name); }; }
function Dog(){
} var per = new Person("孫悟空",18,"男"); var per2 = new Person("玉兔精",16,"女"); var per3 = new Person("奔波霸",38,"男"); var dog = new Dog(); console.log(per); console.log(dog);
顯示結果為:
㈣ instanceof
使用 instanceof 可以檢查一個對象是否是一個類的實例
語法:對象 instanceof 構造函數
如果是,返回true,否則返回false
具體示例:
function Person(name , age , gender){ this.name = name; this.age = age; this.gender = gender; this.sayName = function(){ alert(this.name); }; } function Dog(){ } var per = new Person("孫悟空",18,"男"); var per2 = new Person("玉兔精",16,"女"); var per3 = new Person("奔波霸",38,"男"); var dog = new Dog(); ①console.log(per instanceof Person); ②console.log(dog instanceof Person);
③console.log(dog instanceof Object);
第一個結果是:true
第二個結果是:false
第三個結果是:true
注意:所有的對象都是Object的后代,所以任何對象和Object做instanceof檢查時都會返回true
㈤代碼優化—將sayName方法在全局作用域中定義
創建一個Person構造函數
在Person構造函數中,為每一個對象都添加了一個sayName方法,目前我們的方法是在構造函數內部創建的
也就是構造函數每執行一次就會創建一個新的sayName方法,也就是所有實例的sayName都是唯一的。
這樣就導致了構造函數執行一次就會創建一個新的方法,
執行10000次就會創建10000個新的方法,而10000個方法都是一模一樣的
這是沒有必要的,完全可以使所有的對象共享同一個方法
具體示例如下:
function PersonOne(name , age , gender){ this.name = name; this.age = age; this.gender = gender; //向對象中添加一個方法 this.sayName = fun; } //將sayName方法在全局作用域中定義 function fun(){ alert("Hello大家好,我是:"+this.name); }; //創建一個Person的實例 var per = new PersonOne("孫悟空",18,"男"); var per2 = new PersonOne("豬八戒",28,"男"); per.sayName(); per2.sayName(); console.log(per.sayName == per2.sayName); 結果為:true
注意:這種方法有一定的問題:將函數定義在全局作用域,污染了全局作用域的命名空間,而且定義在在全局作用域中也很不安全
㈥代碼優化2—原型中添加sayName方法
上面的代碼該如何繼續優化呢?那么可以怎么改呢?向原型中添加sayName方法
以后我們創建構造函數時,可以將這些對象共有的屬性和方法,統一添加到構造函數的原型對象中,
這樣不用分別為每一個對象添加,也不會影響到全局作用域,就可以使每個對象都具有這些屬性和方法了
具體示例:
function PersonOne(name , age , gender){ this.name = name; this.age = age; this.gender = gender; } //向原型中添加sayName方法 PersonThree.prototype.sayName = function(){ alert("Hello大家好,我是:"+this.name); }; //創建一個Person的實例 var per = new PersonThree("孫悟空",18,"男"); var per2 = new PersonThree("豬八戒",28,"男"); per.sayName(); per2.sayName();