#类 以前就是构造函数
继承
先声明两个类,并在父类上追加一个smock方法
function Parent() {
}
Parent.prototype.smock = function () {
console.log('吸烟');
}
function Child() {
}
然后让Child的原型指向Parent的实例,这样child实例上就有了Parent的方法了
function Parent() {
this.name = 'hahah'
}
Parent.prototype.smock = function () {
console.log('吸烟');
}
function Child() {
}
Child.prototype = new Parent;
let child = new Child;
child.smock()
}Parent.prototype.smock = function () { console.log('吸烟');}function Child() {}Child.prototype = new Parent;let child = new Child;child.smock()
执行结果就是“吸烟”;
执行原理如图所示:Child类分配一个原型空间prototype,每个prototype都有constrcutor区域,new Child得到的是一个child的实例,实例上有__proto__属性,child.__proto__指向的就是Child.prototype;同理Parent也是这样。现在
Child.prototype = new Parent;
我让Child类上的prototype等于了new出的Parent实例,也就是parent(就是上面那条1蓝色线),那么child上就有了parent上面的公有属性和私有属性了,那么执行child.smock()就是得到想要的结果了。
我们还可以验证一下
console.log(child.__proto__.__proto__ == Parent.prototype);
验证结果为true
我们也可以看一下constructor指向谁
console.log(child.constructor);
继承Object.create
Object.create只继承公有方法。
Child.prototype = Object.create(Parent.prototype);
let child = new Child;
但是child上面没有name(私有属性),但是有smock方法(公有)
怎么实现的呢:
function create(pa) {
function Fn() { } //相当于构建一个类,类的原型指向父类的原型
Fn.prototype = pa;
return new Fn
}
//儿子查找时,可以查找到父类的原型,所以可以拿到父类的公有方法
Child.prototype = create(Parent.prototype);
let child = new Child;
child.smock()
流程图如下:(黄色线部分:create的方法就是改变了Child的prototype的指向。)
而此时child的constructor是Parent,要是想让它变回Child
function create(pa,paranm) {
function Fn() { } //相当于构建一个类,类的原型指向父类的原型
Fn.prototype = pa;
let fn = new Fn;
fn.constructor = param.constructor.value;
return fn
}
//儿子查找时,可以查找到父类的原型,所以可以拿到父类的公有方法
Child.prototype = create(Parent.prototype,{constructor:{value:Child}});
// Child.prototype = Object.create(Parent.prototype,{constructor:{value:Child}});
let child = new Child;
如果想继承静态属性可以这样做
Child.__proto__ = Parent
定义属性
defineProperty
let obj = {};
Object.defineProperty(obj,'a',{
enumerable:true,//是否可枚举
configurable:true,//可配置
// writable:true,//是否可修改 但是不能跟get,set同在,否则会报错
set(val){
console.log(val);
},
get(){
console.log(100)
},
// value:11
})
console.log(obj.a)
es6的继承
extends能继承私有属性
class Parent{
constructor(name){
this.name = name
}
getnaem(){
return this.name
}
}
class Child extends Parent {
constructor(name,age){
super(name)//子类有构造函数必须使用super 类似于call(this,name)
this.age = age
}
}let child = new Child('ww',9);console.log(child.name)
name 是可以拿到的,getname也能拿到(公有私有都能拿到)
静态方法通过类来调用
class Parent{
constructor(name){
this.name = name
}
getname() {
return this.name
}
//通过类来继承
static fu(){
return 100
}
}
Parent.fn()