关于javascript:社招中级前端笔试面试题总结

6次阅读

共计 10950 个字符,预计需要花费 28 分钟才能阅读完成。

HTTP 世界全览

  • 互联网上绝大部分资源都应用 HTTP 协定传输;
  • 浏览器是 HTTP 协定里的申请方,即 User Agent
  • 服务器是 HTTP 协定里的应答方,罕用的有 ApacheNginx
  • CDN 位于浏览器和服务器之间,次要起到缓存减速的作用;
  • 爬虫是另一类 User Agent,是主动拜访网络资源的程序。
  • TCP/IP 是网络世界最罕用的协定,HTTP 通常运行在 TCP/IP 提供的牢靠传输根底上
  • DNS 域名是 IP 地址的等价代替,须要用域名解析实现到 IP 地址的映射;
  • URI 是用来标记互联网上资源的一个名字,由“协定名 + 主机名 + 门路”形成,俗称 URL;
  • HTTPS 相当于“HTTP+SSL/TLS+TCP/IP”,为 HTTP 套了一个平安的外壳;
  • 代理是 HTTP 传输过程中的“中转站”,能够实现缓存减速、负载平衡等性能

协商缓存和强缓存的区别

(1)强缓存

应用强缓存策略时,如果缓存资源无效,则间接应用缓存资源,不用再向服务器发动申请。

强缓存策略能够通过两种形式来设置,别离是 http 头信息中的 Expires 属性和 Cache-Control 属性。

(1)服务器通过在响应头中增加 Expires 属性,来指定资源的过期工夫。在过期工夫以内,该资源能够被缓存应用,不用再向服务器发送申请。这个工夫是一个相对工夫,它是服务器的工夫,因而可能存在这样的问题,就是客户端的工夫和服务器端的工夫不统一,或者用户能够对客户端工夫进行批改的状况,这样就可能会影响缓存命中的后果。

(2)Expires 是 http1.0 中的形式,因为它的一些毛病,在 HTTP 1.1 中提出了一个新的头部属性就是 Cache-Control 属性,它提供了对资源的缓存的更准确的管制。它有很多不同的值,

Cache-Control可设置的字段:

  • public:设置了该字段值的资源示意能够被任何对象(包含:发送申请的客户端、代理服务器等等)缓存。这个字段值不罕用,个别还是应用 max-age= 来准确管制;
  • private:设置了该字段值的资源只能被用户浏览器缓存,不容许任何代理服务器缓存。在理论开发当中,对于一些含有用户信息的 HTML,通常都要设置这个字段值,防止代理服务器 (CDN) 缓存;
  • no-cache:设置了该字段须要先和服务端确认返回的资源是否产生了变动,如果资源未发生变化,则间接应用缓存好的资源;
  • no-store:设置了该字段示意禁止任何缓存,每次都会向服务端发动新的申请,拉取最新的资源;
  • max-age=:设置缓存的最大有效期,单位为秒;
  • s-maxage=:优先级高于 max-age=,仅实用于共享缓存(CDN),优先级高于 max-age 或者 Expires 头;
  • max-stale[=]:设置了该字段表明客户端违心接管曾经过期的资源,然而不能超过给定的工夫限度。

一般来说只须要设置其中一种形式就能够实现强缓存策略,当两种形式一起应用时,Cache-Control 的优先级要高于 Expires。

no-cache 和 no-store 很容易混同:

  • no-cache 是指先要和服务器确认是否有资源更新,在进行判断。也就是说没有强缓存,然而会有协商缓存;
  • no-store 是指不应用任何缓存,每次申请都间接从服务器获取资源。

(2)协商缓存

如果命中强制缓存,咱们无需发动新的申请,间接应用缓存内容,如果没有命中强制缓存,如果设置了协商缓存,这个时候协商缓存就会发挥作用了。

下面曾经说到了,命中协商缓存的条件有两个:

  • max-age=xxx 过期了
  • 值为no-store

应用协商缓存策略时,会先向服务器发送一个申请,如果资源没有产生批改,则返回一个 304 状态,让浏览器应用本地的缓存正本。如果资源产生了批改,则返回批改后的资源。

协商缓存也能够通过两种形式来设置,别离是 http 头信息中的 EtagLast-Modified 属性。

