web前端面向对象面试25题

1 . 简述面向对象?主要特征是什么?

参考回答:

面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物,是一种是软件开发方法

面向对象主要有四大特性:
1、抽象
忽略一个主题中与当前目标无关的东西,专注的注意与当前目标有关的方面。(就是把现实世界中的某一类东西,提取出来,用程序代码表示,抽象出来的一般叫做类或者接口)。抽象并不打算了解全部问题,而是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一个数据抽象,而是过程抽象。
数据抽象 -->表示世界中一类事物的特征,就是对象的属性。比如鸟有翅膀,羽毛等(类的属性)
过程抽象 -->表示世界中一类事物的行为,就是对象的行为。比如鸟会飞,会叫(类的方法)

2、封装
封装是面向对象的特征之一,是对象和类概念的主要特性。封装就是把过程和数据包围起来,对数据的访问只能通过已定义的界面。如私有变量,用set,get方法获取。

封装保证了模块具有较好的独立性,使得程序维护修改较为容易。对应用程序的修改仅限于类的内部,因而可以将应用程序修改带来的影响减少到最低限度。

3、继承
一种联结类的层次模型,并且允许和鼓励类的重用,提供一种明确表达共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),原始类称为新类的基类(父类)。派生类可以从它的父类哪里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。因此可以说,继承为了重用父类代码,同时为实现多态性作准备。

4、多态
多态是指允许不同类的对象对同一消息做出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活/抽象/行为共享/代码共享的优势,很好的解决了应用程序函数同名问题。总的来说,方法的重写,重载与动态链接构成多态性。java引入多态的概念原因之一就是弥补类的单继承带来的功能不足。
动态链接 -->对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将调用子类中的这个方法,这就是动态链接。
2 . 简述继承的原则?

参考回答:

继承使得一个对象可以获取另一个对象的属性。使用继承可以让已经测试完备的功能得以复用,并且可以一次修改,所有继承的地方都同时生效
3 . 面向对象编程(OOP)相关解释?

参考回答:

面向对象编程(Object-Oriented Programming,OOP)是一种编程范式,它以对象作为程序的基本单元,将数据和对数据的操作(方法)封装在一起,通过对象之间的交互实现程序的功能。OOP将现实世界中的事物抽象为对象,通过模拟对象之间的关系和行为来构建软件系统。
下面是关于面向对象编程的详细说明:
对象(Object):
对象是现实世界中的实体或概念在程序中的表示。它具有属性(数据)和方法(行为)。
对象是类(Class)的具体实例化,类是对象的抽象描述。
类(Class):
类是一种定义对象的模板或蓝图,描述了对象的属性和方法。
类定义了对象的共同特征和行为,可以创建多个相同类型的对象。
封装(Encapsulation):
封装是将数据和相关的方法组合在一起,形成一个独立的实体。对象的内部数据对外部是不可见的,只能通过对象的公共接口(方法)来访问和操作数据。
封装提供了数据隐藏和保护的机制,使得对象的实现细节对其他对象是不可见的。
继承(Inheritance):
继承是一种机制,通过它,一个类(子类)可以继承另一个类(父类)的属性和方法。
继承使得类之间可以建立层次结构,子类可以继承父类的特性并添加或修改自己的特性。
继承提供了代码重用和扩展的能力,使得类与类之间形成了继承关系。
多态(Polymorphism):
多态是指同一种操作对不同的对象可以有不同的行为。在多态中,可以使用父类的引用变量来引用子类对象,通过调用父类的方法来执行子类的实现。
多态允许在运行时动态确定对象的类型,提供了灵活性和扩展性。
面向对象编程的优点包括:
可重用性:通过类的继承和对象的实例化,可以在不同的程序中重复使用现有的代码。
可扩展性:通过添加新的类和对象,可以扩展和改进现有的系统,而无需修改已有的代码。
可维护性:封装和模块化的特性使得代码更易于理解、测试和维护。
灵活性:多态的特性使得程序可以根据不同的需求以不同的方式响应。
抽象(Abstraction):
抽象是指从一组对象中提取出共同的特征和行为,形成抽象类或接口来描述这些共同的特性。
抽象类定义了一组方法的签名,但没有具体的实现。它只提供了一个框架,需要子类来实现具体的方法。
接口定义了一组方法的签名,所有实现该接口的类必须实现这些方法。
关联(Association):
关联描述了对象之间的关系。它可以是一对一、一对多、多对多等关系。
关联通过成员变量的方式表示对象之间的关系,一个对象可以引用另一个对象。
组合(Composition):
组合是一种强关联关系,表示一个对象包含另一个对象,并且另一个对象的生命周期与包含它的对象相关联。
例如,一个汽车由引擎、轮胎、座椅等组成,当汽车被销毁时,组成它的部件也会被销毁。
接口(Interface):
接口定义了一组方法的规范,没有具体的实现。它只声明了方法的签名。
类可以实现一个或多个接口,以实现接口定义的方法。
接口提供了一种契约机制,使得多个类可以按照相同的接口进行交互。
单一职责原则(Single Responsibility Principle):
单一职责原则指一个类应该只有一个引起变化的原因。一个类应该只负责一个单一的职责或功能。
这样可以提高类的内聚性和可维护性,使得修改一个功能时不会影响到其他功能。
面向对象编程是一种常用的编程范式,它将复杂的问题分解为对象,并通过对象之间的交互来解决问题。它提供了更高级别的抽象、封装和模块化,使得代码更易于理解、维护和扩展。面向对象编程在Java等许多编程语言中广泛应用,并成为开发大型软件系统的重要工具和方法。
4 . 简述抽象类和接口的理解?

