2020面试收获

Wesley13
• 阅读 539

2020面试收获 一、前言

2020年是特殊的一年,由于疫情原因,大家都窝在家办公。而我则怀着梦想,从天津来到了北京,开启了人生的第一次跳槽。

在面试过程中,频频被原型相关知识问住,每次回答都支支吾吾。后来有家非常心仪的公司,在二面时,果不其然,又问原型了!

我痛下决心用了两天时间钻研了下原型,弄明白后发现世界都明亮了,原来这么简单 ~

有些理解还比较浅薄,随着时间的推移和理解的深入,以后还会补充。如果大家发现我理解的有问题,欢迎大家在评论中指正。话不多说,切入正题。

===

二、构造函数

讲原型则离不开构造函数,让我们先来认识下构造函数。

2.1 构造函数分为 实例成员 和 静态成员

让我们先来看看他们分别是什么样子的。

实例成员:实例成员就是在构造函数内部,通过this添加的成员。实例成员只能通过实例化的对象来访问。

静态成员:在构造函数本身上添加的成员,只能通过构造函数来访问

function Star(name,age) {

2.2 通过构造函数创建对象

该过程也称作实例化

2.2.1 如何通过构造函数创建一个对象?

 function Father(name) {

此时,son就是一个新对象。

2.2.2 new一个新对象的过程,发生了什么?

(1) 创建一个空对象 son {}
(2) 为 son 准备原型链连接son.__proto__ = Father.prototype
(3) 重新绑定this,使构造函数的this指向新对象Father.call(this)
(4) 为新对象属性赋值son.name
(5) 返回this return this,此时的新对象就拥有了构造函数的方法和属性了

2.2.3 每个实例的方法是共享的吗?

这要看我们如何定义该方法了,分为两种情况。

方法1:在构造函数上直接定义方法(不共享)
function Star() {

很明显,stu1 和 stu2 指向的不是一个地方。所以 在构造函数上通过this来添加方法的方式来生成实例,每次生成实例,都是新开辟一个内存空间存方法。这样会导致内存的极大浪费,从而影响性能。

方法2:通过原型添加方法(共享)

构造函数通过原型分配的函数,是所有对象共享的。

   function Star(name) {

2.2.4 实例的属性为基本类型是,它们是共享的吗?

属性存储的是如果存储的是基本类型,不存在共享问题,是否相同要看值内容。

let stu1 = new Star('小红');

2.2.5 定义构造函数的规则

公共属性定义到构造函数里面,公共方法我们放到原型对象身上。

===

三、原型

前面我们在 实例化 和 实例共享方法 时,都提到了原型。那么现在聊聊这个神秘的原型到底是什么?

3.1 什么是原型?

Father.prototype 就是原型,它是一个对象,我们也称它为原型对象。

3.2 原型的作用是什么?

原型的作用,就是共享方法。

我们通过 Father.prototype.method 可以共享方法,不会反应开辟空间存储方法。

3.3 原型中this的指向是什么?

原型中this的指向是实例。

四、原型链

4.1 什么是原型链?

原型与原型层层相链接的过程即为原型链。

4.2 原型链应用

对象可以使用构造函数prototype原型对象的属性和方法,就是因为对象有__proto__原型的存在
每个对象都有__proto__原型的存在

function Star(name,age) {

4.3 原型链图

2020面试收获

4.4 原型查找方式

例如:查找obj的dance方法

function Star(name) {

(1)首先看obj对象身上是否有dance方法,如果有,则执行对象身上的方法。

(2)如果没有dance方法,就去构造函数原型对象prototype身上去查找dance这个方法。

(3)如果再没有dance方法,就去Object原型对象prototype身上去查找dance这个方法。

(4)如果再没有,则会报错。

4.5 原型的构造器

原型的构造器指向构造函数。

 function Star(name) {

4.5.1 在原型上添加方法需要注意的地方

方法1:构造函数.prototype.方法在原型对象上直接添加方法,此时的原型对象是有constructor构造器的,构造器指向构造函数本身

 function Star(name) {

方法2:Star.prototype = {}给原型重新赋值,此时会丢失构造器,我们需要手动定义构造器,指回构造函数本身

function Star(name) {

4.5.2 一般不允许直接改变原型prototype指向

改变原型指向,会使原生的方法都没了,所以Array、String这些内置的方法是不允许改变原型指向的。如果改变了,就会报错。

  Array.prototype.getSum = function (arr) {

如果改变prototype指向,会报错!

Array.prototype = {

五、继承 - ES5方法

ES6之前并没有给我们提供extends继承,我们可以通过构造函数+原型对象模拟实现继承。

继承属性,利用call改变this指向。但该方法只可以继承属性,实例不可以使用父类的方法。

 function Father(name) {

如何继承父类的方法呢?

解决方法1:利用Son.prototype = Father.prototype改变原型指向,但此时我们给子类增加原型方法,同样会影响到父类。

 function Father(name) {

解决方法2:子类的原型指向父类的实例,这样就可以顺着原型链共享父类的方法了。并且为子类添加原型方法的时候,不会影响父类。

 function Father(name) {

2020面试收获

六、类

什么是类?

类的本质还是一个函数,类就是构造函数的另一种写法。

function Star(){}

ES6中类没有变量提升

通过构造函数创建实例,是可以变量提升的。es6中的类,必须先有类,才可以实例化。

类的所有方法都定义在类的prototype属性上面

让我们来测试一下。

  class Father{

向类中添加方法

通过Object.assign,在原型上追加方法。

class Father{

constructor方法

constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

===

七、继承 - ES6方法

 class Father {

八、类和构造函数的区别

(1) 类必须使用new调用,否则会报错。这是它跟普通构造函数的一个主要区别,后者不用new也可以执行。

(2) 类的所有实例共享一个原型对象。

(3) 类的内部,默认就是严格模式,所以不需要使用use strict指定运行模式。

===

九、总结

构造函数特点:

1.构造函数有原型对象prototype。

2.构造函数原型对象prototype里面有constructor,指向构造函数本身。

3.构造函数可以通过原型对象添加方法。

4.构造函数创建的实例对象有__proto__原型,指向构造函数的原型对象。

类:

1.class本质还是function

2.类的所有方法都定义在类的prototype属性上

3.类创建的实例,里面也有__proto__指向类的prototype原型对象

4.新的class写法,只是让对象原型的写法更加清晰,更像面向对象编程的语法而已。

5.ES6的类其实就是语法糖。

===

十、什么是语法糖

什么是语法糖?加糖后的代码功能与加糖前保持一致,糖在不改变其所在位置的语法结构的前提下,实现了运行时的等价。

语法糖没有改变语言功能,但增加了程序员的可读性。

===

十一、面试题分享

面试题1

Object.prototype.__proto__    //null

讲解:这里涉及到Function的原型问题,附一张图,这图是一个面试官发给我的,我也不知道原作者在哪里~

2020面试收获

面试题2

给大家分享那道我被卡住的面试题,希望大家在学习完知识后,可以回顾一下。

按照如下要求实现Person 和 Student 对象 a)Student 继承Person b)Person 包含一个实例变量 name, 包含一个方法 printName c)Student 包含一个实例变量 score, 包含一个实例方法printScore d)所有Person和Student对象之间共享一个方法

es6类写法

  class Person {

原生写法

 function Person (name){

源自:https://juejin.im/post/5e6e000fe51d4526f071efea

声明:文章著作权归作者所有,如有侵权,请联系小编删除。

感谢 · 转发欢迎大家留言

2020面试收获

本文分享自微信公众号 - web前端学习圈(web-xxq)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Android蓝牙连接汽车OBD设备
//设备连接public class BluetoothConnect implements Runnable {    private static final UUID CONNECT_UUID  UUID.fromString("0000110100001000800000805F9B34FB");
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这