(1)服务器通过在响应头中增加 Last-Modified 属性来指出资源最初一次批改的工夫,当浏览器下一次发动申请时,会在申请头中增加一个 If-Modified-Since 的属性,属性值为上一次资源返回时的 Last-Modified 的值。当申请发送到服务器后服务器会通过这个属性来和资源的最初一次的批改工夫来进行比拟,以此来判断资源是否做了批改。如果资源没有批改,那么返回 304 状态,让客户端应用本地的缓存。如果资源曾经被批改了,则返回批改后的资源。应用这种办法有一个毛病,就是 Last-Modified 标注的最初批改工夫只能准确到秒级,如果某些文件在 1 秒钟以内,被批改屡次的话,那么文件已将扭转了然而 Last-Modified 却没有扭转,这样会造成缓存命中的不精确。

(2)因为 Last-Modified 的这种可能产生的不准确性,http 中提供了另外一种形式,那就是 Etag 属性。服务器在返回资源的时候,在头信息中增加了 Etag 属性,这个属性是资源生成的惟一标识符,当资源产生扭转的时候,这个值也会产生扭转。在下一次资源申请时,浏览器会在申请头中增加一个 If-None-Match 属性,这个属性的值就是上次返回的资源的 Etag 的值。服务接管到申请后会依据这个值来和资源以后的 Etag 的值来进行比拟,以此来判断资源是否产生扭转,是否须要返回资源。通过这种形式,比 Last-Modified 的形式更加准确。

当 Last-Modified 和 Etag 属性同时呈现的时候,Etag 的优先级更高。应用协商缓存的时候,服务器须要思考负载平衡的问题,因而多个服务器上资源的 Last-Modified 应该保持一致,因为每个服务器上 Etag 的值都不一样,因而在思考负载平衡时,最好不要设置 Etag 属性。

总结:

强缓存策略和协商缓存策略在缓存命中时都会间接应用本地的缓存正本,区别只在于协商缓存会向服务器发送一次申请。它们缓存不命中时,都会向服务器发送申请来获取资源。在理论的缓存机制中,强缓存策略和协商缓存策略是一起单干应用的。浏览器首先会依据申请的信息判断,强缓存是否命中,如果命中则间接应用资源。如果不命中则依据头信息向服务器发动申请,应用协商缓存,如果协商缓存命中的话,则服务器不返回资源,浏览器间接应用本地资源的正本,如果协商缓存不命中,则浏览器返回最新的资源给浏览器。

JS 整数是怎么示意的?

  • 通过 Number 类型来示意,遵循 IEEE754 规范,通过 64 位来示意一个数字,(1 + 11 + 52),最大平安数字是 Math.pow(2, 53) – 1,对于 16 位十进制。(符号位 + 指数位 + 小数局部无效位)

浏览器的垃圾回收机制

(1)垃圾回收的概念

垃圾回收:JavaScript 代码运行时,须要分配内存空间来贮存变量和值。当变量不在参加运行时,就须要零碎发出被占用的内存空间,这就是垃圾回收。

回收机制

  • Javascript 具备主动垃圾回收机制,会定期对那些不再应用的变量、对象所占用的内存进行开释,原理就是找到不再应用的变量,而后开释掉其占用的内存。
  • JavaScript 中存在两种变量:局部变量和全局变量。全局变量的生命周期会继续要页面卸载;而局部变量申明在函数中,它的生命周期从函数执行开始,直到函数执行完结,在这个过程中,局部变量会在堆或栈中存储它们的值,当函数执行完结后,这些局部变量不再被应用,它们所占有的空间就会被开释。
  • 不过,当局部变量被内部函数应用时,其中一种状况就是闭包,在函数执行完结后,函数内部的变量仍然指向函数外部的局部变量,此时局部变量仍然在被应用,所以不会回收。

(2)垃圾回收的形式

浏览器通常应用的垃圾回收办法有两种:标记革除,援用计数。1)标记革除

  • 标记革除是浏览器常见的垃圾回收形式,当变量进入执行环境时,就标记这个变量“进入环境”,被标记为“进入环境”的变量是不能被回收的,因为他们正在被应用。当变量来到环境时,就会被标记为“来到环境”,被标记为“来到环境”的变量会被内存开释。
  • 垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记。而后,它会去掉环境中的变量以及被环境中的变量援用的标记。而在此之后再被加上标记的变量将被视为筹备删除的变量,起因是环境中的变量曾经无法访问到这些变量了。最初。垃圾收集器实现内存革除工作,销毁那些带标记的值,并回收他们所占用的内存空间。

