【js进阶】ES5原生JS中的几种继承方式
在 JavaScript 中,new 关键字主要用于创建一个对象实例,其具体执行的操作如下:
创建一个空对象:首先,会创建一个空的简单 JavaScript 对象,这个对象会继承自构造函数的 prototype 属性。
设置原型链:将新创建的对象的 proto 属性(在现代 JavaScript 中可以使用 Object.getPrototypeOf() 来访问)设置为构造函数的 prototype 属性,从而实现原型链的继承。
绑定 this:将新创建的对象作为 this 的上下文,也就是将构造函数内部的 this 指向这个新对象。
执行构造函数:调用构造函数,将新对象作为 this 传入,执行构造函数内部的代码,对新对象进行属性的添加和初始化等操作。
返回新对象:如果构造函数没有显式返回一个对象,那么会自动返回这个新创建的对象;如果构造函数显式返回了一个对象,那么会返回该对象,而不是新创建的对象。
类式继承
function Person(name) {
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
};
const reader = new Person('reader');
console.log(reader.getName()); // reader
function Author(name, book) {
Person.call(this, name);
this.book = book;
}
Author.prototype = new Person();
console.log('🚀 ~ Author.prototype:', Author.prototype.constructor);
Author.prototype.constructor = Author;
Author.prototype.getBook = function () {
return this.book;
};
模拟extend
function extend(subClass, superClass) {
// 声明一个空的临时中间类构造函数
var F = function () {};
// 继承父类的原型方法到中间类构造函数的原型中
F.prototype = superClass.prototype;
// 类似继承一个中间类,继承父类的原型方法
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
}
function Animal(name, gender) {
this.name = name;
this.gender = gender;
}
Animal.prototype.getAge = function () {
return this.age;
};
function Dog(name, age, gender) {
Animal.call(this, name, gender);
this.age = age;
this.gender = gender;
}
extend(Dog, Animal);
const dog = new Dog('dog', 10, 'male');
console.log(dog);
console.log(dog.getAge());
弱化父子类中间的耦合
- 改进版的extend方法
子类中无需硬编码Person父类了,只需要用子类自己的属性Dog.superClass.constructor.call(this, ...arguments);
function extend(subClass, superClass) {
// 声明一个空的临时中间类构造函数
var F = function () {};
// 继承父类的原型方法到中间类构造函数的原型中
F.prototype = superClass.prototype;
// 类似继承一个中间类,继承父类的原型方法
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
// 弱化对父类的引用,避免不必要的耦合
subClass.superClass = superClass.prototype;
if (superClass.prototype.constructor == Object.prototype.constructor) {
superClass.prototype.constructor = superClass;
}
}
function Animal(name, gender) {
this.name = name;
this.gender = gender;
}
Animal.prototype.getAge = function () {
return this.age;
};
function Dog(name, age, gender) {
Dog.superClass.constructor.call(this, ...arguments);
this.age = age;
this.gender = gender;
}
extend(Dog, Animal);
const dog = new Dog('dog', 10, 'male');
console.log(dog);
console.log(dog.getAge());
原型继承
- 不同于类似继承,无需构造函数
let Person = {
name: 'default name',
getName() {
return this.name;
},
};
let reader = clone(Person);
console.log(reader.getName());
reader.name = 'reader name';
console.log(reader.getName());
function clone(objec) {
let F = function () {};
F.prototype = objec;
return new F();
}
let Author = clone(Person);
Author.books = [];
Author.hobbies = [];
Author.getBooks = function () {
return this.books;
};
let author = [];
author[0] = clone(Author);
author[0].name = 'author name';
author[0].books = ['设计模式'];
author[1] = clone(Author);
author[1].name = 'rose harmes';
author[1].books = ['设计模式'];
console.log(author[1].getName());
console.log(author[1].getBooks());
let anthorClone = clone(Author);
console.log(anthorClone.name);
anthorClone.name = 'new name';
console.log(anthorClone.name);
anthorClone.books.push('new book');
anthorClone.hobbies = ['reading', 'writing'];
console.log('🚀 ~ anthorClone.hobbies:', anthorClone.hobbies);
console.log(anthorClone.books, '9090');
let anthorClone2 = clone(Author);
console.log(anthorClone2.books, '8080');
console.log('🚀 ~ anthorClone2.hobbies:', anthorClone2.hobbies);
- 修改对象深层次深层次属性的方法
let computedObj = {
name: '张三',
usreInfo: {
age: 18,
sex: '男',
},
};
// bad: 直接修改对象
computedObj.usreInfo.age = 20;
// better
computedObj.usreInfo = {
age: 20,
sex: '男',
};
// best
let compoundObject = {};
compoundObject.name = '张三';
compoundObject.createUserInfo = function () {
return {
age: 100,
sex: '男',
};
};
computedObj.usreInfo = compoundObject.createUserInfo();
let compoundObjectClone = clone(compoundObject);
compoundObjectClone.usreInfo = compoundObject.createUserInfo();
compoundObjectClone.usreInfo.age = 20;
- 参元类,扩展属性
let Mixin = function () {};
Mixin.prototype = {
serialize() {
let output = [];
for (let key in this) {
output.push(key + '=' + this[key]);
}
return output.join('&');
},
};
function aument(receive, give) {
for (let property in give) {
if (!receive.hasOwnProperty(property)) {
receive[property] = give[property];
}
}
}
// 进阶版
function aument2(receive, give) {
if (arguments[2]) {
for (let index = 2; index < arguments.length; index++) {
const element = arguments[index];
receive.property[element] = give[element];
}
} else {
aument(receive, give);
}
}
原文地址:https://blog.csdn.net/qq_27702739/article/details/145162261
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!