01 構(gòu)造函數(shù)內(nèi)部設(shè)置方法(函數(shù)傳值)函數(shù)傳值:可以把構(gòu)造函數(shù)的對象方法抽取為參數(shù)
<script>
//001 創(chuàng)建一個構(gòu)造函數(shù)
function Person(name,age,toDoSomeThing) {
//002 在構(gòu)造函數(shù)內(nèi)部設(shè)置對象的屬性和方法
this.name = name;
this.age = age;
this.sayName = function () {
console.log(this.name);
};
this.toDoSomeThing = toDoSomeThing;
}
//003 使用構(gòu)造函數(shù)創(chuàng)建對象
var zhangsan = new Person("張三",18,function () {
console.log("張三在讀書");
});
var lisi = new Person("李四",20,function () {
console.log("李四在玩耍");
});
//004 打印對象的屬性
console.log(zhangsan.name);
console.log(zhangsan.age);
console.log(lisi.name);
console.log(lisi.age);
//005 調(diào)用對象的方法
console.log("__________________");
zhangsan.sayName();
zhangsan.toDoSomeThing();
lisi.sayName();
lisi.toDoSomeThing();
</script>
02 對象類型
檢查對象的類型:instanceOf 獲取對象的類型:Object.prototype.toString.call(dog)
-
對象的構(gòu)造器屬性
function Dog(name) {
this.name = name;
this.color = "黃色";
}
console.log(dog.constructor);
** 屬性的名稱:constructor**
** 屬性的作用:指向創(chuàng)建該對象的構(gòu)造函數(shù),類似于現(xiàn)實生活中所有的產(chǎn)品都標(biāo)有生產(chǎn)廠家一樣**
-
構(gòu)造函數(shù)的調(diào)用
01 構(gòu)造函數(shù)可以像普通函數(shù)一樣不通過new關(guān)鍵字直接調(diào)用
02 在使用構(gòu)造函數(shù)創(chuàng)建對象的時候,如果沒有傳遞參數(shù),則()可以省略
-
代碼示例
//01 創(chuàng)建構(gòu)造函數(shù)
function Person() {
this.name = "張三";
this.age = 20;
this.sayName = function () {
console.log(this.name);
}
}
//02 使用構(gòu)造函數(shù)創(chuàng)建對象
var p1 = new Person();
var p2 = new Person; //說明:如果不需要傳遞參數(shù),則在調(diào)用構(gòu)造函數(shù)的時候()可以省略
-
this
01 如果使用new 構(gòu)造函數(shù)的方式調(diào)用,則this指向內(nèi)部默認(rèn)創(chuàng)建出來的空對象
02 如果像調(diào)用普通函數(shù)一樣調(diào)用構(gòu)造函數(shù),則this指向全局對象window(不要這樣使用)
<script>
//01 獲得內(nèi)置對象的類型
var obj = {};
console.log(obj.toString());
var arr = [];
console.log(arr.toString()); //無法獲取正確的輸出
console.log(Object.prototype.toString.call(arr)); //[object Array]
//02 創(chuàng)建構(gòu)造函數(shù)
function Dog() {
this.name = "阿黃";
this.color = "黃色";
}
//03 使用構(gòu)造函數(shù)創(chuàng)建對象
var dog = new Dog();
//04 獲得構(gòu)造函數(shù)創(chuàng)建的對象的類型
console.log(Object.prototype.toString.call(dog)); //[object Object] 并非Dog類型
//思考:為什么dog對象的類型不是Dog?
//解答:回想構(gòu)造函數(shù)的執(zhí)行過程,構(gòu)造函數(shù)生成的對象是通過new Object()方式創(chuàng)建后賦值給this的,因此其類型為Object
//instanceOf 用于檢查對象的類型
</script>
03 對象的類型檢查和構(gòu)造屬性
<script>
//01 創(chuàng)建兩個構(gòu)造函數(shù),分別用來構(gòu)造Dog對象和Cat對象
function Dog(name) {
this.name = name;
this.color = "黃色";
}
function Cat(name) {
this.name = name;
this.color = "黑色";
}
//02 創(chuàng)建具體的對象
var dog = new Dog("阿黃");
var cat = new Cat("小花");
//03 驗證dog和cat對象都是Object類型的
console.log(dog instanceof Object); //true
console.log(cat instanceof Object); //true
console.log(dog instanceof Dog); //true
console.log(dog instanceof Cat); //false
console.log(cat instanceof Cat); //true
console.log(cat instanceof Dog); //false
//04 對象中的構(gòu)造屬性
console.log(dog.constructor); //該屬性指向創(chuàng)建該對象的構(gòu)造函數(shù)(類似于現(xiàn)實生活中所有的產(chǎn)品都標(biāo)有生產(chǎn)廠家一樣)
console.log(cat.constructor);
//console.log(dog.constructor.constructor); //Function 函數(shù)的構(gòu)造函數(shù)是Function
//console.log(Dog.constructor.constructor); //Function 的構(gòu)造函數(shù)是本身
console.log(Object.constructor); //Function
</script>
示例:
<script>
//01 創(chuàng)建構(gòu)造函數(shù)
function Person() {
this.name = "張三";
this.age = 20;
this.sayName = function () {
console.log(this.name);
}
}
//02 使用構(gòu)造函數(shù)創(chuàng)建對象
var p1 = new Person();
var p2 = new Person; //說明:如果不需要傳遞參數(shù),則在調(diào)用構(gòu)造函數(shù)的時候()可以省略
console.log(p1.name);
console.log(p2.name);
//03 直接調(diào)用構(gòu)造函數(shù)
//構(gòu)造函數(shù)可以不通過關(guān)鍵new調(diào)用(注意:這是一種錯誤的演示)
Person();
console.log(window.name); //張三
window.sayName(); //張三
//總結(jié):如果通過new關(guān)鍵字調(diào)用構(gòu)造函數(shù),則this指向的是新創(chuàng)建出來的對象
// 如果像調(diào)用普通函數(shù)一樣調(diào)用構(gòu)造函數(shù),則this指向的是window全局對象
// 因為在構(gòu)造函數(shù)內(nèi)部并為創(chuàng)建任何新的對象,this上面設(shè)置的屬性和方法此時會被附加到window上面
// 要謹(jǐn)防不通過new關(guān)鍵字直接調(diào)用構(gòu)造函數(shù)
//04
function Person() {
this.name = "張三";
this.age = 20;
this.sayName = function () {
console.log(this.name);
}
}
</script>
總結(jié):
如果通過new關(guān)鍵字調(diào)用構(gòu)造函數(shù),則this指向的是新創(chuàng)建出來的對象
如果像調(diào)用普通函數(shù)一樣調(diào)用構(gòu)造函數(shù),則this指向的是window全局對象
因為在構(gòu)造函數(shù)內(nèi)部并為創(chuàng)建任何新的對象,this上面設(shè)置的屬性和方法此時會被附加到window上面
要謹(jǐn)防不通過new關(guān)鍵字直接調(diào)用構(gòu)造函數(shù)
–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
-
構(gòu)造函數(shù)創(chuàng)建對象存在的問題
<script>
//代碼示例:提供一個構(gòu)造函數(shù),用于創(chuàng)建人對象,需要包含以下屬性和方法
//屬性:學(xué)號、姓名、年齡
//行為:吃飯、閱讀
//01 提供構(gòu)造函數(shù)
function Student(number,name,age) {
//02 設(shè)置對象的屬性
this.number = number;
this.name = name;
this.age = age;
//03 設(shè)置對象的方法
this.eat = function () {
console.log("eat");
};
this.read = function () {
console.log("閱讀");
}
}
//04 創(chuàng)建學(xué)生對象
var stu1 = new Student("20170201","張佳佳",18);
var stu2 = new Student("20170202","劉小溪",20);
//05 比較并驗證對象的方法
//說明:
console.log(stu1.eat == stu2.eat); //打印結(jié)果為false,說明每次創(chuàng)建對象,都會重新創(chuàng)建函數(shù)
//問題:如果創(chuàng)建的對象數(shù)量很多,而對象方法內(nèi)部的實現(xiàn)一模一樣,則造成了資源浪費
</script>
-
解決因每次都會創(chuàng)建新的函數(shù)而造成的資源浪費問題
<script>
//01 提供構(gòu)造函數(shù)
function Student(number,name,age) {
//02 設(shè)置對象的屬性
this.number = number;
this.name = name;
this.age = age;
//03 設(shè)置對象的方法
this.eat = eatFunction;
this.read = function () {
console.log("閱讀");
}
}
var eatFunction = function () {
console.log("eat");
};
//04 創(chuàng)建具體的學(xué)生對象
var stu1 = new Student("20170201","張佳佳",18);
var stu2 = new Student("20170202","劉小溪",20);
//05 比較并驗證多個對象是否實現(xiàn)方法的共享
console.log(stu1.eat == stu2.eat); //true
//嘗試讓所有的對象共用一個方法,在構(gòu)造函數(shù)外部先定義好指定的函數(shù),然后將該指定的函數(shù)賦值給函數(shù)內(nèi)部的方法
//06 == 等于符號補充
//等于符號在進行比較的時候,只會比較值是否相等
//在比較基本數(shù)據(jù)類型的時候,比較變量(表達式)對應(yīng)的值[具體的數(shù)據(jù)]是否相等
//在比較引用數(shù)據(jù)類型的時候,比較對象對應(yīng)的值(引用地址)是否相等
</script>
-
新的問題
① 全局變量增多,造成污染
② 代碼結(jié)構(gòu)混亂,不易維護
③ 函數(shù)可以不通過對象直接調(diào)用,封裝性不好