前端技术面——(js基础一)

1、Vue双向数据绑定是如何实现的?原文

  • vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调
  1. Vue.js 最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统。
  2. 访问器属性是对象中的一种特殊属性,它不能直接在对象中设置,而必须通过 defineProperty() 方法单独定义。
  3. 访问器属性的"值"比较特殊,读取或设置访问器属性的值,实际上是调用其内部特性:get和set函数。
  4. get 和 set 方法内部的 this 都指向 obj,这意味着 get 和 set
    函数可以操作对象内部的值。另外,访问器属性的会"覆盖"同名的普通属性,因为访问器属性会被优先访问,与其同名的普通属性则会被忽略。

Angularjs和Vue.js对比

2、极简双向数据绑定是如何实现的?

3、原型和原型链是什么?原文

1、构造函数创建对象 我们先使用构造函数创建一个对象:

2、 prototype 每个函数都有一个prototype属性,函数的prototype属性指向了一个对象,这个对象正是调用该构造函数而创建的实例的原型,也就是这个例子中的person1和person2的原型。每一个JavaScript对象(null除外)在创建的时候就会与之关联另一个对象,这个对象就是我们所说的原型,每一个对象都会从原型”继承”属性。

3、proto 这是每一个JavaScript对象(除了null)都具有的一个属性,叫__proto__,这个属性会指向该对象的原型。

4、construcotr,每个原型都有一个constructor属性指向关联的构造函数

5、实例与原型 当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

6、原型链 那Object.prototype的原型呢? null,嗯,就是null,所以查到Object.prototype就可以停止查找了

4、总结ES6常用的新特性。 原文

在这里列举几个常用的:

  • 箭头函数
  • Promise
  • Let与Const
  • 模块化
  • 函数参数默认值
  • 模板字符串
  • 解构赋值
  • 延展操作符
  • 对象属性简写

5、箭头函数。 原文

箭头函数被调用的时候,不会自动绑定一个this对象。换句话说,箭头函数根本就没有自己的this。它的this都是捕获自其所在上下文的this值。
  • 作为匿名函数被调用。

  • 作为方法被调用

  • 在方法内部被调用

  • 使用new 操作符调用,会抛出错误
  • 使用call和apply,bind()调用

总结一下
箭头函数没有自己的this对象,它总是搬运外部环境的this对象。因此,只要离它最近的外部环境中的this改变,箭头函数中的this就改变。如果离它最近的环境中的this,没有改变。那么箭头函数中的this就不会改变。

原文

6.promise是什么? 原文

什么是Prmoise

Promise对象可以理解为一次执行的异步操作,使用promise对象之后可以使用一种链式调用的方式来组织代码

Promise对象的特点:

1、对象的状态不受外界影响。
Promise对象代表一个异步操作,有三种状态:
pending(执行中)
Resolved(成功,又称Fulfilled)
rejected(拒绝)
2、一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise对象的状态改变,只有两种可能:从Pending变为Resolved和从Pending变为Rejected

Promise对象的缺点:

1、无法取消Promise,一旦新建它就会立即执行,无法中途取消。
2、如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
3、当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

promise兼容性

除了IE这种古老的浏览器和一些低版本的安卓外,现代浏览器支持还是挺好的

Promise的使用

1、基本用法:
(1)、首先我们new一个Promise,将Promise实例化
(2)、然后在实例化的promise可以传两个参数,一个是成功之后的resolve,一个是失败之后的reject
(3)、Promise实例生成以后,可以用then方法分别指定Resolved状态和Reject状态的回调函数

2、链式操作
也许你会说,Promise只是简化层层回调的写法而已吧,其实不然,它的精髓是通过维护状态、传递状态的方式来使回调方式能够及时的调用,因此,相比于callback,它更灵活,更简单。

promise.all方法

Promise.all 可以接收一个元素为 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为 resolve 时,该方法才会返回。
all接收一个数组作为参数,p1,p2是并行执行的,等两个都执行完了,才会进入到then,all会把所有的结果放到一个数组中返回,所以我们打印出我们的结果为一个数组。

promise.race方法

race只返回跑的快的值,也就是说result返回比较快执行的那个。

