前端试题(三)

1. js继承的7种方式

回顾:

  1. 每个构造函数都有一个原型对象;
  2. 原型对象都包含一个指向构造函数的指针;
  3. 实例都包含一个指向原型对象的内部指针;
  4. 一切皆为对象,只要是对象,就会有 proto 属性,该属性存储了指向其构造的指针。

1.1确定原型和实例的关系:

1.1.1instanceOf

使用 instanceof操作符来检测实例与原型链中出现过的构造函数,结果就会返回true
因此可以说instance是Object、SuperType或SubType中任何一个类型的原型。

1.1.2 isPrototypeOf

只要是原型链中出现过的原型,都可以说是该原型链派生的实例的原型,因此isPrototypeOf()方法也会返回true

Object.prototype.isPrototypeOf(instance)
SuperType.prototype.isPrototypeOf(instance)
SubType.prototype.isPrototypeOf(instance)

1.2 7中方式

1.2.1 原型链:子类原型对象等于超类的实例
Object.prototype.isPrototypeOf(instance)
SuperType.prototype.isPrototypeOf(instance)
SubType.prototype.isPrototypeOf(instance)
function SuperType() {this.colors = ['red','yellow','blue']
}
function SubType() {
}
SubType.prototype = new SuperType()
var instance1 = new SubType()
instance1.colors.push('green')
var instance2 =  new SubType()
instance2.colors // ['red','yellow','blue', 'green']

2个问题(引用类型、不能向超类型的构造函数传递参数)

1.2.2 借用构造函数: 在SubType内部SuperType.call(this, 'Lee') (能解决原型链的2个问题)

2个问题

  1. 构造函数模式的通病

每个方法都要在每个实例上重新创建一遍!不同实例上的同名函数是不相等的,然而,创建2个完成同样任务的Function实例的确没有必要。

  1. 超类型的原型中定义的方法,对子类型而言是不可见的
1.2.3 组合继承

借用构造函数方式,解决传参和引用 + 原型链方式,使用原型链上的方法

无论什么情况下,都会调用两次超类型构造函数:一次是在创建子类型原型的时候,另一次在子类型构造函数内部。 子类型最终会包含超类型对象的全部实例属性,但我们不得不在调用子类型构造函数时重写这些属性。

function SuperType(name) {this.name = namethis.colors = ['red','yellow','blue']
}
SuperType.prototype.sayName = function() {alert(this.name)
}
function SubType(name, age) {SuperType.call(this, name) // 第二次调用超类型构造函数,在新对象上创建了实例属性name、colors,将屏蔽原型中的两个同名属性this.age = age
}
SubType.prototype = new SuperType() //第一次调用超类型构造函数,SubType.prototype 获得两个属性:name、colors
var instance1 = new SubType('Lee', 26)
instance1.colors.push('green')
var instance2 =  new SubType()
instance2.colors // ['red','yellow','blue']
1.2.4 原型式继承-和原型链对应

在没有必要兴师动众地创建构造函数,而只是想让一个对象与另一个对象保持类似的情况下,原型式继承时完全可以胜任的
相同问题:引用类型值的属性会共享
从本质上讲,object()对传入其中的对象执行了一次浅拷贝

function object(o) {function F() {}F.prototype = oreturn new F()
}

Object.create()

两个参数:

  1. 用来作为新对象原型的对象
  2. 对新对象定义额外属性的对象,与Object.defineProperties()方法的第二个参数格式相同,每个属性都是通过自己的描述符定义的。
var person = {name: 'Lee',friends: ['a', 'b']
}
var p1 = Object.create(person)
p1.name = 'Yoona'
p1.friends = ['c']
var p2 = Object.create(person)
p2.name = 'Jessica'
p2.friends.push('d')
console.log(person.friends) // a, b, c, d 
1.2.5 寄生式继承-和构造函数对应

只能解决方法复用,没有解决引用

function createPerson(original) {// var clone = object(original)var clone = Object.create(original)clone.sayHi = function() {alert('Hi')}return clone
}
var p = {name: 'Lee',friends: ['a', 'b']
}
var p1 = createPerson(p)
p1.sayHi()
p1.friends.push('cs')
console.dir(p.friends)// a b cs
1.2.6 寄生组合式继承-解决组合继承问题

通过借用构造函数:继承属性
通过原型链的混合形成:继承方法
目的:不必为了指定子类型的原型而调用超类型的构造函数,可以使用寄生式继承来继承超类型的原型。
在这里插入图片描述

  1. call 借用构造函数继承属性和方法
  2. Object.create来指定原型
  3. 添加constructor从而弥补重写原型而失去的默认的属性
1.2.7 ES6 Class的继承 extends关键字

