1.面向对象
面向对象和面向过程
面向过程,关注点在于过程,将我们要解决的问题进行流程化,关注于我们每一步要解决什么问题,再将流程串联起来
面向对象:要将我们解决的问题抽象,抽象出来,更关注于对象本身以及他要去处理的事情以及属性
prototype显示原型
2.原型链继承
function Person(){
this.name="zhaobo"
}
Person.prototype.eating = function(){
console.log(this.name + ' 在吃饭')
}
function Student(){
this.sno = 18103420
}
Student.prototype.studying = function(){
console.log(this.sno + ' 在学习')
}
let stu = new Student()
stu.eating()
stu.studying()
可以发现student类想要调用eating方法的话,直接调用会出现stu.eating is not defined
student.prototype里面拿不到所谓的eating 方法
需要改进一下
function Person() {
this.name = "zhaobo"
}
Person.prototype.eating = function() {
console.log(this.name + '吃东西');
}
function Student() {
this.sno = 18103420
}
// Student.prototype = new Person()
let p = new Person()
Student.prototype = p
Student.prototype.studying = function() {
console.log(this.name + 'studying');
}
let stu = new Student()
stu.eating()
那我们在给Student.prototype上挂载studying方法之前将Student.prototype指向new Person
Student.prototype = new Person()
那么内存关系图就变成了如下:
相当于原来的原型对象是有自己单独的原型对象的,现在我把它指向new Person这个对象的,之后在Student.prototype上加方法就相当于加在了new Person().proto 上面
然后在调用过程中先在隐式原型proto上找,
但是这种方法的有三个不好的地方
1.不能够打印stu对象的,继承的某些属性是看不到的
因为我们只能打印stu对象上可以枚举的属性,比如这里继承的name属性我们就获取不到
2.获取引用的话,会直接影响 我在stu1对象里面修改完以后,stu2也能获取到,因为两个指向Person对象。
let stu1 = new Student()
let stu2 = new Student()
stu1.eating()
stu1.friends.push('zzzz')
console.log(stu1.friends)
console.log(stu2.friends)
// 原型链继承
console.log(stu1);
console.log(stu2);
3.在实现继承的时候,并没有传递参数
而且直接在new 的对象上下面这样的操作,会给对象添加一个属性name1
stu1.name1 = 'znnnn'
那么我们用借用构造函数来解决上面用原型链
3.借用父类对象继承
function Person(name, age, friends) {
this.name = name
this.age = age
this.friends = friends
}
Person.prototype.eating = function() {
console.log(this.name + '在吃饭');
}
function Student(name, age, friends, sno) {
Person.call(this, name, age, friends)
this.sno = sno
}
Student.prototype = new Person()
Student.prototype.studying = function() {
}
let st = new Student('zhaobo', 22, ['zb,zl'], 18103420)
console.log(st);
借用构造函数也是有弊端
1.Person函数至少被调用了两次 一次是new Person的时候,一次是Person.call调用
2.stu的原型对象上会多出一些属性,但是这些属性没有存在的必要
4.父类原型赋值给子类
这种方法相当于找了一个中间的代理对象,将要继承的对象
let obj = {
name:'zhaobo',
age:22
}
let info = Object.create(obj)
//原型式继承函数
function createObject1(o){
let newObj = {}
Object.setPrototypeOf(newObj,o)
return newObj
}
function createObject2(o){
function fn(){
fn.prototype = o
let newObj = new fn()
return newObj
}
}
let info = Object.create(obj)
5.寄生组合式继承
function createObject(o) {
function Fn() {}
Fn.prototype = o
return new Fn()
}
function inheritPrototype(SubType, SuperType) {
SubType.prototype = Objec.create(SuperType.prototype)
Object.defineProperty(SubType.prototype, "constructor", {
enumerable: false,
configurable: true,
writable: true,
value: SubType
})
}
function Person(name, age, friends) {
this.name = name
this.age = age
this.friends = friends
}
Person.prototype.running = function() {
console.log("running~")
}
Person.prototype.eating = function() {
console.log("eating~")
}
function Student(name, age, friends, sno, score) {
Person.call(this, name, age, friends)
this.sno = sno
this.score = score
}
inheritPrototype(Student, Person)
Student.prototype.studying = function() {
console.log("studying~")
}
var stu = new Student("why", 18, ["kobe"], 111, 100)
console.log(stu)
stu.studying()
stu.running()
stu.eating()
console.log(stu.constructor.name)
\