学习教材为:https://wangdoc.com/javascript/oop/index.html
1 如何理解编程语言中的对象?有哪些生成对象的方法?
面向对象编程(Object Oriented Programming,缩写为 OOP)是目前主流的编程范式。它将真实世界各种复杂的关系,抽象为一个个对象,然后由对象之间的分工与合作,完成对真实世界的模拟。
1)对象是单个实物的抽象。
2)对象是一个容器,封装了属性(property)和方法(method)。
2 面向对象编程的利弊?
利:易维护、质量高、效率高、易扩展
弊:类和继承等特点使得程序会多很多指针操作来定位函数入口和自身要维护虚拟方法表等额外的工作,程序的处理效率相对要低(但程序开发效率高)。
3 谈谈JavaScript 语言的对象体系
在JavaScript中一切皆对象。Everything is object(万物皆对象), JS语言中将一切都视为对象。
4 Object方法如何处理参数是原始类型的值?
Object 方法会将其转为对应的包装对象的实例。
5 什么是构造函数?和普通函数的区别在哪?
所谓”构造函数”,就是专门用来生成实例对象的函数。它就是对象的模板,描述实例对象的基本结构。一个构造函数,可以生成多个实例对象,这些实例对象都有相同的结构。
区别:构造函数名字的第一个字母通常大写。
6 new命令有什么作用?
new命令的作用,就是执行构造函数,返回一个实例对象。
7 如果忘了使用new命令,直接调用构造函数会发生什么事?
这种情况下,构造函数就变成了普通函数,并不会生成实例对象。而且由于后面会说到的原因,this这时代表全局对象,将造成一些意想不到的结果。
8 使用new命令时,会执行哪些的步骤?
1.创建一个空对象,作为将要返回的对象实例。
2.将这个空对象的原型,指向构造函数的prototype属性。
3.将这个空对象赋值给函数内部的this关键字。
4.开始执行构造函数内部的代码。
9 什么是this?
this指的是一个新生成的空对象,所有针对this的操作,都会发生在这个空对象上。构造函数之所以叫“构造函数”,就是说这个函数的目的,就是操作一个空对象(即this对象),将其“构造”为需要的样子。
10 this都有哪些指向?
1.全局环境使用this,它指的就是顶层对象window。
2.构造函数中的this,指的是实例对象。
3.如果对象的方法里面包含this,this的指向就是方法运行时所在的对象。该方法赋值给另一个对象,就会改变this的指向。
11 为何JavaScript 语言有 this 的设计?
JavaScript 语言之所以有 this 的设计,跟内存里面的数据结构有关系。
12 this有哪些使用场合?
全局环境
构造函数
对象的方法
13 使用this 有哪些注意点?
1.由于this的指向是不确定的,所以切勿在函数中包含多层的this。
2.数组的map和foreach方法,允许提供一个函数作为参数。这个函数内部不应该使用this。
3.回调函数中的this往往会改变指向,最好避免使用。
14 如何改变this的指向?
1.将对象中的方法赋值给另一个对象,就会改变this的指向。
2.call 和 apply方法可以改变this指向,然后再调用该函数。
15 JavaScript 语言继承的机制?
面向对象编程很重要的一个方面,就是对象的继承。A 对象通过继承 B 对象,就能直接拥有 B 对象的所有属性和方法。这对于代码的复用是非常有用的
16 JS都有哪些实现继承的方式?
1.原型链继承
2.借用构造函数继承(伪造对象、经典继承)
3.实例继承(原型式继承)
4.组合式继承
5.寄生组合继承
17 如何理解原型链?
从一个实例对象向上找有一个构造实例的原型对象,这个原型对象又有构造它的上一级原型对象,如此一级一级的关系链,就构成了原型链。原型链的最顶端就是Object.prototype。
18 instanceof 运算符的作用?
instanceof运算符的一个用处,是判断值的类型。
19 JavaScript 如何实现多重继承?
JavaScript 不提供多重继承功能,即不允许一个对象同时继承多个对象。但是,可以通过变通方法,实现这个功能。
function M1() {
this.hello = 'hello';
}
function M2() {
this.world = 'world';
}
function S() {
M1.call(this);
M2.call(this);
}
// 继承 M1
S.prototype = Object.create(M1.prototype);
// 继承链上加入 M2
Object.assign(S.prototype, M2.prototype);
// 指定构造函数
S.prototype.constructor = S;
var s = new S();
s.hello // 'hello'
s.world // 'world'
20 如何实现JavaScript 模块化编程?
1.简单的做法是把模块写成一个对象,所有的模块成员都放到这个对象里面。这样的写法会暴露所有模块成员,内部状态可以被外部改写。比如,外部代码可以直接改变内部计数器的值。
2.我们可以利用构造函数,封装私有变量。这种方法将私有变量放入实例对象中,好处是看上去更自然,但是它的私有变量可以从外部读写,不是很安全。
3.另一种做法是使用“立即执行函数”(Immediately-Invoked Function Expression,IIFE),将相关的属性和方法封装在一个函数作用域里面,可以达到不暴露私有成员的目的。
4.如果一个模块很大,必须分成几个部分,或者一个模块需要继承另一个模块,这时就有必要采用“放大模式”(augmentation)。
5.独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互。
为了在模块内部调用全局变量,必须显式地将其他变量输入模块。
21 Object 对象的相关方法有哪些?
1.Object.getPrototypeOf方法返回参数对象的原型。这是获取原型对象的标准方法。
2.Object.setPrototypeOf方法为参数对象设置原型,返回该参数对象。它接受两个参数,第一个是现有对象,第二个是原型对象。
3.Object.create()方法,该方法接受一个对象作为参数,然后以它为原型,返回一个实例对象。该实例完全继承原型对象的属性。
实例对象的isPrototypeOf方法,用来判断该对象是否为参数对象的原型。
4.Object.getOwnPropertyNames方法返回一个数组,成员是参数对象本身的所有属性的键名,不包含继承的属性键名。
5.对象实例的hasOwnProperty方法返回一个布尔值,用于判断某个属性定义在对象自身,还是定义在原型链上。
6.in运算符返回一个布尔值,表示一个对象是否具有某个属性。它不区分该属性是对象自身的属性,还是继承的属性。
22 为何会有严格模式?
1.明确禁止一些不合理、不严谨的语法,减少 JavaScript 语言的一些怪异行为。
2.增加更多报错的场合,消除代码运行的一些不安全之处,保证代码运行的安全。
3.提高编译器效率,增加运行速度。
4.为未来新版本的 JavaScript 语法做好铺垫。