2)援用计数

  • 另外一种垃圾回收机制就是援用计数,这个用的绝对较少。援用计数就是跟踪记录每个值被援用的次数。当申明了一个变量并将一个援用类型赋值给该变量时,则这个值的援用次数就是 1。相同,如果蕴含对这个值援用的变量又获得了另外一个值,则这个值的援用次数就减 1。当这个援用次数变为 0 时,阐明这个变量曾经没有价值,因而,在在机回收期下次再运行时,这个变量所占有的内存空间就会被释放出来。
  • 这种办法会引起 循环援用 的问题:例如:obj1obj2 通过属性进行互相援用,两个对象的援用次数都是 2。当应用循环计数时,因为函数执行完后,两个对象都来到作用域,函数执行完结,obj1obj2 还将会持续存在,因而它们的援用次数永远不会是 0,就会引起循环援用。
function fun() {let obj1 = {};
    let obj2 = {};
    obj1.a = obj2; // obj1 援用 obj2
    obj2.a = obj1; // obj2 援用 obj1
}

这种状况下,就要手动开释变量占用的内存:

obj1.a =  null
 obj2.a =  null

(3)缩小垃圾回收

尽管浏览器能够进行垃圾主动回收,然而当代码比较复杂时,垃圾回收所带来的代价比拟大,所以应该尽量减少垃圾回收。

  • 对数组进行优化: 在清空一个数组时,最简略的办法就是给其赋值为[],然而与此同时会创立一个新的空对象,能够将数组的长度设置为 0,以此来达到清空数组的目标。
  • object 进行优化: 对象尽量复用,对于不再应用的对象,就将其设置为 null,尽快被回收。
  • 对函数进行优化: 在循环中的函数表达式,如果能够复用,尽量放在函数的里面。

什么是同源策略

跨域问题其实就是浏览器的同源策略造成的。

同源策略限度了从同一个源加载的文档或脚本如何与另一个源的资源进行交互。这是浏览器的一个用于隔离潜在歹意文件的重要的平安机制。同源指的是:协定 端口号 域名 必须统一。

同源策略:protocol(协定)、domain(域名)、port(端口)三者必须统一。

同源政策次要限度了三个方面:

  • 以后域下的 js 脚本不可能拜访其余域下的 cookie、localStorage 和 indexDB。
  • 以后域下的 js 脚本不可能操作拜访操作其余域下的 DOM。
  • 以后域下 ajax 无奈发送跨域申请。

同源政策的目标次要是为了保障用户的信息安全,它只是对 js 脚本的一种限度,并不是对浏览器的限度,对于个别的 img、或者 script 脚本申请都不会有跨域的限度,这是因为这些操作都不会通过响应后果来进行可能呈现平安问题的操作。

请实现 DOM2JSON 一个函数,能够把一个 DOM 节点输入 JSON 的格局

题目形容:

<div>
  <span>
    <a></a>
  </span>
  <span>
    <a></a>
    <a></a>
  </span>
</div>

把上诉 dom 构造转成上面的 JSON 格局

{
  tag: 'DIV',
  children: [
    {
      tag: 'SPAN',
      children: [{ tag: 'A', children: [] }
      ]
    },
    {
      tag: 'SPAN',
      children: [{ tag: 'A', children: [] },
        {tag: 'A', children: [] }
      ]
    }
  ]
}

实现代码如下:

function dom2Json(domtree) {let obj = {};
  obj.name = domtree.tagName;
  obj.children = [];
  domtree.childNodes.forEach((child) => obj.children.push(dom2Json(child)));
  return obj;
}

扩大思考: 如果给定的不是一个 Dom 树结构 而是一段 html 字符串 该如何解析?

那么这个问题就相似 Vue 的模板编译原理 咱们能够利用正则 匹配 html 字符串 遇到开始标签 完结标签和文本 解析结束之后生成对应的 ast 并建设相应的父子关联 一直的 advance 截取残余的字符串 直到 html 全副解析结束

参考 前端进阶面试题具体解答

代码输入后果

var a = 10
var obj = {
  a: 20,
  say: () => {console.log(this.a)
  }
}
obj.say() 

var anotherObj = {a: 30} 
obj.say.apply(anotherObj) 

输入后果:10 10

我么晓得,箭头函数时不绑定 this 的,它的 this 来自原其父级所处的上下文,所以首先会打印全局中的 a 的值 10。前面尽管让 say 办法指向了另外一个对象,然而仍不能扭转箭头函数的个性,它的 this 依然是指向全局的,所以依旧会输入 10。