7、JS中事件冒泡与捕获。 原文

1、document 往 target节点,捕获前进,遇到注册的捕获事件立即触发执行
2、到达target节点,触发事件(对于target节点上,是先捕获还是先冒泡则捕获事件和冒泡事件的注册顺序,先注册先执行)
3、target节点 往 document 方向,冒泡前进,遇到注册的冒泡事件立即触发
总结下就是:
对于非target节点则先执行捕获在执行冒泡
对于target节点则是先执行先注册的事件,无论冒泡还是捕获

8、http和https

(1)http和https的基本概念

http: 超文本传输协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议。
https: 是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层。
https协议的主要作用是:建立一个信息安全通道,来确保数组的传输,确保网站的真实性。

(2)http和https的区别?

https协议是由http和ssl协议构建的可进行加密传输和身份认证的网络协议,比http协议的安全性更高。

1.Https协议需要ca证书,费用较高。
2.http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
3.使用不同的链接方式,端口也不同,一般而言,http协议的端口为80,https的端口为443
4.http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

(3)https协议的工作原理

客户端在使用HTTPS方式与Web服务器通信时有以下几个步骤。

1.客户使用https url访问服务器,则要求web 服务器建立ssl链接。
2.web服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥),返回或者说传输给客户端。
3.客户端和web服务器端开始协商SSL链接的安全等级,也就是加密等级。
4.客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。
5.web服务器通过自己的私钥解密出会话密钥。
6.web服务器通过会话密钥加密与客户端之间的通信。

9.tcp三次握手,一句话概括

三次握手可以简化为:C发起请求连接S确认,也发起连接C确认我们再看看每次握手的作用:

第一次握手:S只可以确认 自己可以接受C发送的报文段
第二次握手:C可以确认 S收到了自己发送的报文段,并且可以确认 自己可以接受S发送的报文段
第三次握手:S可以确认 C收到了自己发送的报文段

10.TCP和UDP的区别

  1. TCP是面向连接的,udp是无连接的即发送数据前不需要先建立链接。
  2. TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付。 并且因为tcp可靠,面向连接,不会丢失数据因此适合大数据量的交换。
  3. TCP是面向字节流,UDP面向报文,并且网络出现拥塞不会使得发送速率降低(因此会出现丢包,对实时的应用比如IP电话和视频会议等)。
  4. TCP只能是1对1的,UDP支持1对1,1对多。
  5. TCP的首部较大为20字节,而UDP只有8字节。
  6. TCP是面向连接的可靠性传输,而UDP是不可靠的。

11.Cookie、sessionStorage、localStorage的区别

共同点:都是保存在浏览器端,并且是同源的

Cookie:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递。而sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下,存储的大小很小只有4K左右。 (key:可以在浏览器和服务器端来回传递,存储容量小,只有大约4K左右)

sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持,localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。(key:本身就是一个回话过程,关闭浏览器后消失,session为一个回话,当页面不同即使是同一页面打开两次,也被视为同一次回话)

localStorage:localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。(key:同源窗口都会共享,并且不会失效,不管窗口或者浏览器关闭与否都会始终生效)

12.自己实现一个bind函数

原理:通过apply或者call方法来实现。

13、preventDefault 和 stopPropagation

event.stopPropagation() 方法阻止事件冒泡到父元素,阻止任何父事件处理程序被执行。 preventDefault阻止元素发生的默认行为。

例如: 当点击提交按钮时阻止对表单的提交
阻止一下URL的链接

## 14、写一个通用事件侦听函数

15、为什么要用闭包

闭包就是能够读取其他函数内部变量的函数
闭包的作用在于,可以通过闭包,设计私有变量及方法。

闭包的三大特点为:

1、函数嵌套函数
2、内部函数可以访问外部函数的变量
3、参数和变量不会被回收。

16、call和apply和bind有什么不一样?

相同点

都是实现继承或者转换对象指针的作用
1、call和apply可以改变this的指向
2、第一个参数都是this要指向的对象
3、都可以利用后续参数继续传参

不同点

1、call和apply是对函数的直接调用,而bind方法返回的是一个函数,bind后函数不会立即执行,而是返回了一个改变上下文的函数副本
2、call和apply都可以传递参数

