面向對象
面向對象的本質是對面向過程的封裝
面向對象三大特徵:封裝、繼承、多態
封裝
將某個具體功能封裝在對象中,對外部暴露指定的接口,外界使用時無需考慮內部是如何實現的
function person(name,age,country){
this.name = name;
this.age = age;
this.country = country;
}
var person1 = new person('lin','30','china');
console.log(person1.name);//lin
繼承
一個對象可以擁有其他對象的屬性和方法,通過混入+替換原型的方式繼承
例1
var car = {
tyre:4,
wheel:'left'
}
car.energy = 'gasoline';
function Audi(){
this.brand = 'Audi';
};
for(var key in car){
Audi.prototype[key] = car[key];
}
var audi = new Audi();
console.log(audi.tyre);//4
console.log(audi.energy);//gasoline
例2
function car(){
this.tyre = 4;
this.wheel = 'left';
}
car.prototype.energy = 'gasoline';
function Audi(){
this.brand = 'Audi';
};
Audi.prototype = new car();
Audi.prototype.constructor = car;
var audi = new Audi();
console.log(audi.tyre);//4
console.log(audi.energy);//gasoline
多態
一個對象在不同情況下的多種狀態
var A = {
start:function(){
console.log("start A");
}
}
var B = {
start:function(){
console.log("start B");
}
}
var C = {
start:function(){
console.log("start C");
}
}
function go(fn){
if(fn.start instanceof Function){
fn.start();
}
}
go(A);//start A
go(B);//start B
go(C);//start C
原型
原型(prototype)
每個構造函數在創建時都會生成與之對應的原型對象。由該構造函數實例化的對象可以訪問這個原型中的屬性與方法。
//名爲human的構造函數
function human(){}
//構造函數原型中添加一個屬性
human.prototype.essence = 'Repeater';
var somebody = new human();
console.log(somebody.essence);
__proto__
是實例化對象訪問原型的方法,該方法不是W3C標準屬性所以一般不使用__proto__來訪問原型
原型鏈
因爲原型對象本身也是對象,所以原型也有它的原型,這樣一個鏈式結構稱爲【原型鏈】。內置對象(Array、Date、String…)的原型都指向Object.prototype,構造函數是object。
constructor
屬於原型對象,指向這個原型對應的構造函數,可以得知某個實例對象到底是由哪個構造函數生成的。
var somebody = new human();
console.log(somebody.constructor);
instanceof運算符
檢測構造函數的原型prototype在不在這個對象的原型鏈上(驗證一個對象是不是指定的構造函數的實例)。
只能檢測對象,所以檢測基本數據類型(String,Number等)無效
function fn(){
this.jump = function () {}
};
var arr = [];
var fn1 = new fn();
console.log(arr instanceof Array);//true
console.log(fn1.jump instanceof Function);//true
console.log(fn1 instanceof fn);//true