然而,如果是一般函数,那么就会有齐全不一样的后果:

var a = 10  
var obj = {  
  a: 20,  
  say(){console.log(this.a)  
  }  
}  
obj.say()   
var anotherObj={a:30}   
obj.say.apply(anotherObj)

输入后果:20 30

这时,say 办法中的 this 就会指向他所在的对象,输入其中的 a 的值。

实现一个宽高自适应的正方形

  • 利用 vw 来实现:
.square {
  width: 10%;
  height: 10vw;
  background: tomato;
}
  • 利用元素的 margin/padding 百分比是绝对父元素 width 的性质来实现:
.square {
  width: 20%;
  height: 0;
  padding-top: 20%;
  background: orange;
}
  • 利用子元素的 margin-top 的值来实现:
.square {
  width: 30%;
  overflow: hidden;
  background: yellow;
}
.square::after {
  content: '';
  display: block;
  margin-top: 100%;
}

label 的作用是什么?如何应用?

label 标签来定义表单控件的关系:当用户抉择 label 标签时,浏览器会主动将焦点转到和 label 标签相干的表单控件上。

  • 应用办法 1:
<label for="mobile">Number:</label>
<input type="text" id="mobile"/>
  • 应用办法 2:
<label>Date:<input type="text"/></label>

对盒模型的了解

CSS3 中的盒模型有以下两种:规范盒子模型、IE 盒子模型 盒模型都是由四个局部组成的,别离是 margin、border、padding 和 content。

规范盒模型和 IE 盒模型的区别在于设置 width 和 height 时,所对应的范畴不同:

  • 规范盒模型的 width 和 height 属性的范畴只蕴含了 content,
  • IE 盒模型的 width 和 height 属性的范畴蕴含了 border、padding 和 content。

能够通过批改元素的 box-sizing 属性来扭转元素的盒模型:

  • box-sizeing: content-box示意规范盒模型(默认值)
  • box-sizeing: border-box示意 IE 盒模型(怪异盒模型)

浏览器的渲染过程

浏览器渲染次要有以下步骤:

  • 首先解析收到的文档,依据文档定义构建一棵 DOM 树,DOM 树是由 DOM 元素及属性节点组成的。
  • 而后对 CSS 进行解析,生成 CSSOM 规定树。
  • 依据 DOM 树和 CSSOM 规定树构建渲染树。渲染树的节点被称为渲染对象,渲染对象是一个蕴含有色彩和大小等属性的矩形,渲染对象和 DOM 元素绝对应,但这种对应关系不是一对一的,不可见的 DOM 元素不会被插入渲染树。还有一些 DOM 元素对应几个可见对象,它们个别是一些具备简单构造的元素,无奈用一个矩形来形容。
  • 当渲染对象被创立并增加到树中,它们并没有地位和大小,所以当浏览器生成渲染树当前,就会依据渲染树来进行布局(也能够叫做回流)。这一阶段浏览器要做的事件是要弄清楚各个节点在页面中的确切地位和大小。通常这一行为也被称为“主动重排”。
  • 布局阶段完结后是绘制阶段,遍历渲染树并调用渲染对象的 paint 办法将它们的内容显示在屏幕上,绘制应用 UI 根底组件。

大抵过程如图所示:

留神: 这个过程是逐渐实现的,为了更好的用户体验,渲染引擎将会尽可能早的将内容出现到屏幕上,并不会等到所有的 html 都解析实现之后再去构建和布局 render 树。它是解析完一部分内容就显示一部分内容,同时,可能还在通过网络下载其余内容。

什么状况会阻塞渲染?

首先渲染的前提是生成渲染树,所以 HTML 和 CSS 必定会阻塞渲染。如果你想渲染的越快,你越应该升高一开始须要渲染的文件大小,并且扁平层级,优化选择器。而后当浏览器在解析到 script 标签时,会暂停构建 DOM,实现后才会从暂停的中央从新开始。也就是说,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都倡议将 script 标签放在 body 标签底部的起因。

当然在当下,并不是说 script 标签必须放在底部,因为你能够给 script 标签增加 defer 或者 async 属性。当 script 标签加上 defer 属性当前,示意该 JS 文件会并行下载,然而会放到 HTML 解析实现后程序执行,所以对于这种状况你能够把 script 标签放在任意地位。对于没有任何依赖的 JS 文件能够加上 async 属性,示意 JS 文件下载和解析不会阻塞渲染。

