面向对象
面向对象的本质是对面向过程的封装
面向对象三大特征:封装、继承、多态
封装
将某个具体功能封装在对象中,对外部暴露指定的接口,外界使用时无需考虑内部是如何实现的
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