什么是bind

bind()会创建一个新函数,当这个新函数被调用时,bind()的第一个参数将作为运行时的this,之后的一序列参数将会在传递的实参前作为传递的参数

17、前端性能优化你了解哪些

内容层面

  • 使用CDN
  • 单域名、多域名,单域名可以减少DNS查找次数,多域名可以增加浏览器并行下载数量,这需要权衡,一般同一个域下不要超过四个资源。
  • 避免重定向(分场景)
  • 避免404

网络层面

  • 利用缓存,可以参考另一篇文章手写文件服务器,说说前后端交互
  • 文件压缩(通过响应头Accept-Encoding: gzip, deflate, br告诉服务器你支持的压缩类型)
  • 按需加载,提取公共代码,tree-shaking等(都可以通过webpack来实现)
  • 减少cookie大小
  • 文件合并,通过css雪碧图合并图片
  • 文件预加载、图片懒加载

渲染层间

  • js放底部,css放顶部
  • 减少reflow(回流)和repaint(重绘)
  • 减少dom节点

代码层面

  • 缓存dom节点,减少节点查找,css选择器层级优化
  • 减少dom节点操作
  • 合理使用break、continue、return等,优化循环
  • 像react用到的事件委托、对象池等手段

18、说说浏览器的reflow和repaint

浏览器解析过程

解析html生成dom树
解析css
把css应用于dom树,生成render树(这里记录这每一个节点和它的样式和所在的位置)
把render树渲染到页面

reflow(回流)

reflow翻译为回流,指的是页面再次构建render树。每个页面至少发生一次回流,就是第一次加载页面的时候 此外,当页面中有任何改变可能造成文档结构发生改变(即元素间的相对或绝对位置改变),都会发生reflow,常见的有:

添加或删除元素(opacity:0除外,它不是删除)
改变某个元素的尺寸或位置
浏览器窗口改变(resize事件触发)

repaint(重绘)

repaint翻译为重绘,它可以类比为上面的第四步,根据render树绘制页面,它的性能损耗比回流要小。每次回流一定会发生重绘。此外,以下操作(不影响文档结构的操作,影响结构的会发生回流)也会发生重绘:

元素的颜色、透明度改变
text-align等

19、深拷贝

function deepcopy(obj) {
        let res = {};
        for (key in obj) {
            if (typeof obj[key] == 'object') {
                res[key] = deepcopy(obj[key]);
            } else {
                res[key] = obj[key];
            }
        }
        return res;
    }
复制代码

20、defer和async的区别 原文

定义

defer:此布尔属性被设置为向浏览器指示脚本在文档被解析后执行。
async:设置此布尔属性,以指示浏览器如果可能的话,应异步执行脚本。
1. 对于defer,我们可以认为是将外链的js放在了页面底部。js的加载不会阻塞页面的渲染和资源的加载。不过defer会按照原本的js的顺序执行,所以如果前后有依赖关系的js可以放心使用。
2. 对于async,这个是html5中新增的属性,它的作用是能够异步的加载和执行脚本,不因为加载脚本而阻塞页面的加载。一旦加载到就会立刻执行在有async的情况下,js一旦下载好了就会执行,所以很有可能不是按照原本的顺序来执行的。如果js前后有依赖性,用async,就很有可能出错。

区别

相同点:

1. 加载文件时不阻塞页面渲染
2. 对于inline的script(内联脚本)无效
3. 使用这两个属性的脚本中不能调用document.write方法
4. 有脚本的onload的事件回调

不同点:

1. html的版本html4.0中定义了defer;html5.0中定义了async
2. 浏览器兼容性
3. 执行时刻每一个async属性的脚本都在它下载结束之后立刻执行,同时会在window的load事件之前执行。所以就有可能出现脚本执行顺序被打乱的情况;每一个defer属性的脚本都是在页面解析完毕之后,按照原本的顺序执行,同时会在document的DOMContentLoaded之前执行。

结语

1. 如果async为true,那么脚本在下载完成后异步执行。
2. 如果async为false,defer为true,那么脚本会在页面解析完毕之后执行。
3. 如果async和defer都为false,那么脚本会在页面解析中,停止页面解析,立刻下载并且执行。