对媒体查问的了解?

媒体查问由⼀个可选的媒体类型和零个或多个使⽤媒体性能的限度了样式表范畴的表达式组成,例如宽度、⾼度和颜⾊。媒体查问,增加⾃ CSS3,容许内容的出现针对⼀个特定范畴的输出设备⽽进⾏裁剪,⽽不用扭转内容自身,适宜 web ⽹⻚应答不同型号的设施⽽做出对应的响应适配。

媒体查问蕴含⼀个可选的媒体类型和满⾜ CSS3 标准的条件下,蕴含零个或多个表达式,这些表达式形容了媒体特色,最终会被解析为 true 或 false。如果媒体查问中指定的媒体类型匹配展现⽂档所使⽤的设施类型,并且所有的表达式的值都是 true,那么该媒体查问的后果为 true。那么媒体查问内的款式将会⽣效。

<!-- link 元素中的 CSS 媒体查问 --> 
<link rel="stylesheet" media="(max-width: 800px)" href="example.css" /> 
<!-- 样式表中的 CSS 媒体查问 --> 
<style> 
@media (max-width: 600px) {.facet_sidebar {     display: none;} }
</style>

简略来说,应用 @media 查问,能够针对不同的媒体类型定义不同的款式。@media 能够针对不同的屏幕尺寸设置不同的款式,特地是须要设置设计响应式的页面,@media 是十分有用的。当重置浏览器大小的过程中,页面也会依据浏览器的宽度和高度从新渲染页面。

代码输入后果

var F = function() {};
Object.prototype.a = function() {console.log('a');
};
Function.prototype.b = function() {console.log('b');
}
var f = new F();
f.a();
f.b();
F.a();
F.b()

输入后果:

a
Uncaught TypeError: f.b is not a function
a
b

解析:

  1. f 并不是 Function 的实例,因为它原本就不是构造函数,调用的是 Function 原型链上的相干属性和办法,只能拜访到 Object 原型链。所以 f.a() 输入 a,而 f.b() 就报错了。
  2. F 是个构造函数,而 F 是构造函数 Function 的一个实例。因为 F instanceof Object === true,F instanceof Function === true,由此能够得出结论:F 是 Object 和 Function 两个的实例,即 F 能拜访到 a,也能拜访到 b。所以 F.a() 输入 a,F.b() 输入 b。

对 CSSSprites 的了解

CSSSprites(精灵图),将一个页面波及到的所有图片都蕴含到一张大图中去,而后利用 CSS 的 background-image,background-repeat,background-position 属性的组合进行背景定位。

长处:

  • 利用 CSS Sprites 能很好地缩小网页的 http 申请,从而大大提高了页面的性能,这是 CSS Sprites 最大的长处;
  • CSS Sprites能缩小图片的字节,把 3 张图片合并成 1 张图片的字节总是小于这 3 张图片的字节总和。

毛病:

  • 在图片合并时,要把多张图片有序的、正当的合并成一张图片,还要留好足够的空间,避免板块内呈现不必要的背景。在宽屏及高分辨率下的自适应页面,如果背景不够宽,很容易呈现背景断裂;
  • CSSSprites在开发的时候相对来说有点麻烦,须要借助 photoshop 或其余工具来对每个背景单元测量其精确的地位。
  • 保护方面:CSS Sprites在保护的时候比拟麻烦,页面背景有少许改变时,就要改这张合并的图片,无需改的中央尽量不要动,这样防止改变更多的CSS,如果在原来的中央放不下,又只能(最好)往下加图片,这样图片的字节就减少了,还要改变CSS

如何⽤ webpack 来优化前端性能?

⽤ webpack 优化前端性能是指优化 webpack 的输入后果,让打包的最终后果在浏览器运⾏疾速⾼效。

  • 压缩代码:删除多余的代码、正文、简化代码的写法等等⽅式。能够利⽤ webpack 的 UglifyJsPlugin 和 ParallelUglifyPlugin 来压缩 JS ⽂件,利⽤ cssnano(css-loader?minimize)来压缩 css
  • 利⽤ CDN 减速: 在构建过程中,将引⽤的动态资源门路批改为 CDN 上对应的门路。能够利⽤ webpack 对于 output 参数和各 loader 的 publicPath 参数来批改资源门路
  • Tree Shaking: 将代码中永远不会⾛到的⽚段删除掉。能够通过在启动 webpack 时追加参数 –optimize-minimize 来实现
  • Code Splitting: 将代码按路由维度或者组件分块(chunk), 这样做到按需加载, 同时能够充沛利⽤浏览器缓存
  • 提取公共第三⽅库: SplitChunksPlugin 插件来进⾏公共模块抽取, 利⽤浏览器缓存能够⻓期缓存这些⽆需频繁变动的公共代码

