💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] # 题1、面向对象编程的英文缩写? 答:OOP (Object Oriented Programming,面向对象编程)。 # 题2、面向对象编程和面向过程编程有什么区别? 答: 面向过程编程(OOP):把功能封装成一个个的函数,然后通过调用函数来实现功能。(以函数为主) 面向对象编程: 把功能封装成类,然后通过类创建对象,通过对象来实现功能。(以对象为主) # 题3、类和对象是什么关系? 答: 必须先有类才能创建出对象,对象是由类创建出来的,一个类可以创建多个对象。 举个现实中的例子:比如盖房子:类就是图纸(房子长什么样),对象就是盖出来的房子(实体)。 一个图纸可以创建出N个实际的房子。 类就是对象的图纸,类中描述了对象长什么样(属性),有哪些功能(方法) # 题4、 JS 中如何定义一个类? 答: 在 Js 中主要有两种方法定义类: ES5 之前的方法(传统方法):使用 function ~~~ // 定义 People 类(类的构造函数) function People() { } ~~~ ES6 中的新方法:使用 class ~~~ class People { } ~~~ # 题5、类里面都可以放什么东西? 答:属性(变量)和方法(函数)。 如何定义语法: ES5 之前的方法(传统方法): 使用 function ~~~ // 定义 People 类(类的构造函数) function People() {    // 属性    this.name = ''    this.age = 0 } // 为类添加 hello 方法 People.prototype.hello = function() {    console.log('hello') } ~~~ ES6 中的新方法:使用 class ~~~ class People {    // 属性    name = ''    age = ''    // 方法    hello() {        console.log('hello')   } } ~~~ # 题6、如何创建一个对象? 答: 使用 new 。 代码演示:创建 People 类的对象 ~~~ // 定义 People 类(类的构造函数) function People() {    // 属性    this.name = ''    this.age = 18 } // 为类添加 hello 方法 People.prototype.hello = function () {    console.log('hello'); } ​ // 创建对象 let p1 = new People() let p2 = new People() let p3 = new People() ​ /// 调用对象中的方法 p1.hello()  // 让 p1 说 hello p2.hello()  // 让 p2 说 hello p3.hello()  // 让 p3 说 hello ~~~ # 题7、什么是原型链?干什么用的? 答: 1. 每个对象都有一个父对象,这个父对象就叫做这个对象的原型,父对象还有父对象就形成一个链,所以叫做原型链。 2. 原型链的特点:当我们使用一个对象的属性和方法时,如果对象中没有这个属性和方法,那么就会到它的父对象中去找,如果还没有就再找父对象中去找。 3. 基于这个特点的用途:主要再OOP时使用,把对象公共的方法写到原型上 原型的主要用途:保存公共的方法,避免重复定义 ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf7flkhtw5j31200iedqu.jpg) 代码演示: ~~~ // 不好的例子: function People() {    this.name = ''    // 方法直接定义在类中(不好!!),每new一个对象,这个对象体内就会有一个 hello 方法,    this.hello = function() {        console.log('hello')   } } // 每个对象的体内都有一个完全相同的 hello 方法(不好!!!浪费内存!!) let p1 = new People() let p2 = new People() let p2 = new People() ​ // 好的做法:把方法定义到原型上 function People() {    this.name = '' } People.prototype.hello = function() {    console.log('hello') } // 每个对象体内没有 hello 方法,当使用hello 方法时,它们会到同一个原型上去(hello 在内存中定义了一次) let p1 = new People() let p2 = new People() let p2 = new People() ~~~ # 题8、在原型链有 prototype 和 proto 两个属性是干什么用的? 答:JS 中通过 prototype 和 **proto** 才能够实现原型链机制。 函数对象访问原型对象:**prototype** 。 普通对象访问原型对象:**proto** 。 ~~~ // 函数对象 function Hello() { } // 访问 Hello 的原型(函数对象) console.log(  Hello.prototype   ) ​ ​ // 普通对象 let p1 = {name:'tom'} // 访问 p1 对象的原型(普通对象) console.log( p1.__proto__ ) ~~~ # 题9、原型链有终点吗? 答: JS 中所有对象的最终的原型都是 Object 这个函数对象,再往上就是 null 。 总结: 1. Object 的原型是所有 JS 中对象的祖先原型 2. 原型链的终点是 null ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf7g2y8uh1j30y00u6jxs.jpg) # 题10、什么是构造函数?什么是析构函数? 答: 构造函数:创建对象时被调用的函数。 析构函数:对象被销毁时被调用的函数。(Js 中没有析构函数) ~~~ // ES5 (People 就是构造函数也是类) function People() { } let p1 = new People()  // People 函数在创建对象时执行 ​ ​ // ES6 新语法 class People {    // construtor 是构造函数,在创建对象时会被调用    construdtor() {   } } ~~~ # 题11、apply 和 call 的用途和区别? 答:用途: 改变 this 的指向。 区别: 传参数的方式不同。 this的含义: 在普通函数中:this 代表调用这个函数时的对象。 在箭头函数中:自己没有 this,箭头函数中的 this 是从上一级函数中继承过来的 this (上一级的 this)。 **用途:** 代码演示、apply 和 call 的用途 (改变函数中 this 的指向) ~~~ let people = {    name: 'tom',    hello: function () {        console.log(this.name); ​   } } people.hello()  // tom , this 代表 people 这个对象 ​ let boy = {    name: 'jack' } people.hello.call(boy) // jack , 修改 people.hello 中的 this 指向 boy 对象 people.hello.apply(boy) // jack , 修改 people.hello 中的 this 指向 boy 对象 ​ ​ ~~~ 代码演示2、 ~~~ function hello() {    console.log(this.name) } let a = {    name: 'tom' } let b = {    name: 'jack' } hello.call(a)   // tom ,修改 hello 函数中的 this 指向 a 对象 hello.apply(b)  // jack , 修改 hello 函数中的 this 指向 b 对象 ​ ~~~ **区别:** 当函数有参数时,call 和 apply 在传参数时的形式不同。 代码演示、 ~~~ function hello(a, b) {    console.log(this.name + '-' + a + b) } let a = {    name: 'tom' } hello.call(a, 10, 40)   // tom-1040 hello.apply(a, [10, 40])    // tom-1040 ​ ~~~ # 题12、什么是继承? 答:继承:一个对象如果有父对象,那么父对象中的属性和方法也同样被子对象所拥有。 ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf8h196snyj30w60fyguy.jpg) # 题13、OOP 的三大特性是什么? 答:封装、继承、多态。 封装:把功能代码封装成一个一个的类来使用。 继承:子类直接拥有(继承)父类中的属性和方法。 多态:父类中的同一个方法被不同的子类继承之后,表示出不同的形态。 ![](http://ww1.sinaimg.cn/large/007WurYGgy1gf8h5iamjsj30ua0i4jzf.jpg) # 题14、this 是干什么用的? 答:this 一般都会使用在函数中,代表调用这个函数时的对象。 this 在普通函数和箭头函数中的含义不同: 普通函数中: this 代表调用这个函数时的对象。(this 绑定的对象是在 `调用函数` 时确定) ~~~ let people = {    name: 'tom',    hello: function() {        console.log(this.name)   } } let b = {    name: 'jack' } people.hello.call(b)  // this 代表 b people.hello()    // this 代表 people ​ ~~~ 箭头函数: this 代表它外层函数中的 this 。(this 在定义箭头函数时就已经确定)无法通过 call 和 apply 改变箭头函数中的 this 。 # 题15、prototype 是干什么用的? 答:函数对象用来引用原型对象的(父对象)。 ~~~ // 函数对象 function Abc() { } // 打印函数对象的原型对象(父对象) console.log(Abc.prototype) ​ ~~~ # 题16、JS 是如何实现继承的? ​ 答:通过原型链可以到父类中找需要使用的属性和方法,实现继承。 # 题17、如何为对象动态的添加属性和方法? 答:对象.xxx=xxx 代码演示: ~~~ let boy = {} // 为对象添加属性(变量) boy.name = 'tom' boy.age = 100 // 为对象添加方法(函数) boy.hello = function() {    console.log(this.name) } boy.getAge = function() {    return this.age } ​ ~~~ # 题18、对象是如何创建的? 答: 方法一、直接使用{}定义 ~~~ let boy = {    name: 'tom',    age: 10 } ​ ~~~ 方法二、使用 new 关键字 ~~~ let obj = new Objack() ​ ~~~ # 题19、如何从对象中动态的删除一个属性? 答:使用 delete . ~~~ let boy = {} // 为对象添加属性(变量) boy.name = 'tom' boy.age = 18 ​ // 删除 age 属性 delete boy.age ​ ~~~