参考回答:

一、抽象类:
抽象类是特殊的类,只是不能被实例化;除此以外,具有类的其他特性;重要的是抽象类可以包括抽象方法,这是普通类所不能的。抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。另外,抽象类可以派生自一个抽象类,可以覆盖基类的抽象方法也可以不覆盖,如果不覆盖,则其派生类必须覆盖它们。
二、接口:
接口是引用类型的,类似于类,和抽象类的相似之处有三点:
1、不能实例化;
2、包含未实现的方法声明;
3、派生类必须实现未实现的方法,抽象类是抽象方法,接口则是所有成员(不仅是方法包括其他成员);
另外,接口有如下特性:
接口除了可以包含方法之外,还可以包含属性、索引器、事件,而且这些成员都被定义为公有的。除此之外,不能包含任何其他的成员,例如:常量、域、构造函数、析构函数、静态成员。一个类可以直接继承多个接口,但只能直接继承一个类(包括抽象类)。
三、抽象类和接口的区别:
1.类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类叫做抽象类.而接口只是一个行为的规范或规定,微软的自定义接口总是后带able字段,证明其是表述一类类"我能做。。。".抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中.
2.接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;
3.一个类一次可以实现若干个接口,但是只能扩展一个父类
4.接口可以用于支持回调,而继承并不具备这个特点.
5.抽象类不能被密封。
6.抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的.
7.(接口)与非抽象类类似,抽象类也必须为在该类的基类列表中列出的接口的所有成员提供它自己的实现。但是,允许抽象类将接口方法映射到抽象方法上。
8.抽象类实现了oop中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的座位子类去实现。
9.好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染。
10.尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知.(结合堆栈原理理解)。同时,有心的朋友可以留意到微软在构建一个类时,很多时候用到了对象组合的方法。比如asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是非常基本的一个设计原则。
11.如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法.
5 . 列举面对对象OOD访问修饰符 ?

参考回答:

在 Java 中,访问修饰符用于限制类、方法和变量的访问范围。Java 中共有四种访问修饰符:

public:可以被任何类访问。
protected:可以被同一包内的类和不同包中的子类访问。
default(即没有修饰符):可以被同一包内的类访问。
private:只能被同一类内的方法访问,其他任何类都无法访问
6 . 接口是否可以继承接口?抽象类是否可以实现接口?抽象类是否可以继承实体类?

参考回答:

接口是可以继承接口的,抽象类是可以实现接口的,抽象类可以继承实体类,但是有个条件,条件是,实体类必须要有明确的构造函数
7 . 简述什么时候应用带参构造函数?

参考回答:

当需要对对象进行一次性的初始化时,可使用带参的构造函数。
父类拥有带参的构造时,子类继承父类,子类需编写带参数构造函数,并调用父类构造函数
8 . 简述内部类的好处 ?

参考回答:

内部类的第一个好处是------隐藏你不想让别人知道的操作,也即封装性。
内部类的第二个好处谁------每一个内部类对象可以访问创建它的外部类对象的内容,甚至包括私有变量
9 . 简述内部类的作用?

参考回答:

1.内部类可以很好的实现隐藏, 一般的非内部类,是不允许有private与protected权限的,但内部类可以
2.内部类拥有外围类的所有元素的访问权限
3.可是实现多重继承
4.可以避免修改接口而实现同一个类中两种同名方法的调用。
10 . 解释方法重载与重写的区别?

参考回答:

重载(Overloading)
(1) 方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载Overloading是一个类中多态性的一种表现。
(2) Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性。
(3) 重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。
重写(Overriding)
(1)父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
(2)若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
(3)子类函数的访问修饰权限不能少于父类的;
11 . Java中的抽象类和接口的区别?

参考回答:

1)抽象类在Java 语言中表示的是一种继承关系,一个类只能使用一次继承关系。但是,一个类却可以实现多个接口。
2)在抽象类中可以有自己的数据成员,也可以有非抽象的成员方法,而在接口中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在接口中一般不定义数据成员,接口中只能定义常量),所有的成员方法都是抽象的。
3) 抽象类和接口所反映出的设计理念不同。其实抽象类表示的是"is-a"关系,接口表示的是"like-a"关系。
4)实现抽象类和接口的类必须实现其中的所有方法。抽象类中可以有非抽象方法。接口中则不能有实现方法。
5)接口中定义的变量默认是public static final型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值。
6)抽象类中的变量默认是friendly访问级别,其值可以在子类中重新定义,也可以重新赋值。
7)接口中的方法默认都是public, abstract类型的。
12 . 简述接口隔离原则和单一原则如何理解 ?

参考回答:

单一是指接口要尽量的智能单一,不要造成为了实现一个接口,而被迫实现不需要的方法的情况。隔离的是实现和调用,这样才能真正解决团队的并行开发问题
13 . 简述面向对象的特征有哪些方面?

参考回答:

1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是选择其中的一部分,暂时不用部分细节。抽象包括两个方面,一是过程抽象,二是数据抽象。
2.继承:继承是一种联结类的层次模型,并且允许和鼓励类的重用,它提供了一种明确表述共性的方法。对象的一个新类可以从现有的类中派生,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类)而原始类称为新类的基类(父类)。派生类可以从它的基类那里继承方法和实例变量,并且类可以修改或增加新的方法使之更适合特殊的需要。
3.封装:封装是把过程和数据包围起来,对数据的访问只能通过已定义的界面。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。
4.多态性:多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化多态性和包含多态性。多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题。
14 . 简述封装具有的特性?

参考回答:

(1)在类的定义中设置访问对象属性(数据成员)及方法(成员方法)的权限,限制本类对象及其他类的对象使用的范围。
(2)提供一个接口来描述其他对象的使用方法
(3)其他对象不能直接修改本对象所拥有的属性和方法
(4)封装反映了事物的相对独立性
(5)封装在编程上的作用是使对象以外的部分不能随意存取对象的内部数据(属性),从而有效地避免了外部错误对它的"交叉感染"。
(6)当对象的内部做了某些修改时,由于它只通过少量的接口对外提供服务,因此大大减少了内部的修改对外部的影响。
(7)面向对象系统的封装单位是对象,类概念本身也具有封装的意义,因为对象的特性是由它所属的类说明来描述的
15 . 简述JavaScript如何通过new构建对象?

参考回答:

通过new操作符构建对象的步骤如下。
(1)创建一个新的对象,这个对象的类型是 object.
(2)将this变量指向该对象。
(3)将对象的原型指向该构造函数的原型。
(4)执行构造函数,通过this对象,为实例化对象添加自身属性方法。
(5)将this引用的新创建的对象返回。
代码如下。
function demo(Base) {
var obj ={};
//this =obj
obj. __proto__= Base. prototype;
School.call(obj)
return obj
}
16 . JavaScript是怎么样实现继承的?

参考回答:

方法1:借助构造函数实现继承(部分继承)

/**
* 借助构造函数实现继承
*/
function Parent1() {
this.name = 'parent';
}
Parent1.prototype.say = function() {}; // 不会被继承
function Child1() {
// 继承:子类的构造函数里执行父级构造函数
// 也可以用apply
// parent的属性都会挂载到child实例上去
// 借助构造函数实现继承的缺点:①如果parent1除了构造函数里的内容,还有自己原型链上的东西,
自己原型链上的东西不会被child1继承
// 任何一个函数都有prototype属性,但当它是构造函数的时候,才能起到作用(构造函数是有自己的
原型链的) Parent1.call(this);
this.type = 'child1';
}
console.log(new Child1);