代码输入后果

// a
function Foo () {getName = function () {console.log(1);
 }
 return this;
}
// b
Foo.getName = function () {console.log(2);
}
// c
Foo.prototype.getName = function () {console.log(3);
}
// d
var getName = function () {console.log(4);
}
// e
function getName () {console.log(5);
}

Foo.getName();           // 2
getName();               // 4
Foo().getName();         // 1
getName();               // 1 
new Foo.getName();       // 2
new Foo().getName();     // 3
new new Foo().getName(); // 3

输入后果:2 4 1 1 2 3 3

解析:

  1. Foo.getName(), Foo 为一个函数对象,对象都能够有属性,b 处定义 Foo 的 getName 属性为函数,输入 2;
  2. getName(), 这里看 d、e 处,d 为函数表达式,e 为函数申明,两者区别在于变量晋升,函数申明的 5 会被后边函数表达式的 4 笼罩;
  3. Foo().getName(), 这里要看 a 处,在 Foo 外部将全局的 getName 从新赋值为 console.log(1) 的函数,执行 Foo()返回 this,这个 this 指向 window,Foo().getName() 即为 window.getName(),输入 1;
  4. getName(), 下面 3 中,全局的 getName 曾经被从新赋值,所以这里仍然输入 1;
  5. new Foo.getName(), 这里等价于 new (Foo.getName()),先执行 Foo.getName(),输入 2,而后 new 一个实例;
  6. new Foo().getName(), 这 里等价于 (new Foo()).getName(), 先 new 一个 Foo 的实例,再执行这个实例的 getName 办法,然而这个实例自身没有这个办法,所以去原型链__protot__上边找,实例.protot === Foo.prototype,所以输入 3;
  7. new new Foo().getName(), 这里等价于 new (new Foo().getName()),如上述 6,先输入 3,而后 new 一个 new Foo().getName() 的实例。

::before 和 :after 的双冒号和单冒号有什么区别?

(1)冒号 (:) 用于 CSS3 伪类,双冒号 (::) 用于 CSS3 伪元素。
(2)::before就是以一个子元素的存在,定义在元素主体内容之前的一个伪元素。并不存在于 dom 之中,只存在在页面之中。

留神: :before:after 这两个伪元素,是在 CSS2.1 里新呈现的。起初,伪元素的前缀应用的是单冒号语法,但随着 Web 的进化,在 CSS3 的标准里,伪元素的语法被批改成应用双冒号,成为::before::after

代码输入后果

var myObject = {
    foo: "bar",
    func: function() {
        var self = this;
        console.log(this.foo);  
        console.log(self.foo);  
        (function() {console.log(this.foo);  
            console.log(self.foo);  
        }());
    }
};
myObject.func();

输入后果:bar bar undefined bar

解析:

  1. 首先 func 是由 myObject 调用的,this 指向 myObject。又因为 var self = this; 所以 self 指向 myObject。
  2. 这个立刻执行匿名函数表达式是由 window 调用的,this 指向 window。立刻执行匿名函数的作用域处于 myObject.func 的作用域中,在这个作用域找不到 self 变量,沿着作用域链向上查找 self 变量,找到了指向 myObject 对象的 self。

浏览器乱码的起因是什么?如何解决?

产生乱码的起因:

  • 网页源代码是 gbk 的编码,而内容中的中文字是 utf-8 编码的,这样浏览器关上即会呈现 html 乱码,反之也会呈现乱码;
  • html网页编码是 gbk,而程序从数据库中调出出现是utf-8 编码的内容也会造成编码乱码;
  • 浏览器不能自动检测网页编码,造成网页乱码。

解决办法:

  • 应用软件编辑 HTML 网页内容;
  • 如果网页设置编码是gbk,而数据库贮存数据编码格局是UTF-8,此时须要程序查询数据库数据显示数据后退程序转码;
  • 如果浏览器浏览时候呈现网页乱码,在浏览器中找到转换编码的菜单进行转换。
正文完
 0