子类必须在constructor方法中调用super方法

class Point {constructor(x, y) {this.x = x;this.y = y;}
}class ColorPoint extends Point {constructor(x, y, color) {super(x, y);this.color = color;}
}
let cp = new ColorPoint(25, 8, 'green');cp instanceof ColorPoint // true
cp instanceof Point // true

父类的静态方法,也会被子类继承。

class A {static hello() {console.log('hello world');}
}class B extends A {
}B.hello()  // hello world

2. js作用域的类型

全局 局部 块级

3. 块级作用域和全局、局部作用域的区别

4. 闭包

描述用词一定要准确
闭包读取内部嵌套函数的变量
闭包的优点、缺点:
闭包:能够读取其他函数内部变量的函数。(应用场景:要获取某函数内部的局部变量)

闭包的优点:1.能够读取函数内部的变量 2.让这些变量一直存在于内存中,不会在调用结束后,被垃圾回收机制回收

闭包的缺点:正所谓物极必反,由于闭包会使函数中的变量保存在内存中,内存消耗很大,所以不能滥用闭包,解决办法是,退出函数之前,将不使用的局部变量删除。

5. vue的api – 读vue文档

vue-router是vue的生态
在这里插入图片描述

6. computed和watch的区别

一切关于vue的,参考文档最合理
计算属性和侦听器

6.1 计算属性

  1. 对于任何复杂逻辑,你都应当使用计算属性;
  2. 我们提供的函数将用作计算属性的 getter 函数;
  3. 计算属性缓存vs 方法(计算属性是基于它们的响应式依赖进行缓存的。只在相关响应式依赖发生改变时它们才会重新求值。这就意味着只要 message 还没有发生改变,多次访问 reversedMessage 计算属性会立即返回之前的计算结果,而不必再次执行函数)每当触发重新渲染时,调用方法将总会再次执行函数。【假设我们有一个性能开销比较大的计算属性 A,它需要遍历一个巨大的数组并做大量的计算。】;
  4. Date.now() 不是响应式依赖;
  5. 计算属性默认只有 getter,不过在需要时你也可以提供一个 setter

6.2 侦听属性

  1. 当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。question-answer,限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。
  2. 无缓存性,页面重新渲染时值不变化也会执行。

7. 对vue的对象进行深度监听

7.1 deep:true

