首页
技术小册
AIGC
面试刷题
技术文章
MAGENTO
云计算
视频课程
源码下载
PDF书籍
「涨薪秘籍」
登录
注册
请详细介绍Javascript中的数据类型?区别?
Javscript数组的常用方法有哪些?
Javascript字符串的常用方法有哪些?
Javascript 中的类型转换机制
== 和 ===区别,分别在什么情况使用
拷贝浅拷贝的区别?如何实现一个深拷贝?
请介绍你对Javascript中闭包的理解
请介绍你对javascript中作用域链的理解
什么是JavaScript原型,原型链 ?
请介绍Javascript如何实现继承
请介绍你对javascript中this对象的理解
JavaScript中执行上下文和执行栈是什么?
请介绍JavaScript中的事件模型
typeof 与 instanceof 区别
解释下什么是事件代理?应用场景?
请介绍new操作符具体干了什么
ajax原理是什么?如何实现?
bind、call、apply 区别?如何实现一个bind?
请介绍你对正则表达式的理解?应用场景?
请介绍你对事件循环的理解
DOM常见的操作有哪些?
请详细介绍你对BOM的理解,常见的BOM对象你了解哪些?
举例说明你对尾递归的理解,有哪些应用场景。
请介绍 JavaScript 中内存泄漏的几种情况。
Javascript本地存储的方式有哪些?区别及应用场景?
请介绍你对函数式编程的理解?优缺点?
Javascript中如何实现函数缓存?函数缓存有哪些应用场景?
请介绍 Javascript 数字精度丢失的问题,如何解决?
当前位置:
首页>>
技术小册>>
JavaScript面试指南
小册名称:JavaScript面试指南
JavaScript 是一门基于原型的语言,因此它的继承方式也是通过原型链来实现的。通过原型链,一个对象可以从另一个对象那里继承属性和方法。 在 JavaScript 中,有以下几种方式实现继承: **原型链继承** 原型链继承是 JavaScript 中最常见的继承方式,它通过将子类的原型指向父类的实例来实现继承。子类可以访问父类原型中的属性和方法。 ``` function Animal(name) { this.name = name; } Animal.prototype.eat = function() { console.log(this.name + " is eating."); }; function Dog(name) { this.bark = function() { console.log("Woof!"); }; } Dog.prototype = new Animal(); var dog1 = new Dog("Max"); dog1.eat(); // Output: "Max is eating." dog1.bark(); // Output: "Woof!" ``` 在上面的例子中,我们定义了一个 Animal 构造函数和一个 Dog 构造函数。我们将 Dog 的原型设置为 Animal 的一个实例,这样 Dog 的实例就可以访问 Animal 原型中的 eat 方法。 **构造函数继承** 构造函数继承通过在子类的构造函数中调用父类的构造函数来实现继承。这种方式可以继承父类的实例属性,但是无法继承父类的原型属性和方法。 ``` function Animal(name) { this.name = name; } Animal.prototype.eat = function() { console.log(this.name + " is eating."); }; function Dog(name) { Animal.call(this, name); this.bark = function() { console.log("Woof!"); }; } var dog1 = new Dog("Max"); dog1.eat(); // Output: TypeError: dog1.eat is not a function dog1.bark(); // Output: "Woof!" ``` 在上面的例子中,我们定义了一个 Animal 构造函数和一个 Dog 构造函数。在 Dog 的构造函数中,我们使用 call 方法调用了 Animal 的构造函数,并传入了 this 参数,这样 Dog 的实例就可以继承 Animal 的实例属性。 **组合继承** 组合继承是将原型链继承和构造函数继承结合起来的一种方式。它通过将子类的原型设置为父类的实例来实现原型链继承,同时在子类的构造函数中调用父类的构造函数来实现构造函数继承。 ``` function Animal(name) { this.name = name; } Animal.prototype.eat = function() { console.log(this.name + " is eating."); }; function Dog(name) { Animal.call(this, name); } Dog.prototype = new Animal(); var dog1 = new Dog("Max"); dog1.eat(); // Output: "Max is eating." ``` 在上面的例子中,我们定义了一个 Animal 构造函数和一个 Dog 构造函数。在 Dog 的构造函数中,我们使用 Animal.call(this, name) 调用了 Animal 的构造函数,并传入了 this 参数,这样 Dog 的实例就可以继承 Animal 的实例属性。同时,我们将 Dog 的原型设置为 Animal 的一个实例,这样 Dog 的实例也可以访问 Animal 原型中的方法。这样一来,Dog 的实例就同时继承了父类的实例属性和原型属性。 需要注意的是,使用组合继承的方式会调用两次父类的构造函数,一次在子类的构造函数中,一次在将子类的原型设置为父类实例时。因此,这种方式可能会导致性能问题。 **原型式继承** 原型式继承是通过创建一个空对象并将其原型设置为要继承的对象来实现继承的。这种方式可以快速地创建对象,但是无法解决父子之间的引用问题。 ``` var animal = { name: "", eat: function() { console.log(this.name + " is eating."); } }; var dog = Object.create(animal); dog.bark = function() { console.log("Woof!"); }; dog.name = "Max"; dog.eat(); // Output: "Max is eating." dog.bark(); // Output: "Woof!" ``` 在上面的例子中,我们创建了一个 animal 对象,然后通过 Object.create 方法将其原型设置为 animal。接着,我们定义了一个 dog 对象,并在其中添加了一个 bark 方法。最后,我们将 dog 的 name 属性设置为 Max,并调用 dog 的 eat 方法和 bark 方法。 **寄生式继承** 寄生式继承是在原型式继承的基础上,通过在一个新对象上添加方法并返回该对象来实现继承的。这种方式可以在不修改原对象的情况下对其进行扩展。 ``` var animal = { name: "", eat: function() { console.log(this.name + " is eating."); } }; function createDog(name) { var dog = Object.create(animal); dog.name = name; dog.bark = function() { console.log("Woof!"); }; return dog; } var dog1 = createDog("Max"); dog1.eat(); // Output: "Max is eating." dog1.bark(); // Output: "Woof!" ``` 在上面的例子中,我们定义了一个 animal 对象,然后通过 createDog 函数实现了一个寄生式继承。在 createDog 函数中,我们首先通过 Object.create 方法创建了一个新对象 dog,然后在 dog 对象中添加了一个 bark 方法, 并将name 属性设置为传入的 name 值。最后,返回该对象,即可实现继承。 需要注意的是,寄生式继承与原型式继承一样,都无法解决父子之间的引用问题。 **寄生组合式继承** 寄生组合式继承是继承中的最佳实践,它通过组合继承和寄生式继承的方式来实现继承,并且避免了组合继承中的性能问题和寄生式继承中的引用问题。 ``` function Animal(name) { this.name = name; } Animal.prototype.eat = function() { console.log(this.name + " is eating."); }; function Dog(name) { Animal.call(this, name); } (function() { // 创建一个空对象作为中介 var Super = function() {}; Super.prototype = Animal.prototype; // 将中介对象的实例作为子类的原型 Dog.prototype = new Super(); })(); Dog.prototype.bark = function() { console.log("Woof!"); }; var dog1 = new Dog("Max"); dog1.eat(); // Output: "Max is eating." dog1.bark(); // Output: "Woof!" ``` 在上面的例子中,我们首先定义了 Animal 和 Dog 两个构造函数。在 Dog 的构造函数中,我们通过 Animal.call(this, name) 调用了 Animal 的构造函数,并传入了 this 参数,这样 Dog 的实例就可以继承 Animal 的实例属性。 接着,我们使用了一个自执行函数来实现寄生式继承。在该函数中,我们创建了一个空对象 Super,并将 Animal.prototype 赋值给了 Super.prototype。这样,Super 对象就成为了 Animal.prototype 的一个中介对象,可以将 Dog 的原型设置为 Super 的一个实例,以避免调用两次父类的构造函数。 最后,我们在 Dog 的原型中添加了一个 bark 方法,并创建了一个 dog1 实例,可以发现 dog1 实例可以同时访问 Animal 和 Dog 的方法和属性,且避免了调用两次父类的构造函数和引用问题。
上一篇:
什么是JavaScript原型,原型链 ?
下一篇:
请介绍你对javascript中this对象的理解
该分类下的相关小册推荐:
WebSocket入门与案例实战
Flutter核心技术与实战
剑指javascript
编程入门课:Javascript从入门到实战
JavaScript入门与进阶
Javascript-ES6与异步编程
零基础学JavaScript
剑指javascript-ES6
KnockoutJS入门指南
ES6入门指南
Javascript重点难点实例精讲(一)
Javascript编程指南