如果觉得还有点用,请您给我一个赞!您的赞是我坚持下去的动力!
目标:理解原型链及实现类的功能
先看一段代码输出结果然后再来分析
function Bar() {
this.bar = 42;
}
Bar.answer = function() {
return 42;
};
Bar.prototype.print = function() {
console.log(this.bar);
};
var tBar=new Bar();
Object.keys(Bar) // ['answer']
Object.keys(Bar.prototype) //['print']
Object.keys(Bar.__proto__) //[]
Object.keys(tBar) //['bar']
Object.keys(tBar.prototype) // undefined
Object.keys(tBar.__proto__) // ['print']
这里顺便对比一下class的区别,可以发现类的方法成员不能被枚举
class Bar{
constructor(){
this.bar=42;
}
print(){
console.log(this.bar);
}
}
var tBar=new Bar();
Object.keys(Bar) // []
Object.keys(Bar.prototype) //[]
Object.keys(Bar.__proto__) //[]
Object.keys(tBar) //['bar']
Object.keys(tBar.prototype) // undefined
Object.keys(tBar.__proto__) // []
prototype1.png
通过代码来看结构
prototype2.png call_apply_bind.png实现一个new操作符
1.创建一个空对象
2.链接到原型
3.绑定this值
4.返回新对象
function create(fn,...args){
let obj = Object.create(fn.prototype);
//调用new对象的构造函数,并把this绑定为obj
let result = fn.apply(obj,args);
return typeof result==='object'?result:obj;
}
实现一个类的继承功能,让子类继承父类功能,并且子类的相同功能覆盖父类
function ext(son,father){
//遍历当期那子类的所有方法,如果出现重复,则不用父类覆盖子类
for( var param in father.prototype ){
if( !son.__proto__[param ]){
son.__proto__[param] = father.prototype[param];
}else{
son.__proto__[param].super = father.prototype[param];//【可选】将父类方法预留到super内,以备调用
}
}
//先调用父类构造方法进行初始化
father.apply(son,arguments[2]);
//创建runSuper方法,用于调用父类的同名方法【可选】
son.runSuper = function(funName,args){
if(this.__proto__[funName].super)this.__proto__[funName].super.apply(this,args);
}.bind(son);
}
//使用方法如下
function Father(name){
this.name= name;
}
Father.prototype.age = function(age){
console.log('father name is ' + this.name +' ,age is ' + age);
};
function Son(name){
ext(this,Father,arguments);
}
Son.prototype.age = function(age){
this.runSuper('age',arguments);//【可选】运行父类方法
console.log('son name is ' + this.name +' ,age is ' + age);
};
var son = new Son("cx");
son.age(23);
//output:
//father name is cx ,age is 23
//son name is cx ,age is 23
网友评论