watch:{obj:{ //监听的对象deep:true, //深度监听设置为 truehandler:function(newV,oldV){console.log('watch中:',newV)}}
}
data () {return {obj:{name:'夜空中最亮的星星',age:18}}},watch:{'obj.name':{deep:true,handler:function(newV,oldV){console.log('watch中:',newV)}}}

7.2 计算属性+侦听器

data () {return {obj:{name:'夜空中最亮的星星',age:18}}},computed:{name(){return this.obj.name;}},watch:{name(newV){console.log('watch中name为:',newV)}}

8. 节流和防抖

9. vue的生命周期

创建 挂载 更新 销毁
VUE-生命周期/请求数据

详解vue生命周期-一篇文章搞懂详细过程

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title>
</head>
<body><div id="app"><button @click="des">销毁</button><button @click="add">修改状态</button>{{ count }}</div>
</body>
<script src="vue.js"></script>
<script>new Vue({el: '#app',data: {count: 0},methods: {add () {this.count += 1},des () {this.$destroy() // 触发销毁}},beforeCreate () {console.log('创建实例之前', this.$el) // undefinedconsole.log('创建实例之前', this.$data) // undefinedconsole.log('创建实例之前', this.count) // undefined},created () {console.log('创建实例成功', this.$el) // undefinedconsole.log('创建实例成功', this.$data) // {count: 0}console.log('创建实例成功', this.count) // 0},beforeMount () {console.log('装载之前', this.$el) // <div id="app"></div>console.log('装载之前', this.$data) // {count: 0}console.log('装载之前', this.count) // 0},mounted () {console.log('装载之后', this.$el) // <div id="app"></div>console.log('装载之后', this.$data) // {count: 0}console.log('装载之后', this.count) // 0},beforeUpdate () {console.log('更新之前', this.$el) // <div id="app"></div>console.log('更新之前', this.$data) // {count: 0}console.log('更新之前', this.count) // 1},updated () {console.log('更新之后', this.$el) // <div id="app"></div>console.log('更新之后', this.$data) // {count: 0}console.log('更新之后', this.count) // 1},beforeDestroy () {console.log('销毁之前', this.$el) // <div id="app"></div>console.log('销毁之前', this.$data) // {count: 0}console.log('销毁之前', this.count) // 1},destroyed () {console.log('销毁之后', this.$el) // <div id="app"></div>console.log('销毁之后', this.$data) // {count: 0}console.log('销毁之后', this.count) // 1}})
</script>
</html>

10. 在beforeCreated和created之间能请求数据吗

无论在哪个生命周期都是能请求数据的,只是不一定能渲染
在生命周期的什么阶段进行请求:看需求

一般在 created 里面就可以,如果涉及到需要页面加载完成之后的操作话就用 mounted;

  • created 阶段的优势是:请求时间比较早,页面 loading 时间相对较短;
  • mounted 阶段的优势是:页面已经渲染完成,如果想请求之后进行 DOM 操作的话,必须在 mounted 阶段发起请求;

11. 什么是虚拟DOM

12. 什么是MVVM框架

13. 解释响应式原理

在源代码中是怎么实现的

14. 项目中的难点

代表性、成就感最高的——决定了做到什么程度

15. 大数据渲染

16. 循环数组的方式

forEach没有返回值,返回值undefined?斟酌

17. vue的双向数据绑定

Vue内部通过Object.defineProperty方法属性拦截的方式,把data对象里每个数据的读写转化成getter/setter,当数据变化时通知视图更新。
vue的双向绑定原理及实现
代码实现:细读!!!

  1. 【数据层】【视图层】的数据同步
  2. 数据劫持+发布者-订阅者模式

Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

17. 1 对象属性

ECMAScript中有两种属性: 数据属性和访问器属性, 数据属性一般用于存储数据数值, 访问器属性对应的是set/get操作, 不能直接存储数据值, 每种属性下面又都含有四个特性.下面介绍一下:

17.1.1 数据属性(数值)

1.[[Configurable]]: 表示能否通过delete将属性删除,能否把属性修改为访问器属性, 默认为false。当把属性Configurable设置为false后,该属性不能通过delete删除,并且也无法再将该属性的Configurable设置回true
2.[[Enumerable]]: 表示属性可否被枚举(即是否可以通过for in循环返回),默认false
3.[[Writable]]: 表示属性是否可写(即是否可以修改属性的值),默认false
4.[[Value]]: 该属性的数据值, 默认是undefined

17.1.1 访问器属性(set/get操作)

1.[[Configurable]]: 表示能否通过delete将属性删除,能否把属性修改为数据属性, 默认为false。当把属性Configurable设置为false后,该属性不能通过delete删除,并且也无法再将该属性的Configurable设置回true
2.[[Enumerable]]: 表示属性可否被枚举(即是否可以通过for in循环返回),默认false
3.[[Get]]: 读取属性时调用的函数, 默认为undefined
4.[[Set]]: 写入属性时调用的函数, 默认是undefined

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/251306.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

享元模式 - 结构型模式

模式类型&#xff1a; Flyweight 享元模式 - 结构型模式 意图&#xff1a; The intent of this pattern is to use sharing to support a large number of objects that have part of their internal state in common where the other part of state can vary. 运用共享…

前端试题(四)

1. vue过滤器使用场景 2. v-on绑定多个方法 <p v-on"{click:dbClick,mousemove:MouseClick}"></p>一个事件绑定多个函数&#xff1a; <p click"one(),two()">点击</p>3. 在菜单结构不确定时&#xff0c;前端如何动态渲染 树形…

Mysql - 安装与配置

1、下载安装包 > https://www.mysql.com/downloads/ 2、双击安装&#xff0c;点击Install MySQL Products > 3、Skip 打钩&#xff0c;Next下一步 > 4、选择Server only&#xff1a;只选择安装服务端&#xff0c;根据个人喜好更改安装路径和数据保存路径…

廖雪峰git教程学习

廖雪峰git教程 git – Linus在2周内用c写的 1.1 基本概念 版本控制系统&#xff0c;追踪文本文件的改动&#xff0c;文件、视频等二进制文件则不可追踪&#xff08;微软的word也是二进制文件&#xff09;HEAD 指向当前分支&#xff0c;表示当前版本&#xff08;最新的提交&am…

前端后台管理系统梳理

再梳理一遍 一、商品后台管理系统 1. 功能 1.1 服务端情况 开启了CORS跨域支持需要授权的 API &#xff0c;必须在请求头中使用 Authorization 字段提供token 令牌&#xff08;axios拦截器&#xff09;baseUrl&#xff0c;接口地址&#xff1a;http://localhost:8888/api/…

构造器执行顺序

转载于:https://www.cnblogs.com/a6948076/p/8045801.html

Java08-java语法基础(七)构造方法

Java08-java语法基础&#xff08;七&#xff09;构造方法 一、构造方法 1、什么是构造方法&#xff1f; 构造方法&#xff08;类方法&#xff09;是一个方法名和类名相容的特殊的成员方法。 2、构造方法的作用&#xff1f; 当使用new关键字创建一个对象时&#xff0c;为新建对象…

安装mysql8.0.20,报错“找不到VCRUNTIME140_1.dll”

写在最前&#xff0c;指令集合 以管理员身份运行cmd mysql -uroot -p 【进入】mysql mysql > exit 【退出】 net stop mysql 【暂停】 net start mysql 【启动】 mysql -u root -p&#xff08;命令后输入临时密码&#xff0c;进入mysql&#xff09; ALTER USER USER() …

使用mockjs模拟数据

一、安装 简单粗暴 npm install mockjs 二、引入 CommonJS引入 let Mock require(mockjs) let userInfo Mock.mock({data: {responseCode: 200,responseMessage: success,userMessage: {name: "cname",email: "email",msg: cparagraph(2)}} })或者ES…

lodash源码分析之compact中的遍历

小时候&#xff0c; 乡愁是一枚小小的邮票&#xff0c; 我在这头&#xff0c; 母亲在那头。 长大后&#xff0c;乡愁是一张窄窄的船票&#xff0c; 我在这头&#xff0c; 新娘在那头。 后来啊&#xff0c; 乡愁是一方矮矮的坟墓&#xff0c; 我在外头&#xff0c; 母亲在里头。…

[HAOI2008]移动玩具

这又是一道神奇的搜索题。。。只要记录每种状态。。。然后暴力判断这种状态往后一步的情况。。。 广搜出最优解即可。。。 呆码&#xff1a; #include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std;int dx[5]{0…

div设置overflow-scroll滚动之后,jq获取其子元素的offset.top出现问题。

先上个图&#xff1a; 布局很简单&#xff0c;左右超过屏幕的部分自行滚动。 1. html <div class"ce-container"><div class"ce-leftBox">//左边的内容</div><div class"ce-rightBox">//右边的内容 </div…

javascript --- 利用Sortable实现一个可视化公式编辑器

Sortable的依赖引入和简单使用参见:https://blog.csdn.net/piano9425/article/details/90437182 先简单的介绍一下可视化公式编辑器的功能(样式没有调,毕竟每个人的需求都不一样): 首先会有2个需要计算的(我称为操作数)A_XiangRaoZuWenSheng和AYKZQ_CS,以及两个操作符ADD(加法…

使用uni-app搭建微信小程序

0 问题待解决 import { } 与否为什么要封装对齐问题每次重启项目&#xff0c;sitemap就会消失动态修改标题失效图片问题多多 &#xff1a;高度自适应 改成image固定高度&#xff0c;mode&#xff1a;aspectFill微信小程序文档b站视频链接后端接口文档 一、知识点 uni-app 是…

HttpTomcat

本节内容&#xff1a; Http协议Tomcat服务器下面开始的一系列内容都是JavaEE的内容&#xff0c;主要的内容见下图。JavaEE主要是做服务器端开发。 JavaEE全部规范&#xff1a;有13门技术&#xff0c;主要做web开发的需要学习servlet和jsp。其他技术&#xff0c;像EJB、 JNDI、J…

python---线程与进程

一 线程 1.1 概述 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流&#xff0c;一个进程中可以并发多个线程&#xff0c;每条线程并行执行不同的任务。 Threading用于提供线程相关…

javascrpt --- 使用jquery添加dom元素和Angular ng-repeat生成select性能比较

今天用两种方法实现了动态的给select添加option的功能. 第一种是用jquery. // html <select id"drag-pointList"></select> // js $(#drag-pointList).children(option).remove(); // 清空之前的option let list res.data.list ; // res是ajax请…

【C语言及程序设计】项目2-15:模块化的简单银行系统设计

问题描述&#xff1a; https://edu.csdn.net/course/play/456/4808 // 银行系统.cpp: 定义控制台应用程序的入口点。 //#include "stdafx.h" #include <stdlib.h> #pragma warning (disable: 4996)int PassTest(); void ibalance(); void withdraw(); void de…

Android 6.0 动态权限申请

1. 概述 Android 6.0 (API 23) 之前应用的权限在安装时全部授予&#xff0c;运行时应用不再需要询问用户。在 Android 6.0 或更高版本对权限进行了分类&#xff0c;对某些涉及到用户隐私的权限可在运行时根据用户的需要动态授予。这样就不需要在安装时被强迫同意某些权限。 2. …

el-input输入金额,保留两位小数

需求&#xff1a;“只允许输入金额保留两位小数”&#xff0c;有2种实现方法 方法一&#xff08;通过正则控制&#xff09;&#xff1a; html&#xff1a; <el-inputv-model"inputTable.amount"input"formatNum(form.amount, amount)" ></el-i…