dawson66 / interview Goto Github PK
View Code? Open in Web Editor NEWInterview summary.
License: MIT License
Interview summary.
License: MIT License
function Person() {
this.name = 'dawson'
}
Person.prototype.getName = function () {
return this.name;
}
function Student() {}
// 原型链继承:子类构造函数指向父类实例
Student.prototype = new Person();
const student = new Student();
console.log(student.getName()); // dawson
// 引发的问题?
问题
function Person() {
this.name = 'dawson';
this.hobbies = ['backetball', 'football'];
}
Person.prototype.getName = function () {
return this.name;
}
Person.prototype.addHobbies = function (...args){
this.hobbies.push(...args);
}
function Student() {}
Student.prototype = new Person();
const student1 = new Student();
const student2 = new Student();
student1.addHobbies('music');
student2.addHobbies('dance');
console.log(student1.hobbies); // ['backetball', 'football', 'music', 'dance']
细想一下,子类实例化时,通用性属性一般super调用父类的构造函数来为子类初始化,然而,子类构造函数原型指向一个固定的对象,怎么也做不到传值的操作!
function Person(options) {
this.age = options.age;
this.name = 'dawson';
this.hobbies = ['backetball', 'football'];
}
Person.prototype.getName = function () {
return this.name;
}
Person.prototype.addHobbies = function (...args){
this.hobbies.push(...args);
}
function Student(options) {
// 所谓的构造函数继承就是在子类的构造函数中调用父类的构造函数并指定this
Person.call(this, options)
}
const student1 = new Student({age: 20});
const student2 = new Student({age: 88});
console.log(student1.age); // 20
console.log(student2.age); // 88
student1.addHobbies('music');
student2.addHobbies('dance');
console.log(student1.hobbies); // Uncaught TypeError: student1.addHobbies is not a function
// 解决了什么问题?
// 1. 解决了原型链继承的传参问题
// 引发了什么问题?
// addHobbies报错说明原型上没有此方法,即子类未继承父类原型链上的属性和方法;那么你可能会说,可以将方法挂载到属性上而不是原型上,没错,这样是可以的
// 但是会引发一个问题,就是子类每次实例化时都会重复创建相同的方法,如addHobbies,这样就丧失了原型链或者面向对象的意义,因此引出下面思考
// 思考:未继承原型链上的属性,那么我们怎么才能继承父类原型链上的属性呢?
function Person(options) {
this.age = options?.age || 20;
this.name = 'dawson';
this.hobbies = ['backetball', 'football'];
}
Person.prototype.getName = function () {
return this.name;
}
Person.prototype.addHobbies = function (...args){
this.hobbies.push(...args);
}
function Student(options) {
Person.call(this, options);
this.gender = options.gender;
}
// 借用原型继承的优点,子类原型指向父类实例,虽不能传参,但是能够继承原型链上的属性
Student.prototype = new Person();
// 需要修复构造函数指向,Student实例constructor属性需要指向其构造函数
// student1.constructor == Student Student.prototype.constructor == Student
Student.prototype.constructor = Student;
const student1 = new Student({age: 20, gender: 'male'});
const student2 = new Student({age: 88, gender: 'female'});
console.log(student1);
console.log(student1.age); // 20
console.log(student2.age); // 88
student1.addHobbies('music');
student2.addHobbies('dance');
console.log(student1.hobbies); // ['backetball', 'football', 'music']
组合继承已经能够实现对象的继承问题,算是一种解决方案了,但是还不够完美。如果你将student实例打印并查看的话,你会发现,属性不仅在实例中有,在原型对象上也有,因为我们的父类构造函数被调用了两次!那么如何减少一次构造函数的调用呢?
寄生式组合继承
// 寄生式组合继承作为ES6之前的 继承的 较好实现
function Person(options) {
this.age = options?.age || 20;
this.name = 'dawson';
this.hobbies = ['backetball', 'football'];
}
Person.prototype.getName = function () {
return this.name;
}
Person.prototype.addHobbies = function (...args){
this.hobbies.push(...args);
}
function Student(options) {
Person.call(this, options);
this.gender = options.gender;
}
function F(){
}
// 中间加一层,子类原型指向F实例,F实例原型之乡Person的原型,实现原型链的访问
F.prototype = Person.prototype;
// 这里试想一下,Student.prototype = Person.prototype 行不行? 为何中间非要加一层?
Student.prototype = new F();
// 别忘了,constructor的正确指向
Student.prototype.constructor = Student;
const student1 = new Student({age: 850, gender: 'male'});
const student2 = new Student({age: 88, gender: 'female'});
console.log(student1);
console.log(student1.age); // 20
console.log(student2.age); // 88
student1.addHobbies('music');
student2.addHobbies('dance');
console.log(student1.hobbies); // ['backetball', 'football', 'music']
class继承
class Person {
constructor(options){
this.age = options?.age || 20;
this.name = 'dawson';
this.hobbies = ['backetball', 'football'];
}
getName() {
return this.name;
}
addHobbies(...args){
this.hobbies.push(...args);
}
}
class Student extends Person {
constructor(options){
super(options)
this.gender = options.gender
}
}
const student3 = new Student({age: 890, gender: 'male'})
console.log(student3);
先来看一个例子
// 例一
var name = 'global'
let obj = {
name: 'dawson'
}
function getName() {
return this.name;
}
const copyGetName = getName.bind(obj)
console.log(getName()); // global
console.log(copyGetName()); // dawson
// 例二
function add(a, b, c) {
return a + b + c;
}
const copyAdd = add.bind(null, 1);
console.log(copyAdd(2, 3)); // 6
结论:
// 实现上述三点,第四点是最难的,也请思考!
Function.prototype._bind = function (context) {
if (typeof this !== 'function') {
throw new Error('bind只能被函数调用')
}
const fn = this;
const args = Array.prototype.slice.call(arguments, 1);
return function () {
const bindArgs = Array.prototype.slice.call(arguments);
return fn.call(context, ...args, ...bindArgs);
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.