一、对象的创建
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 属性。