JS类与继承

定义JS类

工厂模式

function Person (name) {
    var o = new Object();
    o.name = name;
    o.sayName = function () {
        alert(this.name);
    };
    return o;
}
var p = Person('Tom');
  • new一个object,给object添加属性,return object对象
  • 缺点:无法识别对象的类型,都是Object

构造函数

function Person (name) {
    this.name = name;
    this.sayName = function () {
        alert(this.name);
    };
}
var p = new Person('Tom');
  • 直接给this赋属性和方法,无需return,需要new一个实例对象,该实例对象的类型为构造函数Person
  • 缺点:每个实例都会创建同样的方法sayName,即方法不能共享

原型模式

function Person () {};
Person.prototype.name = 'Tom';
Person.prototype.sayName = function () {
    alert(this.name);
}
var p = new Person(); // p.name = Tom
var r = new Person();
r.name = 'Jerry'; // 导致p.name=Jerry
  • 通过prototype来设置属性和方法,共享的
  • 缺点:所有的实例共享方法和属性的引用,一个实例修改会影响所有的实例

组合构造函数和原型模式

function Person (name) {
    this.name = name;
}
Person.prototype = {
    constructor = Person;
    sayName: function () {
        alert(this.name);
    };
}
var p = Person('Tom');
  • 构造函数中定义实例属性,各个实例拥有自己的属性
  • 原型中定义共享的方法
  • 原型链:实例属性的查找,首先在查找实例属性,若没有,则向上查找,即查找其prototype指向的原型对象是否有该属性,依次向上直到Object

继承

原型链

function Super(name) {
    this.name = name;
    this.phone = [1,2,3];
}
Super.prototype.sex = 'female';
Super.prototype.sayName = function () {
    alert(this.name);
}
function Sub(name,age) {
    this.name = name;
    this.age = age;
}
Sub.prototype = new Super('Tom');//原型具有父类的实例属性和方法,即拥有自己的name和phone
Sub.prototype.sayName = function () {
    alert(this.name + this.age);
}
var obj1 = new Sub('Jerry', 23); // obj1.phone=[1,2,3]
var obj2 = new Sub('Chris', 18);// obj2.phone=[1,2,3]
obj1.phone.push(4);// obj2.phone=[1,2,3,4]
// obj1.__proto__ === Sub.prototype === obj2.__proto__
// obj1.phone === obj1.__proto__.phone
//obj1.phone === obj2.phone
  • 子类的原型重写为父类的一个实例对象,子类拥有父类原型对象中的所有属性和方法,子类同名属性和方法会覆盖父类
  • 子类的原型对象拥有父类实例对象的所有引用类型的属性(实例属性)
  • 子类实例对引用类型的变更会影响到所有其他的实例中的该引用变量

借助构造函数

function Super(name) {
    this.name = name;
    this.sayName = function() {
        alert(this.name);
    }
}
function Sub(name, age) {
    Super.call(this, name);
    this.age = age;
}
  • 构造函数中定义方法,所有实例都会创建一个函数,复用性差

组合原型链和构造函数

function Super(name) {
    this.name = name;
    this.phone = [1,2,3];
}
Super.prototype.sex = 'female';
Super.prototype.sayName = function () {
    alert(this.name);
}
function Sub(name, age) {
    Super.call(this, name); // 将属性绑定到this
    this.age = age;
}
Sub.prototype = new Super();
Sub.prototype.sayAge = function () {
    alert(this.age);
}
var obj1 = new Sub('A');
var obj2 = new Sub('B');
// obj1 obj2分别拥有自己的phone属性
// Sub.prototype.phone != obj1.phone
  • 原型链实现原型属性的继承,构造函数实现实例属性的继承
  • 每创建一个实例都会调用一次Super.call(),每个实例都创建自己的实例属性,引用类型属性在实例之间也不共享
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值