(1)如果父类的属性都在构造函数内,就会被子类继承。
(2)如果父类的原型对象上有方法,子类不会被继承。


方法2:借助原型链实现继承

/**
* 借助原型链实现继承
*/
function Parent2() {
this.name = 'name';
this.play = [1, 2, 3]
}
function Child2() {
this.type = 'child2';
}
Child2.prototype = new Parent2(); // prototype使这个构造函数的实例能访问到原型对象上
console.log(new Child2().__proto__);
console.log(new Child2().__proto__ === Child2.prototype); // true
var s1 = new Child2(); // 实例
var s2 = new Child2();
console.log(s1.play, s2.play);
s1.play.push(4);
console.log(s1.__proto__ === s2.__proto__); // true // 父类的原型对象

(1)原型链的基本原理:构造函数的实例能访问到它的原型对象上
(2)缺点:原型链中的原型对象,是共用的


方法3:组合方式

/**
①组合方式优化1:
②组合方式优化2(最优解决方案):
* 组合方式
*/
function Parent3() {
this.name = 'name';
this.play = [1, 2, 3];
}
function Child3() {
Parent3.call(this);
this.type = 'child3';
}
Child3.prototype = new Parent3();
var s3 = new Child3();
var s4 = new Child3();
s3.play.push(4);
console.log(s3.play, s4.play);
// 父类的构造函数执行了2次
// 构造函数体会自动执行,子类继承父类的构造函数体的属性和方法

①组合方式优化1:
/**
* 组合继承的优化方式1:父类只执行了一次
*/
function Parent4() {
this.name = 'name';
this.play = [1, 2, 3];
}
function Child4() {
Parent4.call(this);
this.type = 'child4';
}
Child4.prototype = Parent4.prototype; // 继承父类的原型对象
var s5 = new Child4();
var s6 = new Child4();
console.log(s5 instanceof Child4, s5 instanceof Parent4); // true
console.log(s5.constructor); // Parent4 //prototype里有个constructor属性,子类和 父
类的原型对象就是同一个对象, s5的constructor就是父类的constructor

②组合方式优化2(最优解决方案):

/**
* 组合继承优化2
*/
function Parent5() {
this.name = 'name';
this.play = [1, 2, 3];
}
function Child5() {
Parent5.call(this);
this.type = 'child5';
}
Child5.prototype = Object.create(Parent5.prototype); // Object.create创建的对象 就
是参数 Child5.prototype.constructor = Child5; var s7 = new Child5();
console.log(s7 instanceof Child5, s7 instanceof Parent5);
console.log(s7.constructor); // 构造函数指向Child5

优缺点:
原型链继承的缺点
1、字面量重写原型
一是字面量重写原型会中断关系,使用引用类型的原型,并且子类型还无法给超类型传递参数。
2、借用构造函数(类式继承)
借用构造函数虽然解决了刚才两种问题,但没有原型,则复用无从谈起。所以我们需要原型链+借用构
造函数的模式,这种模式称为组合继承
3、组合式继承
组合式继承是比较常用的一种继承方法,其背后的思路是 使用原型链实现对原型属性和方法的继承,而
通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又保证
每个实例都有它自己的属性。
17 . 简述JavaScript中继承的实现方法?

参考回答:

方法1:借助构造函数实现继承(部分继承)

/**
* 借助构造函数实现继承
*/
function Parent1() {
this.name = 'parent';
}
Parent1.prototype.say = function() {}; // 不会被继承
function Child1() {
// 继承:子类的构造函数里执行父级构造函数
// 也可以用apply
// parent的属性都会挂载到child实例上去
// 借助构造函数实现继承的缺点:①如果parent1除了构造函数里的内容,还有自己原型链上的东西,
自己原型链上的东西不会被child1继承
// 任何一个函数都有prototype属性,但当它是构造函数的时候,才能起到作用(构造函数是有自己的
原型链的) Parent1.call(this);
this.type = 'child1';
}
console.log(new Child1);

(1)如果父类的属性都在构造函数内,就会被子类继承。
(2)如果父类的原型对象上有方法,子类不会被继承。


方法2:借助原型链实现继承

/**
* 借助原型链实现继承
*/
function Parent2() {
this.name = 'name';
this.play = [1, 2, 3]
}
function Child2() {
this.type = 'child2';
}
Child2.prototype = new Parent2(); // prototype使这个构造函数的实例能访问到原型对象上
console.log(new Child2().__proto__);
console.log(new Child2().__proto__ === Child2.prototype); // true
var s1 = new Child2(); // 实例
var s2 = new Child2();
console.log(s1.play, s2.play);
s1.play.push(4);
console.log(s1.__proto__ === s2.__proto__); // true // 父类的原型对象

