JS面向对象编程与对象继承实现

一、对象的创建

1、工厂方法(函数声明):

function createUser(name) {
    const user = {
        name,
        sayName: function() {
            console.log(this.name);
        }
    }

    return user;
}

const user = createUser('Johnson');

user.sayName();
// -> Johnson

这样创建了一个对象 user,然后执行了对象中的 sayName 方法。

2、面向对象(构造函数+原型链):

function User(name) {
    this.name = name;
}

User.prototype.sayName = function() {
    console.log(this.name);
}

const user = new User('Johnson');

user.sayName();
// -> Johnson

这样创建了一个对象user,然后执行了对象原型链上的sayName方法。

二、对象的继承

function User(name) {
    this.name = name;
}

User.prototype.sayName = function() {
    console.log(this.name);
}
;
User.prototype.changeName = function(name) {
    this.name = name;
};

上面定义了原型方法,也可以用下面的代码快速定义多个方法:

User.prototype = {
    sayName: function() {
        console.log(this.name);
    },
    changeName: function() {
        this.name = name;
    }
};

但是,这样会导致创建出来的对象的 constructor 不指向函数 User,而是指向 Object 函数,可以像下面这样写:

User.prototype = {
    constructor : User
    sayName: function() {
        console.log(this.name);
    },
    changeName: function() {
        this.name = name;
    }
};

在构造函数与原型上定义相同的的方法:

function User(name) {
    this.name = name;
    this.sayName = function() {
        console.log(this.name);
    };
}

User.prototype.sayName = function() {
    console.log(this.name + ' prototype');
};

const user = new User('Johnson');

user.sayName();
// -> Johnson

这个时候会输出 Johnson,而不是 Johnson prototype,因为在访问对象的属性或方法时,会优先取对象自身的属性和方法,找不到时才会在原型上查找。

实现对象继承的方法

① 借用构造函数继承

function People() {
    this.id = '001';
}

People.prototype.changeId = function(id) {
    this.id = id;
};

function User(name) {
    People.call(this);

    this.name = name;
}

const user = new User('Johnson');

console.log(user.id);
// -> 001

user.changeId('002');
// -> user.changeId is not a function

user 对象上具有 id 属性,没有 changeId 方法。

② 原型链继承

function People() {
    this.id = '001';
    this.type = [1, 2];
}

People.prototype.pushType = function(type) {
    this.type.push(type);
};

function User(name) {
    this.name = name;
}

User.prototype = new People();
User.prototype.constructor = User;

const user1 = new User('Johnson1');

const user2 = new User('Johnson2');

console.log(user1.id, user2.id);
// -> 001 002

user1.pushType(3);

user2.pushType(4);

console.log(user1.type, user2.type);
// -> [1, 2, 3, 4] [1, 2, 3, 4]

user1, user2 对象上同时具有 id 属性和 pushType 方法,但 type 属性被多个对象共享。

③ 借用构造函数+原型链 组合继承

function People() {
    this.id = '001';
    this.type = [1, 2];
}

People.prototype.pushType = function(type) {
    this.type.push(type);
};

function User(name) {
    People.call(this);

    this.name = name;
}

User.prototype = new People();
User.prototype.constructor = User;

const user1 = new User('Johnson1');

const user2 = new User('Johnson2');

user1.pushType(3);

user2.pushType(4);

console.log(user1.type, user2.type);
// -> [1, 2, 3] [1, 2, 4]

user1, user2 对象上具有各自的 type 属性。

此条目发表在JavaScript分类目录,贴了, , , , , 标签。将固定链接加入收藏夹。