类和继承
类
- ES6 class,extends;
面向过程和面向对象
OOP:Object Oriented Programming
从面向过程的角度
step1();
step2();
step3();
……
finish();
从面向对象的角度
面向对象 —— 一切皆对象 finish => step(xxx) something.deal(finish)
函数式编程
something.step1().step2().step3()......
[1,2,3,4,5].map(item => item * 2).filter(item => item > 10).join(',')
JS对象的创建
创建一个对象有哪些方法
- Object.create()
- Object.create() 创建了一个对象;
- let p = Object.create(q) => p.ptoto = q
- new Function();
- 创建了一个对象;
- 该对象的原型只想了这个Function(构造函数)的prototype
- 该对象实现了这个构造函数的方法;
- 跟据一些特定情况返回对象
- 如果没有返回值,则返回创建的对象;
- 如果有返回值,是一个对象,则返回该对象;
- 如果有返回值,不是一个对象,则返回创建的对象
function newObj(Father){
if(typeof Father !== 'function'){
throw new Error('new operator function the frist param must be a function')
}
var obj = Object.create(Father.prototype);
var result = Father.apply(obj, Array.prototype.slice.call(arguments,1));
return result && typeof result === 'object'&& result !== null ? result :obj;
}
let p = new Person() //Person 是构造函数
p.__proto__ = Person.prototype;
Person.prototype.constructor =Person;
p.constructor =Person;
- var obj={};
- obj.proto = Object.prototype; let p = Object.create({}) 相当于: let p = Object.create(obj); 相当于: p.proto = obj;
继承
实现一个继承主要是两个部分:
- 使用父类的构造函数的方法;
- 让对象的原型链指向父类;
原型链继承
function Parent(){
this.name = 'father';
}
Parent.prototype.getName = function(){
console.log(this.name);
}
function Child(){};
//Child.__proto__ = Parent.prototype
Child.prototype =new Parent();
Child.prototype.constructor = Child;
//存在问题:
//1.如果有属性是引用类型,一旦某个实例修改了这个属性,所有的都会改变;
//2. 创建 Child 的时候不能传参
构造函数继承
//想办法把Parent上的属性和方法添加到Child上面去,而不是都存在在原型对象上,防止被实例共享;
function Parent(action,name){
this.action = ['a','b','c'];
this.name = 'parentName';
}
function Child(play){
Parent.apply(this,Array.prototype.slice.call(arguments,1));
this.play = play;
}
//存在问题:
// 1.属性或者方法想被继承的话,只能在构造函数中定义
// 2.如果方法在构造函数中定义了,每次创建实例都会创建一遍方法
组合继承
function Parent(action,name){
this.action = ['a','b','c'];
this.name = 'parentName';
}
Parent.prototype.work = function(){
console.log('hi'+ this.name )
}
function Child(play){
Parent.apply(this,Array.prototype.slice.call(arguments,1));
this.play = play;
}
Child.prototype = new Parent();
Child.prototype.constructor = Child;
组合寄生式继承
function inherit(p){
if(p == null) throw TypeError() //p是一个对象,不能为null
if(Object.create) return Object.create(p);
var t = typeof p;
if(t !== 'object' && t !=='function') throw TypeError()
function f(){
};
f.prototype = p;
return new f();
}
function Parent(action,name){
this.action = ['a','b','c'];
this.name = 'parentName';
}
Parent.prototype.work = function(){
console.log('hi'+ this.name )
}
function Child(play){
Parent.apply(this,Array.prototype.slice.call(arguments,1));
this.play = play;
}
//Child.prototype = new Parent();
Child.prototype = inherit(Parent.prototype);
Child.prototype.constructor = Child;
es6继承
class A{
}
class B extends A{
constructor(){
super()
}
}
//super 作为函数调用时,要求必须执行一次
//因为子类自己的this对象,必须通过父类的构造函数完成
//es6继承会继承静态的方法和属性