最后给一点个人的建议,无论使用defer还是async属性,都需要首先将页面中的js文件进行整理,哪些文件之间有依赖性,哪些文件可以延迟加载等等,做好js代码的合并和拆分,然后再根据页面需要使用这两个属性。

21、详解toString

toString() 方法返回一个表示该对象的字符串。 valueOf() 方法返回指定对象的原始值。

22、如何去除字符串首位空格?

//es6
' ab '.trim()      //"ab" 
//正则
' ab '.replace(/^\s*|\s*$/g,'')  //"ab"
复制代码

23、jsonp原理?缺点?

工作原理:使用script标签实现跨域访问,可在url中指定回调函数,获取JSON数据并在指定的回调函数中执行jquery实现jsop。
缺点:只支持GET方式的jsonp实现,是一种脚本注入行为存在一定的安全隐患。如果返回的数据格式有问题或者返回失败了,并不会报错。

24、设计模式

1、工厂模式
 function People() {
    var obj = new Object();
    obj.name = '小明';
    obj.age = 12;
    obj.say = function() {
        // alert(this.name);
        return this.name;
    }
    return obj;
}

2、构造函数模式
function People() {
    this.name = '小明';
    this.say = function() {
        return this.name;
    }
}

3、原型模式
function People(name) {
    this.name = name;
}
People.prototype.sayName = function() {
    console.log(this.name);
}
复制代码

25、继承

1、原型链继承
function People(name) {
    this.name = name;
}
People.prototype.sayName = function() {
    console.log(this.name);
}
function Student(name, grade) {
    this.name = name;
    this.grade = grade;
    this.sayGrade = function() {
        console.log(this.grade);
    }
}
Student.prototype = new People();


2、构造函数继承
function People() {
    this.name = name;
}
People.prototype.sayName = function() {
    console.log(this.name);
}
People.prototype.type = function() {
    console.log('人');
};
function Student(name, grade) {
    this.name = name;
    this.grade = grade;
    People.apply(this);
}
var student = new Student('小兰', 5);
student.type();
复制代码

26、HTTP的几种请求方法用途

1、GET方法

发送一个请求来取得服务器上的某一资源

2、POST方法

向URL指定的资源提交数据或附加新的数据

3、PUT方法

跟POST方法很像,也是想服务器提交数据。但是,它们之间有不同。PUT指定了资源在服务器上的位置,而POST没有

4、HEAD方法

只请求页面的首部

5、DELETE方法

删除服务器上的某资源

6、OPTIONS方法

它用于获取当前URL所支持的方法。如果请求成功,会有一个Allow的头包含类似“GET,POST”这样的信息
浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。

7、TRACE方法

TRACE方法被用于激发一个远程的,应用层的请求消息回路

8、CONNECT方法

把请求连接转换到透明的TCP/IP通道

27、从浏览器地址栏输入url到显示页面的步骤

  • 浏览器根据请求的URL交给DNS域名解析,找到真实IP,向服务器发起请求;链接
  • 服务器交给后台处理完成后返回数据,浏览器接收文件(HTML、JS、CSS、图象等);
  • 浏览器对加载到的资源(HTML、JS、CSS等)进行语法解析,建立相应的内部数据结构(如HTML的DOM);
  • 载入解析到的资源文件,渲染页面,完成。

28、如何进行网站性能优化

1. content方面

  • 减少HTTP请求:合并文件、CSS精灵、inline Image

  • 减少DNS查询:DNS缓存、将资源分布到恰当数量的主机名

  • 减少DOM元素数量

2. Server方面

  • 使用CDN

  • 配置ETag

  • 对组件使用Gzip压缩

3. Cookie方面

  • 减小cookie大小

4. css方面

  • 将样式表放到页面顶部
  • 不使用CSS表达式
  • 使用不使用@import

5. Javascript方面

  • 将脚本放到页面底部

  • 将javascript和css从外部引入

  • 压缩javascript和css

  • 删除不需要的脚本

  • 减少DOM访问

