继承

tech2025-09-08  5

1、es6继承

2、原型链继承

Student继承Pepole:将Student的prototype属性指向Pepole的实例对象,使得它的Student.prototype=new Pepole()。这样就这样直接引用Pepole的形参了

缺点:共享属性,因为引用类型的原因,改一个属性会改其他实例化对象的属性,其实人家不想改变。

3、构造函数继承

function Person(name, age) { this.name = name; this.age = age; this.type = 'person'; } function Student(name, age, grade) { Person.call(this, name, age); // 用call调用Person,this(Student)代替Person的this,达到继承Person的对象和方法的目的 //就是this,即Student调用了Person函数,并且传入了参数 this.grade = grade; } var student = new Student("zhangsan", 21, "一年级"); console.log('student:', student.type) // student: person

缺点:每个实例都拷贝一份,占用内存大,尤其是方法过多的时候。

没有函数复用。

函数复用:函数重复使用,但方法都在构造函数中,每一个实例都有自己的副本,都有自己的执行环境

4、组合继承:构造继承属性,原型链继承方法

原型链是一种关系,是实例对象和原型对象之间的关系,关系通过原型(proto)来联系的

function Foo(name) { this.name = name; } Foo.prototype.age = function() { console.log('父类:' + this.name); }; Foo.prototype.obj = function() { console.log('hello world'); }; function fn (name) { Foo.call(this,name); } fn.prototype =new Foo(); //保证 constructor 指向正确 fn.prototype.constructor = fn; fn.prototype.age = function() { console.log('子类:' + this.name); }; fn.prototype.set = function() { console.log('set si es5'); }; var a = new fn('lisi'); a.age(); a.obj(); a.set();

如果没有这行代码fn.prototype.constructor = fn;输出fn.prototype如下

有这行, 所以这行是将子类的构造器constructor指向子类的构造函数

fn.prototype =new Foo();不能写成fn.prototype = Foo.prototype.因为如下图,父类的构造器不能指向父类Foo的构造函数了。

5、寄生式继承

6、new

在内存中创建一个新对象(先申请一块空闲的空间)

设置构造函数的this, 让this指向刚刚创建的对象 this就是当前实例化的对象

执行构造函数中的代码 设置对象中的属性和方法

返回新对象

new 运算符接受一个函数 F 及其参数:new F(arguments...)。这一过程分为三步:

创建类的实例。这步是把一个空的对象的 __proto__ 属性设置为 F.prototype 。初始化实例。函数 F 被传入参数并调用,关键字 this 被设定为该实例。返回实例。 function New (f) { //var n={}; //n.'__proto__'= f.prototype var n = { '__proto__': f.prototype }; /*第一步*/ return function () { f.apply(n, arguments); /*第二步*/ return n; /*第三步*/ }; } f.apply(n, arguments); 对象n调用f方法,并且为其传参
最新回复(0)