面向对象三大特征
- 继承 封装 多态(函数工厂根据传参加载不同的类)
- 面向对象写法(构造函数+原型链)
1.属性一般通过this写在构造函数里
2.公有方法一般通过prototype原型对象来写
function Person(name){
this.name=name
}
Person.prototype.eat=function(){
console.log(eat)
}
var p1=new Person('张三')
-
寄生组合继承(构造函数(定义变量的函数)call +原型链(prototype) 复制(Object.create) 重设(constructor) )
1.通过构造函数里的引入父类型的对象,call来改变this的指向子类型,从而继承父类型的私有属性
2.通过new一个父类型,赋值给子类型的prototype,继承父类型的属性和方法(主要),重设子类型的构造函数function Person(options){ options=options || {} //防止我们继承父类型原型链,未赋值导致变量找不 到,其实我们是放在子类型实例中了,搭配new 实例 this.name=options.name || '匿名'//保持代码健壮性 this.age=options.age || 0 } Person.prototype.sayHi=function(){ console.log('nihao') } function Student(options){ //继承父类型构造函数的公有变量 Person.call(this,options) this.score=options.score || 0 this.sex=options.sex || '男' } Student.prototype=Object.create(Person.prototype)//Object.create包裹__proto__创建对象,而不是直接创建对象 /*避免继承了私有属性,还有new实例未传参导致报错,最优解Student.prototype=new Person() 子类型继承父类型中的方法,避免子类型添加的公有方法子会被父类型prototype相同方法名给覆盖 简单来说让parent.__proto__方法扔到child.__proto__.__proto__方法,以区分child与parent的方法*/ Student.prototype.constructor=Student//重设构造函数,解决继承链紊乱 Student.prototype.exam=function(){//不能放在前面 console.log("考试") } var stu1=new Student({name:'三',age:18,score:100,sex:'男'}) stu1.score=80 console.dir(stu1) var stu2=new Student({age:20,score:90,sex:'男'}) console.dir(stu2) var p1=new Person({name:'wo',age:20}) console.dir(p1)
如图所示
instanceof的使用方法
- 检测某个对象是否是另一个对象的实例
- 适用于检查构造函数的实例
- 具体操作:
function Nihao(name){ this.name=name }
var nihao=new Nihao()
console.log(nihao instanceof Nihao)//结果为true
console.log(typeof nihao)//结果为object