(1)原型链的基本原理:构造函数的实例能访问到它的原型对象上
(2)缺点:原型链中的原型对象,是共用的


方法3:组合方式

/**
①组合方式优化1:
②组合方式优化2(最优解决方案):
* 组合方式
*/
function Parent3() {
this.name = 'name';
this.play = [1, 2, 3];
}
function Child3() {
Parent3.call(this);
this.type = 'child3';
}
Child3.prototype = new Parent3();
var s3 = new Child3();
var s4 = new Child3();
s3.play.push(4);
console.log(s3.play, s4.play);
// 父类的构造函数执行了2次
// 构造函数体会自动执行,子类继承父类的构造函数体的属性和方法

①组合方式优化1:
/**
* 组合继承的优化方式1:父类只执行了一次
*/
function Parent4() {
this.name = 'name';
this.play = [1, 2, 3];
}
function Child4() {
Parent4.call(this);
this.type = 'child4';
}
Child4.prototype = Parent4.prototype; // 继承父类的原型对象
var s5 = new Child4();
var s6 = new Child4();
console.log(s5 instanceof Child4, s5 instanceof Parent4); // true
console.log(s5.constructor); // Parent4 //prototype里有个constructor属性,子类和 父
类的原型对象就是同一个对象, s5的constructor就是父类的constructor

②组合方式优化2(最优解决方案):

/**
* 组合继承优化2
*/
function Parent5() {
this.name = 'name';
this.play = [1, 2, 3];
}
function Child5() {
Parent5.call(this);
this.type = 'child5';
}
Child5.prototype = Object.create(Parent5.prototype); // Object.create创建的对象 就
是参数 Child5.prototype.constructor = Child5; var s7 = new Child5();
console.log(s7 instanceof Child5, s7 instanceof Parent5);
console.log(s7.constructor); // 构造函数指向Child5

优缺点:
原型链继承的缺点
1、字面量重写原型
一是字面量重写原型会中断关系,使用引用类型的原型,并且子类型还无法给超类型传递参数。
2、借用构造函数(类式继承)
借用构造函数虽然解决了刚才两种问题,但没有原型,则复用无从谈起。所以我们需要原型链+借用构
造函数的模式,这种模式称为组合继承
3、组合式继承
组合式继承是比较常用的一种继承方法,其背后的思路是 使用原型链实现对原型属性和方法的继承,而
通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又保证
每个实例都有它自己的属性。
18 . 简述JavaScript构造函数的特点 ?

参考回答:

构造函数的函数名首字母大写,构造函数类似于一个模板,可以使用new关键字执行构造函数,创建实例化对象
19 . 简述列出 JavaScript常用继承方式并说明其优缺点 ?

参考回答:

常用继承方式及其优缺点如下。
(1)构造函数式继承是指在子类的作用域上,执行父类的构造函数,并传递参数构造函数式继承虽然解决了对父类构造函数的复用问题,但没有更改原型。
(2)类(原型链)式继承是指将父类的实例化对象添加给子类的原型。执行构造函数是没有意义的,因为我们只想继承原型链上的属性和方法,当执行父类的构造函数时,没有添加参数,所以执行构造函数的结果是不正确的。父类构造函数中的数据,没有直接添加在子类的实例化对象上,而是添加在原型上。子类型实例化时无法复用父类的构造函数。
(3)组合式继承是比较常用的一种继承方法,其背后的思路是,使用原型链实现对原型属性和方法的继承,而通过构造函数来实现对实例属性的继承。这样,既在原型上定义方法实现了函数复用,又保证每个实例都有它自己的属性。但其问题是导致父类的构造函数执行了两次:一次是在构造函数式继承中执行的;另一次是在类式继承中执行的。
使用上述继承要注意以下几点
(1)在构造函数式继承中,属性的赋值一定在继承的后面执行,否则会产生覆盖问题。
(2)在类式继承中,原型上属性或者方法的赋值一定在继承后面,否则会产生覆盖问题。
(3)在类式继承中,在原型上添加属性或者方法一定使用点语法的形式,不可以给对象赋值。
(4)在类式继承中,要为原型添加属性方法对象,可以在继承后面通过库的 extend方法(或 ECMAScript6提供了 assign方法)实现。
20 . 用 JavaScript写一个实现寄生式继承的方法 ?