6. 图片方面

  • 优化图片:根据实际颜色需要选择色深、压缩
  • 优化css精灵
  • 不要在HTML中拉伸图片

29、HTTP状态码及其含义

1XX:信息状态码

100 Continue 继续,一般在发送post请求时,已发送了http header之后服务端将返回此信息,表示确认,之后发送具体参数信息

2XX:成功状态码

200 OK 正常返回信息

201 Created 请求成功并且服务器创建了新的资源

202 Accepted 服务器已接受请求,但尚未处理

3XX:重定向

301 Moved Permanently 请求的网页已永久移动到新位置。

302 Found 临时性重定向。

303 See Other 临时性重定向,且总是使用 GET 请求新的 URI。

304 Not Modified 自从上次请求后,请求的网页未修改过。

4XX:客户端错误

400 Bad Request 服务器无法理解请求的格式,客户端不应当尝试再次使用相同的内容发起请求。

401 Unauthorized 请求未授权。

403 Forbidden 禁止访问。

404 Not Found 找不到如何与 URI 相匹配的资源。

5XX: 服务器错误

500 Internal Server Error 最常见的服务器端错误。

503 Service Unavailable 服务器端暂时无法处理请求(可能是过载或维护)。

31、介绍js有哪些内置对象?

  • Object 是 JavaScript 中所有对象的父对象

  • 数据封装类对象:Object、Array、Boolean、Number 和 String

  • 其他对象:Function、Arguments、Math、Date、RegExp、Error

32、JavaScript的基本数据类型和引用数据类型?你能画一下他们的内存图吗?

  • 栈:原始数据类型(Undefined,Null,Boolean,Number,String)
  • 堆:引用数据类型(Object,Array,Function,Data)
  • 两种类型的区别是:存储位置不同;
  • 原始数据类型直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;
  • 引用数据类型存储在堆(heap)中的对象,占据空间大、大小不固定,如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。不同是,你不可以直接访问堆内存空间中的位置和操作堆内存空间。只能操作对象在栈内存中的引用地址。 链接
总结区别
  • 声明变量时不同的内存分配: 
  • 不同的内存分配机制也带来了不同的访问机制
  • 复制变量时的不同
  • 参数传递的不同(把实参复制给形参的过程)

33、["1", "2", "3"].map(parseInt) 答案是多少?

  • [1, NaN, NaN]因为 parseInt 需要两个参数 (val, radix),其中radix 表示解析时用的基数。

  • map传了 3个(element, index, array),对应的 radix 不合法导致解析失败。

34、同步和异步的区别?

  • 同步:浏览器访问服务器请求,用户看得到页面刷新,重新发请求,等请求完,页面刷新,新内容出现,用户看到新内容,进行下一步操作
  • 异步:浏览器访问服务器请求,用户正常操作,浏览器后端进行请求。等请求完,页面不刷新,新内容也会出现,用户看到新内容

35、谈一谈let与var的区别?

  • let命令不存在变量提升,如果在let前使用,会导致报错
  • 如果块区中存在let和const命令,就会形成封闭作用域
  • 不允许重复声明,因此,不能在函数内部重新声明参数

36、浏览器兼容问题

  • 微信H5

1.设置 overflow scroll 在IOS中滑动不流畅的问题 -webkit-overflow-scrolling: touch
2. 用bootstrap 模态框弹在IOS中弹不出的问题
cursor: pointer;

  • 微信小程序
  1. 上下两张图片之间的空隙,设置img为:display:block;
  2. 小程序button的边框去不掉的时候,:after{border:none;}

37、判断一个数组

  • arr instancof Array
  • Array.isArray(arr)
  • Object.prototype.toString.call(arr)=='[Object Array]'

38、如何保证一个变量里面的属性不被修改

const object1 = { property1: 42 };

const object2 = Object.freeze(object1);

object2.property1 = 33;

39、splice和slice和substring和substr

分类改变原数据名称第一个参数第二个参数第三个参数
数组方法改变splicestart(可负值)lenadd
数组方法不改变slicestartend
字符串方法不改变substringstartend
字符串方法不改变substrstart(可负值)len

40、数组去重

  • [...new Set(arr)]
  • Array.from(new Set(arr))
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值