前端面试宝典【Javascript篇】【4】
欢迎来到《前端面试宝典》,这里是你通往互联网大厂的专属通道,专为渴望在前端领域大放异彩的你量身定制。通过本专栏的学习,无论是一线大厂还是初创企业的面试,都能自信满满地展现你的实力。
核心特色:
- 独家实战案例:每一期专栏都将深入剖析真实的前端面试案例,从基础知识到前沿技术,从算法挑战到框架运用,让你在实战中迅速成长。
- 深度技术解析:不再只是表面文章,我们将带你深入技术的核心,理解每一个知识点背后的原理与- - 应用场景,让你在面试中不仅知其然,更知其所以然。
- 高质量内容保证:每一期内容都经过精心策划与打磨,确保信息的准确性和实用性,拒绝泛泛而谈,只提供真正有价值的内容。
- 持续更新迭代:持续关注前端领域的最新动态,及时更新专栏内容,确保你始终站在技术的最前沿。
10. 介绍一下JavaScript中的原型链
JavaScript中的原型链是实现继承和属性查找机制的基础。在JavaScript中,每个对象都有一个原型对象,这个原型对象可以是另一个对象的实例或者是Object.prototype。原型链就是一系列的原型对象,它们通过Object.getPrototypeOf(obj)获取obj这个对象的原型对象,同样的方法获取原型对象的原型对象,形成一个链式结构。
原型对象
每个函数在创建时都会自动获得一个prototype属性,这是一个对象,用于初始化由该构造函数创建的对象的原型。当我们使用构造函数创建新对象时,新对象的原型对象将指向构造函数的prototype对象。
原型链工作原理
当试图访问一个对象的属性或方法时,如果该对象自身没有这个属性或方法,JavaScript引擎会沿着原型链向上查找,直到找到该属性或方法为止。如果在原型链的末端(通常是Object.prototype)都没有找到,那么查找失败,返回undefined。
示例:
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log("Hello, my name is " + this.name);
};
const john = new Person("John");
john.greet(); // 输出: Hello, my name is John
console.log(john.hasOwnProperty('greet')); // 输出: false
console.log(Object.getPrototypeOf(john).hasOwnProperty('greet')); // 输出: true
在这个例子中,john对象没有自身的greet方法,但是Object.getPrototypeOf(john)指向了Person.prototype,而Person.prototype有greet方法,因此john.greet()可以正常工作。
原型链的顶端
原型链的最顶端是Object.prototype,它是所有对象的原型。Object.prototype也有一个原型对象(即Object.getPrototypeOf(Object.prototype)),但它指向null,表示原型链的终点。
原型链与继承
原型链还用于实现继承。当一个对象没有某个属性或方法时,它会沿着原型链查找,如果在某个原型对象中找到了,那么就可以使用这个属性或方法,这就是继承的实现方式。
总结
原型链是JavaScript中对象属性查找和继承的基础,了解它是理解和编写复杂JavaScript代码的关键。通过原型链,JavaScript实现了动态的属性查找和灵活的继承机制。
原型链是js的核心内容,理解其原理非常重要,因为篇幅问题介绍的没那么详细,想了解更多的朋友可以查看MDN官方文档,介绍的非常详全面
11. ES5有几种方式可以实现继承?分别有哪些优缺点?
在ES5中,实现继承主要有六种方式,它们分别是:
- 原型链继承
- 实现方式:通过将子类的prototype属性设置为父类的一个实例,来实现继承。
- 优点:
- 简单易懂,实现容易。
- 子类可以复用父类的所有方法。
- 缺点:
- 每个子类实例会共享父类的引用类型属性。
- 创建子类实例时,不能向父类构造函数传递参数。
- 父类的构造函数会被调用多次,一次是在创建父类实例时,另一次是在创建子类实例时。
function Parent() {
this.name = 'parent';
}
Parent.prototype.getName = function() {
return this.name;
};
function Child() {}
// 继承
Child.prototype = new Parent();
var child = new Child();
console.log(child.getName()); // "parent"
- 构造函数继承
- 实现方式:在子类构造函数中调用父类构造函数,并使用apply或call方法改变this指向。
- 优点:
- 可以为子类实例添加独立的属性。
- 可以在创建子类实例时向父类构造函数传递参数。
- 缺点:
- 无法实现函数复用,每个子类实例都会拥有父类方法的副本。
- 父类中定义的方法不会被子类继承。
function Parent() {
this.name = 'parent';
}
function Child() {
Parent.call(this); // 调用父类构造函数
}
var child = new Child();
console.log(child.name); // "parent"
- 组合继承(经典继承)
- 实现方式:结合原型链继承和构造函数继承的优点,既能在子类实例中复用父类的方法,也能为子类实例添加独立的属性。
- 优点:
- 解决了原型链继承和构造函数继承的缺点。
- 缺点:
- 父类的构造函数会被调用两次,一次在原型链继承中,另一次在构造函数继承中。
function Parent() {
this.name = 'parent';
}
function Child() {
Parent.call(this); // 调用父类构造函数
}
var child = new Child();
console.log(child.name); // "parent"
- 寄生继承
- 实现方式:创建一个仅用于继承其他对象的函数,然后将这个函数的返回值赋给新的对象。
- 优点:
- 可以增强对象,同时不会影响到原型链。
- 缺点:
- 相比其他方式较为复杂,使用较少。
function createObj(o) {
var F = function() {};
F.prototype = o;
return new F();
}
function Parent() {
this.name = 'parent';
}
function Child() {
this.name = createObj(new Parent()).name;
}
var child = new Child();
console.log(child.name); // "parent"
- 寄生组合继承
- 实现方式:组合继承的优化版本,通过借用构造函数和原型链,避免了父类构造函数被调用两次的问题。
- 优点:
- 避免了组合继承的缺点,只调用一次父类构造函数。
- 缺点:
- 实现稍微复杂一些。
function inheritPrototype(subType, superType) {
var prototype = createObj(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
function Parent() {
this.name = 'parent';
}
Parent.prototype.getName = function() {
return this.name;
};
function Child() {
Parent.call(this);
}
inheritPrototype(Child, Parent);
var child = new Child();
console.log(child.getName()); // "parent"
- 使用Object.create()
- 实现方式:使用Object.create()方法指定原型对象,创建一个新的对象。
- 优点:
- 更加规范和清晰,避免了原型链的污染。
- 缺点:
- 不能向父类构造函数传递参数。
function Parent() {
this.name = 'parent';
}
Parent.prototype.getName = function() {
return this.name;
};
function Child() {
this.name = 'child';
}
// 继承
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;
var child = new Child();
console.log(child.getName()); // "parent"
原文地址:https://blog.csdn.net/BDawn/article/details/140671008
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!