参考回答:

以下代码实现了寄生式继承方法 inherit。
var inherit =(function() {
//定义寄生类
function F() {
}
;
return function(sub, sup) {
//寄生类的原型指向父类
E.prototype= sup.prototype;
//继承父类的原型
sub.prototype=new F ();
//更正构造函数
sub.prototype.constructor =sub;
//返回子类
return sub;
}
}
)()
//父类
function Star(names) {
this.names = names
}
Star.prototype.getNames = function() {
return this.names
//子类
function Moviestar(names, age) {
//构造函数式继承
Star.apply(this, arguments)
this.age = age;
//寄生式继承
inherit(Moviestar, star);
MovieStar.prototype.getAge =function () {
return this.age;
}
console. log(new Moviestar( 'xiao bai', 20))
21 . 简述说出你熟知的 Javascript继承方式 ?

参考回答:

有以下几种继承方式
(1)构造函数式继承。
(2)类(原型链)式继承。
(3)组合式继承(混合使用构造函数式和类式)。
(4)寄生式继承。
(5)继承组合式继承(混合使用构造函数式和寄生式)。
(6)原子继承。
(7)多继承。
(8)静态继承。
(9)特性继承。
(10)构造函数拓展式继承。
(11)工厂式继承
22 . JavaScript如何判断某个对象是否包含指定成员?

参考回答:

通过以下方式判断。
(1)使用 obj. hasOwnProperty(" ")。
如果找到,返回true;否则,返回 false。
(2)使用"属性名"in对象如果找到,返回true;否则,返回 false。
(3)直接使用ob属性名作为判断的条件,如下所示。
if (obj. demo === undefined)
若不包含,条件值为true;若包含,条件值为 false
23 . 简述JavaScript this通常指向 ?

参考回答:

在运行时,this关键字指向正在调用该方法的对象

1、作为构造函数执行
function Foo(name) {
this.name = name;
}
var f = new Foo('zhangsan')

2、作为对象属性执行
var obj = {
name: 'A',
printName: function() {
console.log(this.name);
}
}
obj.printName();

3、作为普通函数执行
function fn() {
console.log(this);
}
fn();

4、call apply bind
function fn1(name, age) {
alert(name);
console.log(this);
}
fn1.call({x: 100}, 'zhangsan', 20);
fn1.apply({x:100}, ['zhangsan', 20])
var fn2 = function (name, age) {
// 必须是函数表达式,不能是函数声明,即不能是function fn2(name, age) {}
alert(name); console.log(this);
}.bind({y:200});
fn2('zhangsan', 20);
24 . JavaScript如何判断属性是自有属性还是原型属性?

参考回答:

方法如下
(1)要判断自有属性,使用 obj. hasOwn Property("属性名")
(2)要判断原型属性,使用"属性名" in obj&&!obj.hasOwn Property("属性名")的形式。
25 . JavaScript 实现对象的继承有哪几种方式?

参考回答:

(1)修改对象的 _proto_,如下所示
Object.set Prototypeof(子对象,父对象)
(2)修改构造函数的原型对象,如下所示。
构造函数.prototype=对象
(3)使用原子继承方法 Object.create(父对象[, {
属性列表
}
]),如下所示。
var demo = Object.create(obj)
相关推荐
NiNg_1_23425 分钟前
后端id设置long类型时,传到前端,超过19位最后两位为00
前端
小白小白从不日白2 小时前
react 事件处理
前端·react.js
ZhangTao_zata2 小时前
前端知识点
前端·javascript·css
GDAL2 小时前
HTML5中`<ul>`标签深入全面解析
前端·html·html5
桃子叔叔2 小时前
前端工程化3:使用lerna管理多包
前端·前端工程化·lerna
下雪天的夏风2 小时前
Vant 按需引入导致 Typescript,eslint 报错问题
前端·typescript·eslint
流浪的大萝卜2 小时前
开发一个电商API接口的步骤!!!
java·大数据·前端·数据仓库·后端·爬虫·python
2301_796982142 小时前
requests-html的具体使用方法有哪些?
前端·python·html
运维Z叔3 小时前
利用shuji还原webpack打包源码
服务器·前端·webpack·node.js·postman·xss·csrf
不cong明的亚子3 小时前
webpack5-手撸RemoveConsolePlugin插件
前端·webpack·react