知識點
- 面向對象的三大特性
- 封裝
- 繼承
- 多態
- 創建對象的幾種方式
- 字面量形式
- 使用內置構造函數
- 封裝簡單的工廠函數
- 自定義構造函數
- 構造函數
- 什么是構造函數?
- 對象的創建過程
- 構造函數的返回值
- 對象是無序的鍵值對兒的集合
- 如果像使用正常的函數一樣使用構造函數
- 獲取對象類型
面向對象的三大特性
封裝
對象是將數據與功能組合到一起, 即封裝
- js 對象就是 鍵值對的集合
- 鍵值如果是數據( 基本數據, 復合數據, 空數據 ), 就稱為屬性
- 如果鍵值是函數, 那么就稱為方法
- 對象就是將屬性與方法封裝起來
- 方法是將過程封裝起來
//封裝
var name = "張學友";
var age = 18;
function sayHello(){
console.log("hello world");
}
var obj = {
name : "劉德華",
age : 50,
sayHello : function () {
//.....
}
}
var itcast = {
getEle:{
},
}
繼承
所謂繼承就是自己沒有, 別人有,拿過來為自己所用, 并成為自己的東西
讓某個類型的對象獲得另一個類型的對象的屬性的方法
- js 繼承基于對象
- 在JavaScript中,繼承就是當前對象可以使用其他對象的方法和屬性。
- js繼承實現舉例:混入(mix)
function mix ( o1, o2 ) {
for ( var k in o2 ) {
o1[ k ] = o2[ k ];
}
}
<script>
//繼承
//javaScript當中的繼承是指
//一個對象沒有一些方法和屬性,但是另外一個對象有
//把另外一個對象的屬性和方法,拿過來使用,就是繼承
var obj = {
};
var obj1 = {
name : "張學友",
sayHello: function () {
console.log("你好,我是張學友");
}
}
// obj.sayHello();
//混入式繼承(mix-in) for in
for(var k in obj1){
//k可以獲取到對象的每一個屬性
//obj1[k]可以獲取到對象的每一個屬性的值
//這里使用k給對象新增屬性的時候,不可以使用點語法
obj[k] = obj1[k];
}
obj.sayHello();
</script>
多態
- 把不同的子類對象都當作父類來看,可以屏蔽不同子類對象之間的差異,寫出通用的代碼,做出通用的編程,以適應需求的不斷變化。
- 多態是在強類型語言中比較常用,JavaScript中沒有相應的體現
- 使用父類的引用(指針)指向子類的對象 就叫做多態
- 使用多態來隱藏不同
動物 animal = new 子類(); // 子類:麻雀、狗、貓、豬、狐貍...
動物 animal = new 狗();
animal.叫();
創建對象的方式
- 字面量形式
只能創建一次對象,復用性較差,如果要創建多個對象,代碼冗余度太高
var obj = {
name:"演員",
singer:"薛段子手",
type:"流行"
};
var obj1 ={
name:"吻別",
singer:"張學友",
type:"流行"
}
- 使用內置構造函數
//使用內置構造函數
var obj = new Object();
obj.name = "一千個傷心的牛油";
obj.singer = "張學友";
obj.sing = function () {
console.log("一千個傷心的牛油");
}
var obj2 = new Object();
obj2.name = "一千個傷心的牧流";
obj2.singer = "張學友";
obj2.sing = function () {
console.log("一千個傷心的牧流");
}
- 封裝簡單的工廠函數
本質還是內置構造函數,已經不推薦使用了
function createSong(SingerName,SingName){
var obj = new Object();
obj.name = SingerName;
obj.singer = SingName;
obj.sing = function () {
console.log("一千個傷心的牛油");
}
return obj;
}
var obj = createSong("一千個傷心的牛油","張學友");
自定義構造函數
- 什么是構造函數?
- 構造函數其實也是函數,但是通常用來初始化對象,并且和new關鍵字同時出現
- new 是用來創建對象的,構造函數是用來初始化對象的(給對象新增成員)
- 構造函數名,首字母要大寫!以示區分
<script type="text/javascript">
//自定義構造函數
function Person(){
//默認隱含的操作,把剛才用new新創建出來的對象賦值給this
this.name = "美女";
this.age = 45;
this.sayPaPa = function () {
console.log("啪啪");
}
// return 123;
return [1,2];
}
var p = new Person();
console.log(p);
p.sayPaPa();
</script>
- 對象的創建過程
function Person(name, age){
this.name = name;
this.age = age;
}
var p = new Person();
以上面這個p對象創建為例:
首先使用new關鍵字創建對象,類似于使用{},這個時候創建出來的對象是一個"沒有任何成員"的對象。這里需要注意兩點:
1, 使用new關鍵字創建的對象,對象的類型就是創建這個對象使用的構造函數的函數名
2, 使用{}創建對象,對象的類型一定是Object,相當于使用了new Object()使用構造函數為其初始化成員
1, 在構造函數調用開始的時候,有一個賦值操作,也就是讓this = 剛創建出來的對象
2, 在構造函數中,this就代表剛創建出來的對象在構造函數中,利用對象的動態特性,為對象添加成員
構造函數的執行過程
- 使用new關鍵字創建對象
- 調用構造函數,把新創建出來的對象賦值給構造函數內的this
- 在構造函數內使用this為新創建出來的對象新增成員
- 默認返回新創建的這個對象 (普通的函數,如果不寫返回語句,會返回undefined)
- 構造函數的返回值
- 如果不寫返回值,默認返回的是新創建出來的對象 (一般都不會去寫這個return語句)
- 如果我們自己寫return語句 return的是空值(return;),或者是基本類型的值或者null,都會默認返回新創建出來的對象
- 如果返回的是object類型的值,將不會返回剛才新創建的對象,取而代之的是return后面的值
- 對象是無序的鍵值對兒的集合
function Animal(name, type, barkWay) {
this.name = name;
this.type = type;
this.bark = barkWay;
}
- 如果像使用正常的函數一樣使用構造函數
- 構造函數中的this將不再指向新創建出來的對象(因為根本就沒有創建對象)
- 構造函數中的this這個時候指向的就是window全局對象
- 當使用this給對象添加成員的時候,全部都添加到了window上
Animal("","",function () {
console.log("我是函數");
}); //這是一個錯誤的演示
window.bark();
- 獲取對象類型
-
typeof 對象實例
,獲取的是object
var dog = new Animal("大黃","BYD",function () {
console.log("汪汪汪");
});
console.log(dog);
var cat = new Animal("小花","BSM",function () {
console.log("喵喵喵");
});
console.log(typeof cat);//object
- js中提供了兩個方法來調用其他對象的方法:
call、apply
- 獲取具體類型的方式
var typeStr = Object.prototype.toString.call(想獲取類型的對象)
typeStr = typeStr.slice(8, -1);