WebProblem
一、网页布局
一、HTML面试题
-
- DOCTYPE的作用是什么?
- 声明一般位于文档的第一行,它的作用主要是告诉浏览器以什么样的模式来解析文档。一般指定了之后会以标准模式来进行文档解析,否则就以兼容模式进行解析。在标准模式下,浏览器的解析规则都是按照最新的标准进行解析的。而在兼容模式下,浏览器会以向后兼容的方式来模拟老式浏览器的行为,以保证一些老的网站的正确访问
-
- 标准模式与兼容模式各有什么区别?
- 标准模式的渲染方式和 JS 引擎的解析方式都是以该浏览器支持的最高标准运行
- 兼容模式中,页面以向后兼容的方式显示 ,模拟老式浏览器的行为以防止站点无法工作
-
- HTML5 为什么只需要写 ,而不需要引入 DTD?
- HTML5 不基于 SGML,因此不需要对 DTD 进行引用,但是需要 DOCTYPE 来规范浏览器的行为,即让浏览器按照它们应该的方式来运行。而 HTML4.01 是基于 SGML ,所以需要对 DTD 进行引用,才能告知浏览器文档所使用的文档类型
-
- 什么是DTD?
- DTD( Document Type Definition 文档类型定义)是一组机器可读的规则,它们定义 XML 或 HTML 的特定版本中所有允许元素及它们的属性和层次关系的定义。在解析网页时,浏览器将使用这些规则检查页面的有效性并且采取相应的措施。
DTD 是对 HTML 文档的声明,还会影响浏览器的渲染模式(工作模式)
-
- SGML 、 HTML 、XML 和 XHTML 的区别?
- SGML:是标准通用标记语言,是一种定义电子文档结构和描述其内容的国际标准语言,是所有电子文档标记语言的起源
- HTML:是超文本标记语言,主要是用于规定怎么显示网页
- XML:是可扩展标记语言,是未来网页语言的发展方向,XML 和 HTML 的最大区别就在于 XML 的标签是可以自己创建的,数量无限多, 而 HTML 的标签都是固定的而且数量有限
- XHTML:也是现在基本上所有网页都在用的标记语言,他其实和 HTML 没什么本质的区别,标签都一样,用法也都一样,就是比 HTML 更严格,比如标签必须都用小写,标签都必须有闭合标签等
-
- 空元素定义
- 标签内没有内容的 HTML 标签被称为空元素。空元素是在开始标签中关闭的
- 常见的空元素有:br hr img input link meta
-
- 你是如何理解语义化的?
- 语义化,顾名思义,就是你写的HTML结构,是用相对应的有一定语义的英文字母(标签)表示的、标记的,因为HTML本身就是标记语言。不仅对自己来说,容易阅读,书写。别人看你的代码和结构也容易理解,甚至对一些不是做网页开发的人来说,也容易阅读。那么,我们以后在开发的过程中,一定要注意了,尽量使用官方的、有语义的标签,不要再使用一堆无意义的标签去堆你的结构
-
- H5 是什么?
- H5是HTML5的简称,就是 “ HTML ” 的第5个版本,也就是第5个版本的超文本标记语言
-
- 简述一下src与href的区别?
- src用于替换当前元素,href用于在当前文档和引用资源之间确立联系
- src是source的缩写,指向外部资源的位置,指向的内容将会嵌入到文档中当前标签所在位置;在请求src资源时会将其指向的资源下载并应用到文档内,例如js脚本,img图片和frame等元素
当浏览器解析到该元素时,会暂停其他资源的下载和处理,直到将该资源加载、编译、执行完毕,图片和框架等元素也如此,类似于将所指向资源嵌入当前标签内。这也是为什么将js脚本放在底部而不是头部
- href是Hypertext Reference的缩写,指向网络资源所在位置,建立和当前元素(锚点)或当前文档(链接)之间的链接,如果我们在文档中添加
-
- Label 的作用是什么?是怎么用的?
- label 标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上
-
- 很多网站都不常用table、iframe这两个元素,你知道什么原因吗?
- 因为浏览器页面渲染的时候是从上至下的,而table 和 iframe 这两种元素会改变这样渲染规则,他们是要等待自己元素内的内容加载完才整体渲染。用户体验会很不友好
-
- jpg和png格式的图片有什么区别?
- jpg是有损压缩格式,png是无损压缩格式。所以,相同的图片,jpg体积会小。比如我们一些官网的banner图,一般都很大,所以适合用jpg类型的图片。但png分8位的和24位的,8位的体积会小很多,但在某些浏览器下8位的png图片会有锯齿
-
- a标签的伪类中,active hover link visited 的正确顺序是什么?
- a:link a:visited a:hover a:active
-
- 前端页面由哪三层构成?分别是什么?作用是什么?
- ① 结构层:HTML,主要负责搭建页面的整体架构
- ② 样式层:CSS,主要负责为页面添加样式,进行美化
- ③ 行为层:JavaScript,主要负责页面与用户的交互
-
- 简述你对html语义化的理解?
- html语义化其实就是用正确的标签做正确的事,html语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析,即使在没有css样式的情况下,也是以一种文档的格式显示,并且是容易阅读的。搜索引擎的爬虫也依赖于html标记来确定上下文和各个关键字的权重,利于SEO。同时使阅读源代码的人对网站更容易分块,便于阅读维护理解
-
- 下面关于HTML5 中表格的说法错误的是()?
- A. 表格只能包含0 或1 个
- B. 表格
可以有且仅能定义一个子元素子元素定义标题 - C. 表格
用定义表格行,用
- D. 表格
用定义表格头定义表格列 - 答案:B
-
- HTML5 正确的doctype是()?
- A.
- B.
- C. .
- D.
- 答案:A
-
- 标签是不是最小的节点?
-
答案
- 一个<标签名>是一个标签,一个标签不会成为节点对象。只有由开始标签+结束标签联合表示的一个元素才是一个元素节点对象。节点不分大小,只区分上下级。而元素节点不一定就是最底层的节点。还可能包含子元素或子文本。但是,在元素树中,最底层节点一定都是元素节点
-
- href=""能不能表示空连接?
- 不行,href="",表示没有href属性,a也就不是一个超链接元素了。鼠标放上去,是变不成手指的。因为,"“是所有无效属性的默认值。href=”",相当于让href属性失效
-
- 空链接: 和 有什么差别?
-
答案
-
href="#" 不是不跳转,而是在当前页面内跳转。而且只写一个#,表示回到顶部的意思。如果页面很长,且发生了滚动,用href="#",会导致页面跳回顶部
-
href=“javascript:;”,其实href中有两种选择
-
- href=“url或#锚点” 执行跳转操作
-
- href=“javascript: js语句;” 当href中以javascript:开头时,浏览器不再执行跳转操作。而是执行javascript:后规定的js语句。但是,多数情况下,不会这么写,因为不符合内容与行为分离的原则。但是javascript:;经常用来表示什么也不做。“;” 本来是js语句的结束,如果分号单用,表示空语句,什么也不做
-
-
-
- iframe的优缺点?
-
优点
-
- 解决加载缓慢的第三方内容如图标和广告等的加载问题
-
- Security sandbox
-
- 并行加载脚本
-
-
缺点
-
- iframe会阻塞主页面的Onload事件
-
- 即时内容为空,加载也需要时间
-
- 没有语意
-
-
- div+css的布局较table布局有什么优点?
-
- 改版的时候更方便 只要改css文件
-
- 页面加载速度更快、结构化清晰、页面显示简洁
-
- 表现与结构相分离
-
- 易于优化(seo)搜索引擎更友好,排名更容易靠前
二、CSS面试题
-
- rem与em区别?
- rem:相对于根元素html的font-size,假如html为font-size:12px,那么,将其中的div设置为font-size:2rem,此时div字体大小为:12*2=24px
- em:相对于父元素计算,假如某个p元素为font-size:12px,在它内部有个span标签,设置font-size:2em,那么这时候的span字体大小为:12*2=24px
-
- display:none; 和 visibility:hidden; 的区别是什么?
- display:隐藏对应的元素并且挤占该元素原来的空间
- visibility:隐藏对应的元素但是不挤占该元素原来的空间
- 也就是说,使用CSS display:none属性后,HTML元素(对象)的宽度、高度等各种属性值都将“丢失”;而使用visibility:hidden属性后,HTML元素(对象)仅仅是在视觉上看不见(完全透明),而它所占据的空间位置仍然存在
-
- 请写出至少5五种解决浮动造成的高度坍塌的方法?
-
- 父级div定义伪类:after加clear:both
-
- 父级div定义overflow:hidden
-
- 父级div定义height
-
- 在结尾处添加空div标签clear:both
-
- 父级div定义overflow:auto
-
- 父级div也一起浮动
-
- 父级div定义display:table
-
- 结尾处加br标签clear:both
-
- 谈谈你对 BFC 规范的理解有哪些?(BFC是什么?)
-
BFC(Block formatting context)直译为"块级格式化上下文"。它是一个独立的渲染区域,只有 Block-level box 参与, 它规定了内部的 Block-level Box 如何布局,并且与这个区域外部毫不相干
- BFC(块级格式化上下文),一个创建了新的BFC的盒子是独立布局的,盒子内元素的布局不会影响盒子外面的元素。在同一个BFC中的两个相邻的盒子在垂直方向发生margin重叠的问题
- BFC是指浏览器中创建了一个独立的渲染区域,该区域内所有元素的布局不会影响到区域外元素的布局,这个渲染区域只对块级元素起作用
-
BFC 布局规则
- a. 内部的 Box 会在垂直方向,一个接一个地放置
- b. Box 垂直方向的距离由 margin 决定。属于同一个 BFC 的两个相邻 Box 的 margin 会发生重叠
- c. 每个元素的 margin box 的左边, 与包含块 border box 的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此
- d. BFC 的区域不会与 float box 重叠
- e. BFC 就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此
- f. 计算 BFC 的高度时,浮动元素也参与计算
-
触发 BFC
- A. 根元素
- B. float 属性不为 none
- C. position 为 absolute 或 fixed
- D. display 为 inline-block, table-cell, table-caption, flex, inline-flex
- E. overflow 不为 visible
-
- 页面中有一个不知道尺寸的div,请写出三种方法,实现div的水平垂直居中?
- div{
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
margin:auto;
} - div{
position:absolute;
top:50%;
left:50%;
transform:translate(-50%,-50%);
} - // 给div加父容器container
#container{
display:flex;
justify-content:center;
align-items:center;
}
-
- 页面导入样式使用 link 和 import 有什么区别?
-
- link是XHTML标签,而@import是CSS提供的
-
- link写在html页面中,只能存在于 head 部分,而@import写在CSS文件中
-
- link引用CSS时,在页面载入时同时加载,而@import需要页面网页完全载入以后加载
-
- link是XHTML标签,无兼容问题;@import是在CSS2.1提出的,低版本(IE5及以下)的浏览器不支持
-
- link支持使用Javascript控制DOM去改变样式,而@import不支持
-
- link方式的样式的权重高于@import的权重
-
详细
-
- 从属关系区别:@import是CSS提供的语法规则,只有导入样式表的作用;link是HTML提供的标签,不仅可以加载CSS文件,还可以定义RSS、rel连接属性、引入网站图标等
-
- 加载顺序区别:加载页面时,link标签引入的CSS文件被同时加载;而@import引入的CSS文件将在页面加载完毕后被加载
-
- 兼容性区别:@import时CSS 2.1才有的语法,故只可在IE5+才能识别;link标签作为HTML标签,不存在兼容性问题
-
- DOM可控性区别:可以通过JS操作DOM,插入link标签来改变样式;由于DOM方法是基于文档的,无法使用@import的方法插入样式
-
-
- css sprite 是什么?有什么优缺点?
-
css sprite是将多个小图片拼接到一个图片中。通过background-position和元素尺寸调节需要显示的背景图案,即我们所说的精灵图,也叫雪碧图
-
优点
- 减少http请求数,极大地提高页面加载速度
- 增加图片信息重复度,提高压缩比,减少图片大小
- 更换风格方便,只需在一张或几张图片上修改颜色或样式即可实现
-
缺点
- 图片合并麻烦
- 维护麻烦,修改一个图片可能需要从新布局整个图片,样式
-
- 行内元素和块级元素的具体区别是什么?行内元素的margin和padding可以设置吗?
-
- 块级元素(block)特性
- 总是独占一行,表现为另起一行开始,而且其后的元素也必须另起一行显示。宽度(width)、高度(height)、内边距(padding)和外边距(margin)都可控制
-
- 行内元素(inline)特性
- 和相邻的内联元素在同一行。宽度(width)、高度(height)、内边距的top(padding-top/padding-bottom)和外边距的top/bottom(margin-top/margin-bottom)都不可改变(也就是padding和margin的left和right是可以设置的),就是里面文字或图片的大小,内容区域的大小是由内容撑开的
-
- rgba()和opacity的透明效果有什么不同?
- rgba()和opacity都能实现透明效果,但最大的不同是opacity作用于元素,以及元素内的所有内容的透明度。而rgba()只能作用于元素的颜色或其背景颜色,同时,设置rgba透明的元素的子元素不会继承透明效果
-
- 列出display的值,说明他们的作用?position的值relative和absolute定位原点是谁?
-
display的值
- block:设置元素为块级元素显示;
- inline:设置元素为行内元素显示;
- inline-block:设置元素为行内块元素显示;
- none:彻底的隐藏元素包括位置也不在占据;
-
positon的值
- relative:生成相对定位的元素,相对于其本身位置进行定位
- absolute:生成绝对定位元素,当绝对定位元素的祖先元素,没有已定位元素,相对于浏览器的左上角进行定位,当绝对定位元素的祖先元素,有已定位元素的时候,以“最近的”,“已定位的”,“祖先元素”的左上角进行定位
-
- 当 a. 内联样式 b. 内部样式 c. 外部样式 d. 浏览器缺省设置 等多个样式层叠,以下正确优先级顺序是()?
A. acdb
B. abcd
C. bacd
D. dbac
- 结果:B
- 当 a. 内联样式 b. 内部样式 c. 外部样式 d. 浏览器缺省设置 等多个样式层叠,以下正确优先级顺序是()?
-
- 下面 E 代表元素,attr代表属性,错误的属性选择表示是()?
A. E[attr]
B. E[attr=value]
C. E[attr%=“value”]
D. E[attr$=“value”]
- 结果:C
- 下面 E 代表元素,attr代表属性,错误的属性选择表示是()?
-
- 要你出一套适应不同分辨率,不同终端的前端实现方案你有什么思路?
- 流式布局: 使用非固定像素来定义网页内容,也就是百分比布局,通过盒子的宽度设置成百分比来根据屏幕的宽度来进行伸缩,不受固定像素的限制,内容向两侧填充。这样的布局方式,就是移动 web开发使用的常用布局方式。这样的布局可以适配移动端不同的分辨率设备
- 响应式开发:简而言之,就是一个网站能够兼容多个终端。CSS3 中的 Media Query(媒介查询),通过查询 screen 的宽度来指定某个宽度区间的网页布局
超小屏幕(移动设备) 768px 以下
小屏设备 768px-992px
中等屏幕 992px-1200px
宽屏设备 1200px 以上
由于响应式开发显得繁琐些,一般使用第三方响应式框架来完成,比如 bootstrap 来完成一部分工作,当然也可以自己写响应式
-
- 主流浏览器及其内核?
- IE:trident
- chrome:webkit/blink
- Safari:webkit
- Opera:presto
- Firefox:gecko
-
- 介绍一下css盒子模型?
- W3C盒子模型(标准盒模型) box-sizing: content-box;
根据 W3C 的规范,标准模式下,盒子的最终宽度/高度 = 原始宽度/高度 + 左右/上下的内边距 + 左右/上下的外边距 - IE盒子模型(怪异盒模型) box-sizing: border-box;
在该模式下,怪异模式下,盒子的最终宽度/高度 = 原始宽度/高度+左右/上下的外边距
-
- 搭建页面实现,左右两边定宽,中间⾃适应的的布局(写出关键代码)
- .wrap{
width: 100%;
height: 100px;
display: flex;
}
.wrap>div:first-child,.wrap>div:last-child{
width: 100px;
height: 100%;
}
.wrap>div:nth-child(2){
flex-grow: 1;
}
-
- CSS选择器有哪些?哪些属性可以继承?
-
CSS选择符:id选择器(#myid)、类选择器(.myclassname)、标签选择器(div, h1, p)、相邻选择器(h1 + p)、子选择器(ul > li)、后代选择器(li a)、通配符选择器(*)、属性选择器(a[rel=“external”])、伪类选择器(a:hover, li:nth-child)
-
可继承的属性:font-size, font-family, color
-
不可继承的样式:border, padding, margin, width, height
-
优先级(就近原则):!important > [ id > class > tag ]
- !important 比内联优先级高
二、BootStrap
1. 为什么要使用 less/sass 预处理器(优点、缺点)
-
优点
-
- CSS 无法递归式定义
-
- CSS 的 mixin 式复用性支持不够
-
- 预编译可缓解多浏览器兼容造成的冗余,css 并不能算是一们真正意义上的“编程”语言,它本身无法未完成像其它编程语言一样的嵌套、继承、设置变量等工作。为了解决css 的不足,开发者们想到了编写一种对 css 进行预处理的“中间语言”,可以实现一些“编程”语言才有的功能,然后自动编译成 css 供浏览识别,这样既一定程度上弥补了css 的不足,也无需一种新的语言来代替 css 以供浏览器识别。于是 css 预处理语言就应运而生了
-
- CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS
更易维护和扩展
- CSS 预处理语言,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS
-
-
缺点
-
- CSS 的好处在于简便、随时随地被使用和调试。预编译 CSS 步骤的加入,让我们开发工作流中多了一个环节,调试也变得更麻烦了
-
- 预编译很容易造成后代选择器的滥用因此,实际项目中衡量预编译方案时,还是得想想,比起带来的额外维护开销,预编译有没有解决更大的麻烦。降低了自己对最终代码的控制力
-
- 更致命的是提高了门槛,首先是上手门槛,其次是维护门槛,再来是团队整体水平和规范的门槛。这也造成了初学学习成本的昂贵
-
2. less/sass 区别?
-
- sass 是基于 Ruby 的,然后是在服务器端处理的。很多开发者不会选择 LESS 因为JavaScript 引擎需要额外的时间来处理代码然后输出修改过的 CSS 到浏览器
-
- 关于变量在 LESS 和 Sass 中的唯一区别就是,LESS 用@,Sass 用$
三、Git与GitHub
四、JavaScript
一、变量
-
- Javascript中,以下哪条语句一定会产生运行错误?
A. var _变量=NaN;
B. var 0bj = [];
C. var obj = //;
D. var obj = {};
- 结果:B C
- Javascript中,以下哪条语句一定会产生运行错误?
-
- 以下哪条语句会产生运行错误:()
A. var obj = ();
B. var obj = [];
C. var obj = {};
D. var obj = //;
- 结果:A D
- 以下哪条语句会产生运行错误:()
-
- 以下哪个单词不属于javascript保留字:()
A. with
B. parent
C. class
D. void
- 结果:B
- 以下哪个单词不属于javascript保留字:()
-
- 以下 js 的运行结果是什么,为什么?
var txt=‘hx’;
function hello(){
var txt;
fn();
var fn=function(){alert(‘hello’)}
function fn(){alert(‘world’);}
alert(txt);
fn();
fn=function(){alert(‘hello’)}
}
hello();
- var txt=‘hx’;
function hello(){
var txt;
fn(); //world 函数名与变量名重复的时候,以函数名为主
var fn=function(){alert(‘hello’)}
function fn(){alert(‘world’);}
alert(txt); //undefined 局部变量,只是声明,没有赋值
fn(); //hello 先进行声明,后赋值,执行
fn=function(){alert(‘hello’)}
}
hello();
- 以下 js 的运行结果是什么,为什么?
二、数据类型
-
- JavaScript 有哪几种数据类型?
- 原始类型:数值型(number)/字符串型(string)/布尔型(boolean)/undefined/null
- 引用类型:对象(object)、数组(array)、函数(function)
-
- typeof 返回的类型有哪些?
- number 、string 、boolean 、undefined 、object 、function
-
- null 和 undefined的区别?
- null 是 Null 类型,代表 “ 空值 ”,代表一个空对象指针,使用 typeof 运算得到 “ object ”,所以你可以认为它是一个特殊的对象值。undefined 是 Undefined 类型,当声明了一个变量未初始化时,得到的就是undefined。null 和 undefined 都表示 “ 值的空缺 ”,你可以认为undefined是表示系统级的、出乎意料的或类似错误的值的空缺,而null是表示程序级的、正常的或在意料之中的值的空缺。在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined。null值则是表示空对象指针。(undefined是访问一个未初始化的变量时返回的值,而null是访问一个尚未存在的对象时所返回的值。因此,可以把undefined看作是空的变量,而null看作是空的对象。在定义一个想保存对象的变量时,就可以让该变量先保存null值,这样既能体现null是一个空指针对象,也能更好的区分null和undefined)
-
- 下面程序执行后,会输出几个true?()
console.log([][]);
console.log({}{});
console.log(/\d//\d/);
console.log(MathMath)
A. 1个 B.2个 C.3个 D.4个
-
结果:A
- console.log([][]); // false
console.log({}{}); // false
console.log(/\d//\d/); // false
console.log(MathMath) // true
- console.log([][]); // false
- 下面程序执行后,会输出几个true?()
-
- 下面程序的执行结果为?
var a=“2.2”;
var b=1.8;
var c=parseInt(a+b)
console.log©
A.2 B. 3 C. 4 D. 5
- 结果:A
- 下面程序的执行结果为?
-
- 例举3种强制类型转换和2种隐式类型转换?
- 强制转换:parseInt()、parseFloat()、Number()
- 隐式转换:== 、!!
-
- 看下列代码输出为何?解释原因?
var a;
alert(typeof a);
alert(b);
- a的输出结果为undefined,undefined是一个只有一个值的数据类型,这个值就是 “ undefined ”,在使用var声明变量但并未对其赋值进行初始化时,这个变量的值就是 undefined。而b由于未声明将报错。注意未声明的变量(b is not defined)和声明了未赋值的是不一样的
- 看下列代码输出为何?解释原因?
-
- 看下列代码,输出什么?解释原因?
var a = null;
alert(typeof a);
- 输出结果为object,null是一个只有一个值的数据类型,这个值就是null,表示一个空指针对象,所以用typeof检测会返回 ” object ”
- 看下列代码,输出什么?解释原因?
-
- 看下列代码,输出什么?解释原因?
var undefined;
undefined == null;
1 == true;
2 == true;
0 == false;
0 == ‘’;
NaN == NaN;
[] == false;
[] == ![];
- var undefined;
console.log(undefined == null); //true
console.log(1 == true); //true
console.log(2 == true); //false
console.log(0 == false); //true
console.log(0 == ‘’); //true
console.log(NaN == NaN); //false
console.log([] == false); //true
console.log([] == ![]); //true - 解析:
- 看下列代码,输出什么?解释原因?
- undefined 与 null 相等,但不恒等,undefined和null进行比较的过程中,会先将undefined隐式转换为null再进行比较
2.3.4.5 == 比较,默认情况下一切转为number进行比较 - NaN不等于,不大于,不小于一切,因为NaN表示所有不是数字的内容,是一个范围,不表示一个具体值,做比较无任何意义
- 在和对象比较的过程中,将对象转换为number或string,取决于另一个对比量的类型
- [][]为false,所有[]![]为true
-
- 请选择结果为真的表达式:()
A. null instanceof Object
B. null === undefined
C. null == undefined
D. NaN == NaN
- 结果:C
- 请选择结果为真的表达式:()
-
- 下面的代码将输出到控制台什么,为什么?
(function(){
var a = b = 3;
})();
console.log("a defined? " + (typeof a !== ‘undefined’));
console.log("b defined? " + (typeof b !== ‘undefined’));
-
a defined? false
b defined? true- 解析:b没有声明直接赋值,程序会自动在全局下定义一个全局变量b,所有b的值可以获取到,结果为3,不是undefined,但是a时声明在函数中的,所有在全局下是得不到a的值的,默认为undefined
- 下面的代码将输出到控制台什么,为什么?
-
- 如下代码输出的结果是什么:
console.log(1+ “2”+“2”);
console.log(1+ +“2”+“2”);
console.log(“A”- “B”+“2”);
console.log(“A”- “B”+2);
A.122 122 NaN NaN
B.122 32 NaN NaN2
C.122 32 NaN2 NaN
D.122 32 NaN2 NaN2
-
结果:C
- a. console.log(1+ “2”+“2”);
做加法时要注意双引号,当使用双引号时,JavaScript 认为是字符串,字符串相加等于字符串合并。因此,这里相当于字符串的合并,结果为:122 - b. console.log(1+ +“2”+“2”);
第一个+"2"中的加号是一元加操作符,+"2"会变成数值 2,因此 1+ +"2"相当于 1+2=3,然后和后面的字符串 “2” 相合并,变成了字符串 “32” - c. console.log(“A”- “B”+“2”);
“A”-“B"的运算中,需要先把"A"和"B"用 Number 函数转换为数值,其结果为 NaN,在减法操作中,如果有一个是 NaN,则结果是 NaN,因此"A”-"B"结果为 NaN,然后和"2"进行字符串合并,变成了 NaN2 - d. console.log(“A”- “B”+2);
根据上题所述,“A”-"B"结果为 NaN,然后和数值 2 进行加法操作,在加法操作中,如果有一个操作数是 NaN,则结果为 NaN
- a. console.log(1+ “2”+“2”);
- 如下代码输出的结果是什么:
三、逻辑结构
-
- continue和 break有什么区别?
- break和continue都是用来控制循环结构的
- break:终止循环,跳出循环体执行循环后面的语句
- continue:跳过本次循环,执行下一次循环
-
- JavaScript中循环语句书写正确的是()?
A. if(i<10;i++)
B. for(i=0;i<10)
C. for i=1 to 10
D. for(i=0;i<=10;i++)
- 答案:D
- JavaScript中循环语句书写正确的是()?
-
- 写出程序运行的结果?
for(i=0, j=0; i<10, j<6; i++, j++){
k = i + j;
}
console.log(k)
- 结果:10
- 写出程序运行的结果?
-
- 试写出程序运行结果
for(var i=4,s=1;i>0;i–){s*=i}
console.log(s)
- 结果:24
- 试写出程序运行结果
四、运算符
-
- i++和++i的区别?计算:var n=5; 求 var num=n+++++n+n+++++n+n; 的结果?
- i++ :先用i值后加1;
- ++i :先加1后用i值;
- 结果:37
-
- 请说出 (true+false)>2+true 的执行结果?
- 答案:false
-
- == 和 === 有什么不同?
- == 抽象相等,比较时,会先进行类型转换,然后再比较值
- === 严格相等,判断两个值相等同时数据类型也得相同
-
- 下面程序的执行结果为?
var a=3
var b=4
var c=a++ +b++ + ++a+ ++b
console.log©
A. 17 B.18 C.19 D.20
- 结果:B
- 下面程序的执行结果为?
-
- 2==[[[2]]] 是真是假?为什么?
-
引用类型转换为基本类型
-
- 所有的引用类型转换为布尔型的结果都是true
-
- 引用类型转换为字符串
- a. 优先调用toString方法(如果有),看其返回结果是否是原始数据类型,如果是,转换为字符串,返回
- b. 否则,调用valueOf方法(如果有),看其返回结果是否是原始数据类型,如果是,转换为字符串,返回
- c. 其他报错
-
- 引用类型转换为数字
- a. 优先调用valueOf方法(如果有),看其返回结果是否是原始数据类型,如果是,转换为数字,返回
- b.否则,调用toString方法(如果有),看其返回结果是否是原始类型,如果是,转化为数字,返回
- c. 其他报错
-
-
解析:因为是与数字进行比较,所有优先调用valueOf()方法,返回的本身不是原始数据类型,然后调用toString()方法得到“2”,然后就变成了字符串“2”和数字2进行比较
-
结果:true
-
valueOf()
-
提示:返回指定对象的原始值
-
object.valueOf()
- Object:返回对象本身
- String:字符串值
- Number:数字值
- Boolean:返回布尔值
- Array:返回数组本身
- Date:存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数
- Function:返回函数本身
-
-
- 读程序,写结果:
var x=10;
var y=20;
var z=x<y?x++:++y;
console.log(‘x=’+x+’;y=’+y+’;z=’+z)
- 结果:x=11 y=20 z=10
- 读程序,写结果:
-
- 下面四个表达式中,结果为NaN的是()?
① 100/0 ② 0/0 ③ parseInt(“邮政储蓄”) ④ “NaNxyz”-“xyz”
A. ①
B. ②
C. ②③
D. ②③④
- ① 100/0:infinity
- ② 0/0:NaN
- ③ parseInt(“邮政储蓄”):NaN
- ④ “NaNxyz”-“xyz”:NaN
- 结果:D
- 下面四个表达式中,结果为NaN的是()?
-
- 看下面的代码,输出什么,foo的值为什么?
var foo = “11”+2-“1”;
console.log(foo);
console.log(typeof foo);
- 执行完后foo的值为111,foo的类型为Number
- 看下面的代码,输出什么,foo的值为什么?
-
- foo = foo||bar ,这行代码是什么意思?为什么要这样写?
- if(!foo) foo = bar; //如果foo存在,值不变,否则把bar的值赋给foo
- 短路表达式:作为”&&”和”||”操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程便告终止,这称之为短路求值
-
- 下面程序的执行结果为?()
var a= 5 && true;
var b= false || 6;
console.log(a+b)
A. 5 B. 7 C. 13 D.1
-
答案:B
-
||
-
- 只要 || 前面为 false,不管 || 后面是 true 还是 false,都返回 || 后面的值
-
- 只要 || 前面为 true,不管 || 后面是 true 还是 false,都返回 || 前面的值
-
-
&&
-
- 只要 && 前面是 false,无论 && 后面是 true 还是 false,结果都将返 && 前面的值
-
- 只要 && 前面是 true,无论 && 后面是 true 还是 false,结果都将返 && 后面的值
-
-
- 下面程序的执行结果为?()
-
- 请写出下面输出的值
Console.log(undefined || 1);
Console.log(null || NaN);
Console.log(0 && 1);
Console.log(0 && 1 || 0);
- Console.log(undefined || 1);//值___1__
- Console.log(null || NaN);//值__NaN___
- Console.log(0 && 1);//值__0___
- Console.log(0 && 1 || 0);//值__0___
- 请写出下面输出的值
-
- 以下两个变量a和b,a+b的哪个结果是NaN?
A、var a=undefined; b=NaN
B、var a=‘123’; b=NaN
C、var a =undefined , b =NaN
D、var a=NaN , b=‘undefined’
- 答案:AC
- 以下两个变量a和b,a+b的哪个结果是NaN?
-
- var a=10; b=20; c=4; ++b+c+a++ 以下哪个结果是正确的?
A、34 B、35 C、36 D、37
- 答案:B
- var a=10; b=20; c=4; ++b+c+a++ 以下哪个结果是正确的?
-
- 分析代码,得出正确的结果。
var a=10, b=20 , c=30;
++a;
a++;
e=++a+(++b)+(c++)+a++;
alert(e);
- 弹出提示对话框:77
- 分析代码,得出正确的结果。
五、函数
-
- JavaScript中arguments的用法
-
- Javascript并没有重载函数的功能,但是Arguments对象能够模拟重载。Javascrip中每个函数都会有一个Arguments对象实例arguments,它引用着函数的实参,可以用数组下标的方式"[]"引用arguments的元素。arguments.length为函数实参个数,arguments.callee引用函数自身
-
- arguments的特性和使用方法
-
- 特性
-
- arguments对象和Function是分不开的
-
- arguments这个对象不能显式创建
-
- arguments对象只有函数开始时才可用
-
- 使用方法
-
- 虽然arguments对象并不是一个数组,但是访问单个参数的方式与访问数组元素的方式相同
-
实例
- arguments[0],arguments[1],。。。arguments[n];
-
- 在js中 不需要明确指出参数名,就能访问它们
-
实例
- function test() {
var s = “”;
for (var i = 0; i < arguments.length; i++) {
alert(arguments[i]);
s += arguments[i] + “,”;
}
return s;
}
test(“name”, “age”);
…
输出结果:
name,age
- function test() {
-
- 每一个对象都有自己的属性,arguments对象也不例外,首先arguments的访问犹如Array对象一样,用0到arguments.length-1来枚举每一个元素。使用callee属性,返回正被执行的 Function 对象,也就是所指定的 Function 对象的正文。callee 属性是 arguments 对象的一个成员,仅当相关函数正在执行时才可用。callee 属性的初始值就是正被执行的 Function 对象。实现匿名的递归函数
-
实例
- var sum = function (n) {
if (1 == n) {
return 1;
} else {
return n + arguments.callee(n - 1);
}
}
alert(sum(6));
…
输出结果:21
- var sum = function (n) {
-
- arguments此对象大多用来针对同个方法多处调用并且传递参数个数不一样时进行使用。根据arguments的索引来判断执行的方法
-
- 知识扩展
-
-
使用arguments进行函数传递
-
实例
- var length = 10;
function fn() {
console.log(this.length);
}
var obj = {
method: function(fn) {
fn();
arguments0;
}
};
obj.method(fn, 1);
- var length = 10;
-
-
输出:10,2
- * 注- 这里有2个需要注意的点。fn函数里面的this的指向- 1. .第一个值为10,执行的是method里面的第一行"fn()",这里this指向的window。所以输出的值为最外层定义的length- 2. 第二个值为2,执行的是method里面的第二行"arguments[0]()"(arguments[0]() => fn()),这里this执行的是arguments这个对象,所以输出值为arguments的长度
-
- 函数声明与函数表达式的区别?
-
相同点:两者都可以创建函数
-
不同点:函数声明可以存在函数提升(前),函数表达式不存在函数提升(前)
-
函数声明
- function myFunction(){}
-
函数表达式
- var myFunc = function(){};
-
- 简述创建函数的几种方式?
-
第一种(函数声明)
- function sum1(num1,num2){
return num1+num2;
}
- function sum1(num1,num2){
-
第二种(函数表达式)
- var sum2 = function(num1,num2){
return num1+num2;
}
- var sum2 = function(num1,num2){
-
第三种(函数对象方式)
- var sum3 = new Function(“num1”,“num2”,“return num1+num2”);
-
- 读程序,写结果:
var z=20;
function foo(){
console.log(z)
}
(function(funArg){
var z=10;
funArg()
})(foo)
- 结果:20
- 读程序,写结果:
-
- 读程序,写结果:
var uname=“jack”
function change(){
console.log(uname)
var uname=“lily”
console.log(uname)
}
change()
- 结果:undefined lily
- 读程序,写结果:
-
- 下面程序的执行结果为?()
var a=true;
var b=false;
function fn(){
if(a){var a=10;}
if(b){var b=20;}
console.log(a+b)
}
fn()
A. 10 B. 20 C. 30 D.NaN
- 结果:NaN
- 下面程序的执行结果为?()
-
- 下面的代码将输出到控制台什么,为什么?
(function(){
var a = b = 3;
})();
console.log("a defined? " + (typeof a !== ‘undefined’));
console.log("b defined? " + (typeof b !== ‘undefined’));
- a defined? false
b defined? true
- 下面的代码将输出到控制台什么,为什么?
-
- 下面的代码将输出到控制台,为什么?
var myObject = {
foo: “bar”,
func: function() {
var self = this;
console.log("outer func: this.foo = " + this.foo);
console.log("outer func: self.foo = " + self.foo);
(function() {
console.log("inner func: this.foo = " + this.foo);
console.log("inner func: self.foo = " + self.foo);
}());
}
};
myObject.func();
- outer func: this.foo = bar
outer func: self.foo = bar
inner func: this.foo = undefined
inner func: self.foo = bar - 解析:this指针问题
- 下面的代码将输出到控制台,为什么?
-
- 如果一对兔子每月生一对兔子;一对新生兔,从第二个月起就开始生兔子;假定每对兔子都是一雌一雄,试问一对兔子,第n个月能繁殖成多少对兔子?(使用callee完成)
- var result=[];
function fn(n){ //典型的斐波那契数列
if(n1){
return 1;
}else if(n2){
return 1;
}else{
if(result[n]){
return result[n];
}else{
//argument.callee()表示fn()
result[n]=arguments.callee(n-1)+arguments.callee(n-2);
return result[n];
}
}
}
-
- 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法?
- // 斐波那契数列
function fn(n){
if(n0 || n1){
return 1
}else{
return arguments.callee(n-1)+arguments.callee(n-2)
}
}
-
- 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法?
- 子主题 1
-
- 对比两个函数中return的差别
functioin fn(){
return 3
}
function fn(){
return
3
}
- 本来一个js表达式中间是可以换行的。但是 return 后如果有返回值的话,不能随意换行。如果换行,js会在return后自动添加返回值。即使return下方还有其他表达式,也不再执行
- 对比两个函数中return的差别
-
- 读程序,写结果
var x=20;
var a={
x:15,
fn:function(){
return function(){
return this.x
}
}
}
console.log(a.fn())
console.log((a.fn())())
console.log(a.fn()())
console.log(a.fn()() == (a.fn())())
console.log(a.fn().call(this))
console.log(a.fn().call(a))
-
- console.log(a.fn());
对象调用方法,返回了一个方法:function() {return this.x}
- console.log(a.fn());
- 读程序,写结果
- console.log((a.fn())());
a.fn()返回的是一个函数,()()这是自执行表达式。this -> window
返回结果:20 - console.log(a.fn()());
a.fn()相当于在全局定义了一个函数,然后再自己调用执行。this -> window
返回结果:20 - console.log(a.fn()() == (a.fn())());
返回结果:true - console.log(a.fn().call(this));
这段代码在全局环境中执行,this -> window
返回结果:20 - console.log(a.fn().call(a));
this -> a
返回结果:15
-
- 定义一个函数,遍历一个指定的父元素下的所有后代元素:① 定义一个函数,仅遍历直接子元素;② 如果当前子元素有更下级直接子元素,则对当前子元素继续调用当前函数,查找子元素的直接子元素
- // 1. 定义函数,遍历父元素下的所有后代元素
function getChildren(parent){
// 2. 获得当前父元素下的所有直接子元素
var children=parent.children;
// 3. 遍历当前父元素下的所有直接子元素
for(var child of children){
// 输出当前子元素的标签名
console.log( child.nodeName )
// 4. 如果 child 有下级直接子元素
if(child.children.length>0){
// 5.对child继续调用getChildren
arguments.callee(child)
}
}
}
// 调用函数:查找body下所有后代元素
getChildren(document.body);
-
- b继承a的方法
- function A( age, name ){
this.age = age;
this.name = name;
}
A.prototype.show = function(){
alert(‘父级方法’);
}function B(age,name,job){
A.apply( this, arguments );
this.job = job;
}B.prototype = new A();
var b = new A(20,‘丁丁’);
var a = new B(21,‘丁丁’,‘前端’);-
- 看下列代码,将会输出什么?
var foo = 1;
(function(){
console.log(foo);
var foo = 2;
console.log(foo);
})()
-
输出undefined 和 2
- 上面代码相当于:
var foo = 1;
(function(){
var foo;
console.log(foo); //undefined
foo = 2;
console.log(foo); // 2;
})()
函数声明与变量声明会被JavaScript引擎隐式地提升到当前作用域的顶部,但是只提升名称不会提升赋值部分
- 上面代码相当于:
- 看下列代码,将会输出什么?
-
- Javascript中callee和caller的作用?
- caller是返回一个对函数的引用,该函数调用了当前函数;
callee是返回正在被执行的function函数,也就是所指定的function对象的正文。
-
- Javascript如何实现继承?
- 1.构造继承法
2.原型继承法
3.实例继承法
-
2.请自选一种方法来实现 fn(1)(2) == 3 的方法
-
读程序,写结果:
function fun() {
var i=10
return function(n){
console.log(n+(++i))
}
}
var fn =new fun();
fn(10)
fn(20)
fun()(10)
fun()(20)- 结果:21 32 21 31
-
var name=“world”;
(function(){
var name;
if(typeof name===“undefined”){
name=“jack”;
console.log(“goodbye”+name)
}else{
console.log(“hello”+name)
}
})()- 结果:goodbyejack
六、对象
-
- 自定义对象的方式?
-
解析:自定义对象就是自己创建的对象(对象字面量/内置构造函数/自定义构造函数…)
-
包含
-
第一种:对象字面量创建对象
-
var obj={
name:“lileilei”,
sex:“男”,
age:20
}- 使用 {} 创建对象,属性名和属性值之间用冒号隔开,多组属性之间用逗号隔开,属性名中引号可加可不加,如果含有特殊字符必须加引号
-
var obj={};
- 空对象,相当于 var obj=new Object();
-
-
第二种:内置构造函数创建对象
-
var obj=new Object();
obj.name=“lileilei”;
obj.sex=“男”;- 使用 new Object()创建一个空对象,需要通过访问对象中属性添加每一个属性
-
-
解析:第一种和第二种缺点
- 代码复用性差,如果要创建多个类似的对象,就会产生大量的重复性代码
-
第三种:工厂模式
-
使用步骤
-
第一步:定义构造函数,将所有属性添加到一个对象的身上,然后返回这个对象
- function Person(name,age,job){
var obj=new Object();
obj.name=name;
obj.age=age;
obj.job=job;
obj.sayName=function(){
alert(this.name)
}
return obj;
}
- function Person(name,age,job){
-
第二步:使用构造函数创建新的对象
- var person1=new Person(‘mingming’,21,‘student’)
- var person2=new Person(‘dingding’,20,‘teacher’)
-
第三步:调用构造函数中方法
- person1.sayName();
- person2.sayName();
-
-
优点
-
工厂模式是使用一个函数来创建对象,能够接收参数,我们可以无数次的调用这个函数,来创建对象,每次创建都可以返回一个包含属性和方法的不同的对象,从而减少代码的重复
-
person1 == person2
- 结果:false
-
-
-
缺点
- 缺点:虽然解决了创建多个相似对象的问题,但是没有解决对象识别的问题,即无法准判断到底是Object的实例对象还是Person的实例对象
-
-
第四种:自定义构造函数创建对象
-
使用步骤
-
- 定义构造函数,直接将属性和方法赋给this对象
- function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.sayName=function(){
alert(this.name)
}
}
-
- 创建一个新对象,要创建Person对象的新实例,当使用了 new 操作符,后台也就执行了new Object()
- var person1=new Person(“lili”,24,“teacher”)
- var person2=new Person(“leilei”,20,“student”)
-
- 将构造函数的作用域赋给新对象,此时的this就指向这个新对象
-
- 执行构造函数中的代码
- person1.sayName()
- person2.sayName()
-
- 返回对象,后台会直接返回
-
-
优点
-
即解决的代码重复的问题,又解决了对象识别的问题
-
person1 instanceof Object;
- 结果:true
-
person1 isntanceof Person;
- 结果:true
-
-
创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型
-
-
缺点
-
每个方法都要在每个实例上重新创建一遍,造成资源浪费。person1,person2都有一个名为sayName()的方法,但这两个方法不是同一个Function的实例。因为ECMAScript中的函数是对象,所以每定义一个函数都是实例化了一个对象
-
person1 == person2
- 结果:false
-
-
-
注意:构造函数始终要应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头
-
-
第五种:原型模式
-
使用步骤
-
第一步:创建构造函数
- function Person(){}
-
第二步:通过原型链添加对象
- Person.prototype.name=“pingping”;
- Person.prototype.age=20;
- Person.prototype.job=“student”;
- Person.prototype.sayName=function(
console.log(this.name)
}
-
第三步:封装属性和方法,可以使用对象字面量,原型对象写法
- Person.prototype={
constructor:Person,
name:“pingping”,
age:20,
job:“student”,
sayName(){
console.log(this.name)
}
}
- Person.prototype={
-
第四步:构造对象
- var person1=new Person();
- var person2=new Person();
-
第五步:调用方法
-
person1.sayName() == person2.sayName()
- 结果:true
-
-
-
原型对象
-
我们创建的每个函数都有一个 prototype 的属性,这个属性是一个指针,指向函数的原型对象。在默认情况下,所有原型对象都会自动获得一个 constructor(构造函数) 属性,这个属性是一个指向 prototype 属性所在函数的指针
-
prototype
-
prototype其实就是存在于对象中的一个特殊的对象,我们可以把它理解为对象的一个属性或方法,每个对象都有一个prototype,除了null
-
Person.prototype
- 原型对象
-
Person.prototype.isPrototypeOf(person1)
- 用于指示对象是否存在于另一个对象的原型链中。如果存在,返回true,否则返回false
-
Object.getPrototypeOf(person1)
- 返回prototype的值,等于 Person.prototype
-
-
-
proto
-
Person的每个实例都包含一个内部属性 [_prorto],该属性指向构造函数的原型对象 Person.prototype
- person1.proto == Person.prototype
-
-
constructor
-
Person.prototype.constructor
- 指向Person
-
person1(实例化对象).constructor
- 指向Person
-
-
-
优点
- 减少了代码的重复,也可用标识来创建对象
-
缺点
-
- 它省略了为构造函数传递初始化参数这一环节,结果所有势力在默认情况下都将取得相同的属性值
-
- 原型中所有属性是被很多势力共享的,这种共享对函数来说非常适合,对于那些包含基本值的属性也还说得过去,但是对于包含引用类型值的属性来说,就是一个问题了,因为实例一般都有属于自己的全部属性
-
-
-
第六种:组合构造函数模式和原型模式
-
提示:构造函数模式用于定义实例属性,而原型模式用于定义方法和共享的属性。这样,每个实例都有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度的节省了内存。而且还支持向构造函数传递参数。这种方式也是ECMAScript种使用最广泛,认同度最高的一种创建自定义类型的方法
-
使用步骤
-
第一步:创建函数
- function Person(name,age,job){
this.name=name;
this.age=age;
this.job=job;
this.friends=[“lili”,“mingming”]
}
- function Person(name,age,job){
-
第二步:原型对象添加
- Person.prototype={
constructor:Person,
sayName:function(){
alert(this.name)
}
}
- Person.prototype={
-
第三步:创建新的对象
- var person1=new Person(“dingding”,21,“teacher”);
- var person2=new Person(“xinxin”,20,“student”);
-
第四步:调用方法
-
person1.friends.push(“huhu”);
-
alert(person1.friends == person2.friends)
- 结果:false
-
alert(person1.sayName==person2.sayName)
- 结果:true
-
-
-
-
-
- 请指出JavaScript宿主对象和原生对象的区别?
- 宿主对象:指JavaScript解释器提供的对象,由解释器厂家自定义并提供实现,不同的解释器提供的扩展对象存在较大的差异(DOM和BOM对象)
- 原生对象:JavaScript语言本身预定义的对象,在ECMAScript标准中定义,由所有的解释器厂家来提供具体实现(Array,Date,Math,Number,String,Boolean等)
-
- 取 1~11之间的随机数 (即包括1不包括11)?
- Math.floor(Math.random()*10+1)
- parseInt (Math.random()*10+1)
-
- 写出函数DateDemo的返回结果,系统时间假定为今天
function DateDemo(){
var d,s=“今天日期是:”
d=new Date()
s+=d.getMonth()+1+"/"
s+=d.getDate()+"/"
s+=d.getFullYear()
return s
}
console.log(DateDemo)
- 结果:今天日期是:8/29/2020
- 写出函数DateDemo的返回结果,系统时间假定为今天
-
- javascript的本地对象,内置对象和宿主对象?
- 本地对象为array obj regexp等可以new实例化
- 内置对象为gload Math 等不可以实例化的
- 宿主为浏览器自带的document,window 等
-
- 看代码给答案
var a = new Object();
a.value = 1;
b = a;
b.value = 2;
alert(a.value);
- 结果:2
- 看代码给答案
-
- 看代码给答案
var a = new Object();
a.value = 1;
b = a;
b.value = 2;
alert(a.value);
-
答案:2
- (考察引用数据类型细节)引用数据类型,数据放在堆中,指针指向这个数据
- 看代码给答案
-
- 输出今天的日期,以YYYY-MM-DD的方式,比如今天是2014年9月26日,则输出2014-09-26
- var d = new Date();
// 获取年,getFullYear()返回4位的数字
var year = d.getFullYear();
// 获取月,月份比较特殊,0是1月,11是12月
var month = d.getMonth() + 1;
// 变成两位
month = month < 10 ? ‘0’ + month : month;
// 获取日
var day = d.getDate();
day = day < 10 ? ‘0’ + day : day;
alert(year + ‘-’ + month + ‘-’ + day);
-
- 有这样一个URL:http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,请写一段JS程序提取URL中的各个GET参数(参数名和参数个数不确定),将其按key-value形式返回到一个json结构中,如{a:’1′, b:’2′, c:”, d:’xxx’, e:undefined}
- function serilizeUrl(url) {
var urlObject = {};
if (/?/.test(url)) {
var urlString = url.substring(url.indexOf("?") + 1);
var urlArray = urlString.split("&");
for (var i = 0, len = urlArray.length; i < len; i++) {
var urlItem = urlArray[i];
var item = urlItem.split("=");
urlObject[item[0]] = item[1];
}
return urlObject;
}
return null;
}
-
- Javascript创建对象的几种方式?
- 1、var obj = {};(使用json创建对象)
如:obj.name = ‘张三’;
obj.action = function ()
{
alert(‘吃饭’);
}; - 2、var obj = new Object();(使用Object创建对象)
如:obj.name = ‘张三’;
obj.action = function ()
{
alert(‘吃饭’);
}; - 3、通过函数创建对象。
(1)、使用this关键字
如:var obj = function (){
this.name =‘张三’;
this.age = 19;
this.action = function ()
{
alert(‘吃饭’);
};
}
(2)、使用prototype关键字
如:function obj (){}
obj.prototype.name =‘张三’;
obj.prototype.action=function ()
{
alert(‘吃饭’);
}; - 4、通过Window创建对象。
如:window.name = '‘张三’;
window.age = 19;
window.action= function()
{
alert(‘吃饭’);
}; - 5、使用内置对象创建对象。
如:var str = new String(“实例初始化String”);
var str1 = “直接赋值的String”;
var func = new Function(“x”,“alert(x)”);//示例初始化func
var obj = new Object();//示例初始化一个Object
七、数组
-
- 判断一个对象是否为数组:var obj=[1,2,3];
-
- 错误方法:typeof
-
- 判断爹
-
① 用__proto__获得对象的爹,然后再和数组的爹作比较
- obj.proto==Array.prototype
-
② 因为__proto__有可能被浏览器禁用,所以由等效的函数来“ Object.getPrototypeOf(obj) ”完成
- Object.getPrototypeOf(obj)==Array.prototype
-
③ 还有一个更直接的函数“ father.isPrototypeOf(child) ”
- Array.prototype.isPrototypeOf(obj)
-
- 判断妈妈
-
① 用父级元素的constructor属性
- obj.constructor==Array
-
② 用"child instanceof 妈妈"
- obj instanceof Array
-
③ 输出对象的DNA:内部隐藏属性class
-
Object.prototype.toString.call(obj)=="[object Array]"
-
if(typeof Array.isArray===“undefined”){
Array.isArray = function(arg){
return Object.prototype.toString.call(arg)==="[object Array]"
};
}- ECMA Script5中定义了新方法Array.isArray(),
-
-
- 数组去重:var arr=[1,9,3,1,5,6,4,8,2,3,5,7];
-
- 使用indexof
- var arr1=[];
for (var i=0;i<arr.length;i++){
// indexOf 返回元素所在数组的下标
if(arr1.indexOf(arr[i])==-1){
arr1.push(arr[i])
}
}
console.log(arr1)
-
- 利用ES6中的set去重
- function arr2(){
return Array.from(new Set(arr))
}
console.log(arr2(arr))
-
- 利用双层for循环嵌套
- for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]==arr[j]){
arr.splice(j,1);
j–;
}
}
}
console.log(arr)
-
4.利用sort
- function array(arr){
arr=arr.sort()
var arr4=[arr[0]];
for(var i=1;i<arr.length;i++){
if(arr[i]!==arr[i-1]){
arr4.push(arr[i])
}
}
return arr4
}
console.log(array(arr))
- function array(arr){
-
5.利用includes
- function array5(arr){
var arr5=[];
for(var i=0;i<arr.length;i++){
if(!arr5.includes(arr[i])){
arr5.push(arr[i])
}
}
return arr5;
}
console.log(array5(arr))
- function array5(arr){
-
- 利用reduce+includes
- function unique(arr){
return arr.reduce((prev,cur) => prev.includes(cur) ? prev : […prev,cur],[]);
}
console.log(unique(arr));
-
- 利用filter
- function unique1(arr) {
return arr.filter(function(item, index, arr) {
//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
return arr.indexOf(item, 0) === index;
});
}
console.log(unique1(arr))
-
- 用js实现随机选取10–100之间的10个数字,存入一个数组,并使用冒泡排序从小到大排序?
- var arr=[];
for(var i=0;i<10;i++){
arr[i]=Math.floor(Math.random()*90+10)
}
for(var j=1;j<arr.length;j++){
for(var k=0;k<arr.length-j;k++){
if(arr[k]>arr[k+1]){
arr[k]=[arr[k+1],arr[k+1]=arr[k]][0]
}
}
}
console.log(arr)
-
- var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];如何实现数组乱序?
- arr.sort(function () {
return Math.random() - 0.5;
});
-
- split() 、join() 的区别?
- 前者是切割成数组的形式,后者是将数组转换成字符串
-
- 数组方法pop() push() unshift() shift()
- push():尾部添加
- pop():尾部删除
- unshift():头部添加
- shift():头部删除
-
- call和apply的区别?
-
call方法
- 语法:call(thisObj,Object1,Object2…)
定义:调用一个对象的一个方法,以另一个对象替换当前对象。也就是改变当前的this指向的问题
说明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj
- 语法:call(thisObj,Object1,Object2…)
-
apply方法
- 语法:apply(thisObj,[argArray])
定义:应用某一对象的一个方法,用另一个对象替换当前对象。
说明: 如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数
- 语法:apply(thisObj,[argArray])
-
- 把两个数组合并,并删除第二个元素
- var array1 = [‘a’,‘b’,‘c’];
var bArray = [‘d’,‘e’,‘f’];
var cArray = array1.concat(bArray);
cArray.splice(1,1); // 在数组的第(参数1)个索引值开始,删除(参数2)个数组元素,返回剩余的含有数组值的数组
slice()
-
- 已知数组var stringArray = [“This”, “is”, “Baidu”, “Campus”],Alert出”This is Baidu Campus”
- alert(stringArray.join(“”))
-
- 已知有字符串foo=”get-element-by-id”,写一个function将其转化成驼峰表示法”getElementById”
- function combo(msg){
var arr=msg.split("-");
for(var i=1;i<arr.length;i++){
arr[i]=arr[i].charAt(0).toUpperCase()+arr[i].substr(1,arr[i].length-1);
}
msg=arr.join("");
return msg;
}
-
- var numberArray = [3,6,2,4,1,5];
1) 实现对该数组的倒排,输出[5,1,4,2,6,3]
- var numberArray = [3,6,2,4,1,5];
-
实现对该数组的降序排列,输出[6,5,4,3,2,1]
-
- numberArray.reverse( )
-
- numberArray.sort(function(a,b){return b-a})
-
-
- 阅读以下代码,请分析出结果:
var arr = new Array(1 ,3 ,5);
arr[4]=‘z’;
arr2 = arr.reverse();
arr3 = arr.concat(arr2);
alert(arr3);
- 弹出提示对话框:z,5,3,1,z,5,3,1
- 阅读以下代码,请分析出结果:
八、字符串
-
- 截取字符串abcdefg的efg
- alert(‘abcdefg’.substring(4));
-
- 判断一个字符串中出现次数最多的字符,统计这个次数,例如:“asdfssaaasasasasaa”
- var str = ‘asdfssaaasasasasaa’;
var json = {};
for (var i = 0; i < str.length; i++) {
if(!json[str.charAt(i)]){
json[str.charAt(i)] = 1;
}else{
json[str.charAt(i)]++;
}
};
var iMax = 0;
var iIndex = ‘’;
for(var i in json){
if(json[i]>iMax){
iMax = json[i];
iIndex = i;
}
}
console.log(‘出现次数最多的是:’+iIndex+‘出现’+iMax+‘次’);
结果如下:出现次数最多的是:a出现9次
九、DOM
-
- childNodes和children的区别?
-
childNodes 和 children 都是返回动态集合(live collection),不实际存储数据,每次访问集合,都是重新查找 DOM 树
- 优点:首次查找返回速度快
- 缺点:反复访问集合,会导致反复查找 DOM 树
-
遍历
- for(var i=0,len=children.length;i<len;i++){…}
-
区别
- childNodes 是标准属性,返回指定元素的子元素集合,包括 HTML 节点,所有属性、文本节点。可以通过 nodeType 判断是哪种类型的节点
- children 是非标准属性,返回指定元素的子元素集合。但是它只返回 HTML 节点,设置不返回文本节点。虽然不是标准的 DOM 属性,但是却得到几乎所有浏览器的支持
-
- 在实际使用中我们可以用()很方便的获得页面定义的HTML对象?
A. document.GetElementsByTagName
B. document.getElementByTagNames
C. document.getElementsById
D. document.getElementById
- 结果:D
- 在实际使用中我们可以用()很方便的获得页面定义的HTML对象?
-
- 下面关闭名为 mydiv的层的代码正确的是()?
A. document.getElementById(mydiv).style.display=“none”
B. document.getElementById(“mydiv”).style.display=none
C. document.getElementById(“mydiv”).style.display=“none”
D. document.getElementById(“mydiv”).style.display==“none”
- 结果:C
- 下面关闭名为 mydiv的层的代码正确的是()?
-
- table.children找不到tr?为什么?
......
- 因为html标准规定,<table>下必须先包含行分组,在行分组内,再包含<tr>。即使写HTML代码时,没有加行分组,直接用<table>包含<tr>,为了符合HTML标准规定,浏览器也会自动将所有<tr></tr>包含在一个<tbody>中 - 提示:今后只要写table,必须写行分组,然后在行分组中,再添加tr- <table> <tbody> <tr>...</tr><tr>...</tr></tbody>
-
- btnShoot.οnclick=function shoot1(){ … }
btnShoot.removeEventListener(“click”,shoot1)
结果报错: 说 shoot1 未定义,为什么?
- 解析:=function shoot1(){} 这是一种特殊的语法,称为函数签名。函数签名中的函数名shoot1,属于一种仅限于当前函数内才可使用的变量(类似于闭包),但绝不等同于全局变量。所以,在function shoot1(){}之外,使用shoot1,都是未定义
- 同时,即使改成function shoot1(){ … },btnShoot.οnclick=shoot1;也是错误的。因为DOM规定,使用onclick绑定的事件处理函数,不能用removeEventListener移除。只能重新赋值为null: .οnclick=null
- btnShoot.οnclick=function shoot1(){ … }
-
- 1这个1,到底是保存在哪里了?内存?网页上?
- 先写在程序中,1,再被浏览器解析到DOM树上,保存在对象属性中:span:{ nodeName: “SPAN”, innerHTML: “1” , parentNode: td, … }。最后,被浏览器画成界面,显示在网页中: 1
-
- 为什么把
- click me
- click me
- click me
- click me
-
- 已知ID的Input输入框,希望获取这个输入框的输入值,怎么做?(不使用第三方框架)
- document.getElementById(“ID”).value
- $(“#id”).val();
-
- 如何阻止事件冒泡和默认事件
-
阻止事件冒泡
- // IE9+,其他主流浏览器
// var event = event || window.event;
// event.stopPropagation();
// 火狐未实现
// window.event.cancelBubble = true;
// 不建议滥用,jq中可以同时阻止冒泡和默认事件
// return false;
// 兼容模式
// stopBubble(event);
function stopBubble(e) {
// 如果提供了事件对象,则这是一个非IE浏览器
if (e && e.stopPropagation){
// 因此它支持W3C的stopPropagation()方法
e.stopPropagation();
}else{
// 否则,我们需要使用IE的方式来取消事件冒泡
window.event.cancelBubble = true;
}
}
- // IE9+,其他主流浏览器
-
阻止默认事件
- // 全支持
// event.preventDefault();
// 该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。
// window.event.returnValue = false;
// 不建议滥用,jq中可以同时阻止冒泡和默认事件
// return false;
// 兼容
// stopDefault(event);
- // 全支持
-
- 希望获取到页面中所有的checkbox怎么做?(不使用第三方框架)
- var domList = document.getElementsByTagName(‘input’)
var checkBoxList = [];
var len = domList.length; //缓存到局部变量
while (len–) { //使用while的效率会比for循环更高
if (domList[len].type == ‘checkbox’) {
checkBoxList.push(domList[len]);
}
}
-
- 设置一个已知ID的DIV的html内容为 “ hello world ”,字体颜色设置为黑色(不使用第三方框架)
- var dom = document.getElementById(“ID”);
dom.innerHTML = “hello world”
dom.style.color = “#000”
-
- javaScript 的 DOM 节点操作创建、插入、删除、复制、查找?
-
- 创建节点、追加节点
-
- createElement(标签名) // 创建一个元素节点(具体的一个元素)
-
- createTextNode(节点文本内容) // 创建一个文本节点
-
- createDocumentFragment() // 创建一个 DOM 片段
-
- appendChild(节点) // 追加一个节点
-
- 插入节点
-
- appendChild(节点) // 也是一种插入节点的方式,还可以添加已经存在的元素,会将其元素从原来的位置移到新的位置
-
- insertBefore(a,b) // 意思是 a 节点会插入 b 节点的前面
-
- 删除、移除节点
- removeChild(节点) // 删除一个节点,用于移除删除一个参数(节点)。其返回的被移除的节点,被移除的节点仍在文档中,只是文档中已没有其位置了
-
- 复制节点
- cloneNode() // 用于复制节点, 接受一个布尔值参数, true 表示深复制(复制节点及其所有子节点), false 表示浅复制(复制节点本身,不复制子节点)
-
- 替换节点
- replaceChild(插入的节点,被替换的节点) // 用于替换节点,接受两个参数,第一参数是要插入的节点,第二个是要被替换的节点。返回的是被替换的节点
-
- 查找节点
-
- getElementsByTagName() // 通过标签名称
-
- getElementsByName() // 通过元素的 Name 属性的值
-
- getElementById() // 通过元素 Id,唯一性
-
- 当一个DOM节点被点击时候,我们希望能够执行一个函数,应该怎么做?
- 直接在DOM里绑定事件:
在JS里通过onclick绑定:xxx.onclick = test - 通过事件添加进行绑定:addEventListener(xxx, ‘click’, test)
-
- Javascript的事件流模型都有什么?
- “事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播
“事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的
“DOM事件流”:三个阶段:事件捕捉,目标阶段,事件冒泡
-
- 下面的JavaScript语句中,( )实现检索当前页面中的表单元素中的所有文本框,并将它们全部清空?
A. for(vari=0;i< form1.elements.length;i++) {
if(form1.elements.type==”text”)
form1.elements.value=”";
}
B. for(vari=0;i<document.forms.length;i++) {
if(forms[0].elements.type==”text”)
forms[0].elements.value=”";
}
C. if(document.form.elements.type==”text”)
form.elements.value=”";
D. for(vari=0;i<document.forms.length; i++){
for(var j=0;j<document.forms.elements.length; j++){
if(document.forms.elements[j].type==”text”)
document.forms.elements[j].value=”";
}
}
- 答案:D
- 下面的JavaScript语句中,( )实现检索当前页面中的表单元素中的所有文本框,并将它们全部清空?
-
- 要将页面的状态栏中显示“已经选中该文本框”,下列JavaScript语句正确的是( )
A. window.status=”已经选中该文本框”
B. document.status=”已经选中该文本框”
C. window.screen=”已经选中该文本框”
D. document.screen=”已经选中该文本框”
- 答案:A
- 要将页面的状态栏中显示“已经选中该文本框”,下列JavaScript语句正确的是( )
-
- 完成foo()函数的内容,要求能够弹出对话框提示当前选中的是第几个单选框
for(var i =0 ;i<rdo.length;i++){
if(rdo.checked){
alert(“您选择的是第”+(i+1)+”个单选框”);
}
}-
- 完成函数showImg(),要求能够动态根据下拉列表的选项变化,更新图片的显示
城市生活 都市早报 青山绿水- var str = oSel.value;
document.getElementById(“pic”).src= str+”.jpg”;
-
- 简述列举文档对象模型DOM里document的常用的查找访问节点的方法并做简单说明
- Document.getElementById 根据元素id查找元素
Document.getElementByName 根据元素name查找元素
Document.getElementTagName 根据指定的元素名查找元素
-
- 希望获取到页面中所有的checkbox怎么做?(不使用第三方框架)
- var domList = document.getElementsByTagName(‘input’)
var checkBoxList = [];
var len = domList.length; //缓存到局部变量
while (len–) { //使用while的效率会比for循环更高
if (domList[len].type == ‘checkbox’) {
checkBoxList.push(domList[len]);
}
}
十、BOM
-
- 写出程序运行的结果?
for(var i=0;i<3;i++){
setTimeout(function(){
console.log(i)
},0)
console.log(i)
}
- 结果:012333
- 写出程序运行的结果?
-
- 在下面的代码中,数字 1-4 会以什么顺序输出?为什么会这样输出?
(function() {
console.log(1);
setTimeout(function(){console.log(2)}, 1000);
setTimeout(function(){console.log(3)}, 0);
console.log(4);
})();
- 结果:1 4 3 2
- 解析:异步
- 在下面的代码中,数字 1-4 会以什么顺序输出?为什么会这样输出?
-
- 看下面代码,给出输出结果:
for(var i=1;i<=3;i++){
setTimeout(function(){
console.log(i);
},0);
};
- 结果:4 4 4
- 解析:Javascript事件处理器在线程空闲之前不会运行
- 看下面代码,给出输出结果:
-
- 列举浏览器对象模型BOM里常用的至少4个对象,并列举window对象的常用方法至少5个
- 对象:window / document / location / screen / history / navigator
- 方法:alert() / confirm() / prompt() / open() / close()
-
- 读程序,写结果
for(var i=1;i<=3;i++){
setTimeout((function(a){
console.log(a);
})(i),0);
};
- 结果:1 2 3
- 读程序,写结果
十一、oop
-
- 面向对象与面向过程
-
- 面向对象
-
- 面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为
-
- 面向对象(Object Oriented Programming)是当前计算机界关心的重点,它是90年代软件开发方法的主流。面向对象的概念和应用已超越了程序设计和软件开发,扩展到很宽的范围。如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域
-
- 面向过程
-
- 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了
-
- 面向过程(Process-oriented programming)是一种以过程为中心的编程思想。“ 面向过程 ” 也可称之为 “ 面向记录 ” 编程思想,他们不支持丰富的 “ 面向对象 ” 特性(比如继承、多态),并且它们不允许混合持久化状态和域逻辑
-
- 面向过程(pop)和面向对象(oop)是什么?
-
- pop(Process-oriented programming)的缩写, “ 面向过程 ” 是一种是事件为中心的编程思想。就是分析出解决问题所需的步骤,然后用函数把这写步骤实现,并按顺序调用
-
- oop(Object Oriented Programming)的缩写面向对象:用线性的思维。与面向过程相辅相成。在软件开发过程中,宏观上,用面向对象来把握事物间复杂的关系,分析系统。微观上,仍然使用面向过程。” 面向对象 “ 是以 “ 对象 ” 为中心的编程思想
-
- 面向过程总结
-
- 面向过程是一种自顶向下的编程
-
- 面向过程优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;比如单片机、嵌入式开发、 Linux/Unix等一般采用面向过程开发,性能是最重要的因素
-
- 缺点:没有面向对象易维护、易复用、易扩展
-
- 面向对象总结
-
- 面向对象是将事物高度抽象化。面向对象必须先建立抽象模型,之后直接使用模型就行了
-
- 优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统 更加灵活、更加易于维护
-
- 缺点:性能比面向过程低
-
- 说说你对 this 的理解?
-
this 是一个关键字,它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用
-
- 作为纯粹的函数调用 this 指向全局对象
-
- 作为对象的方法调用 this 指向调用对象
-
- 作为构造函数被调用 this 指向新的对象(new 会改变 this 的指向)
-
- apply 调用 this 指向 apply 方法的第一个参数
-
-
- 读程序,写结果:
function A() {}
function B(a) {
this.a = a;
}
function C(a) {
if (a) {
this.a = a;
}
}
A.prototype.a = 1;
B.prototype.a = 1;
C.prototype.a = 1;
console.log(new A().a);
console.log(new B().a);
console.log(new C(2).a);
- 结果:1 undefined 2
- 读程序,写结果:
-
- 读程序,写结果:
var x=20;
var a={
x:15,
fn:function(){
return function(){
return this.x
}
}
}
console.log(a.fn())
console.log((a.fn())())
console.log(a.fn()())
console.log(a.fn()() == (a.fn())())
console.log(a.fn().call(this))
console.log(a.fn().call(a))
-
- console.log(a.fn());
-
对象调用方法,返回了一个方法
- function() {return this.x}
-
- console.log((a.fn())());
-
a.fn()返回的是一个函数,()()这是自执行表达式。this -> window
- 20
-
- console.log(a.fn()());
-
a.fn()相当于在全局定义了一个函数,然后再自己调用执行。this -> window
- 20
-
- console.log(a.fn()() == (a.fn())());
- true
-
- console.log(a.fn().call(this));
-
这段代码在全局环境中执行,this -> window
- 20
-
- console.log(a.fn().call(a));
-
this -> a
- 15
- 读程序,写结果:
十二、ES5
-
- 编写程序,复制数组中的偶数元素放入到新数组中,var arr=[1,2,3,4,5,6,7,8,9,10]
- var arr2=arr.filter(function(elem){
return elem%2==0; //只有偶数元素值才能放入新数组中
})
console.log(arr2);
十三、ES6
-
- CMAScript6 怎么写class?
- class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return ‘(’+this.x+’, ‘+this.y+’)’;
}
}
-
- 看程序,写结果:
const promise=new Promise((resolve,reject)=>{
console.log(1)
resolve()
console.log(2)
})
promise.then(()=>{
console.log(3)
})
console.log(4)
- 结果:1 2 4 3
- 解析:Promise构造函数是同步执行的,但是promise.then中的函数是异步执行的
- 看程序,写结果:
-
- 看程序,写结果:
const promise = new Promise((resolve, reject) => {
resolve(‘success1’)
reject(‘error’)
resolve(‘success2’)
})
promise.then((res) => {
console.log('then: ', res)
}).catch((err) => {
console.log('catch: ', err)
})
- 结果:then: success1
- 解析:构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用,呼应代码二结论:promise 状态一旦改变则不能再变
- 看程序,写结果:
-
- 将多维数组转换成一维数组
例如:let arr = [1,2,3,[4,5,6]]转化为[1,2,3,4,5,6]
- a. 利用apply将参数内的数组转化为参数列表展开(将[1,2,3,[4,5,6]转为参数1,2,3,4,5,6),然后拼接
console.log([].concat.apply([],arr)) - b. 利用…拓展运算符将数组展开,拼接
console.log([].concat(…arr)) - c. 利用flat及flatMap方法,用于将二维或者多维数组拉平成一维数组。如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数
console.log(arr.flat(Infinity))
- 将多维数组转换成一维数组
十二、正则
-
- 将字符串”{KaTeX parse error: Expected 'EOF', got '}' at position 3: id}̲</td><td>{name}”中的{KaTeX parse error: Expected 'EOF', got '}' at position 3: id}̲替换成10,{name}替换成Tony (使用正则表达式)
- “{KaTeX parse error: Expected 'EOF', got '}' at position 3: id}̲</td><td>{id}_{$name}”.replace(/ {$id} /g, ‘10’).replace( / {$name} /g, ‘Tony’);
- 在正则表带式中的直接量的形式:/要匹配的字符串/,/^ 严格模式 $/,/ /g默认在全局下找到所有匹配该字符串的 replace替换匹配到的字符串特殊符号用 \ 转义
-
- 为了保证页面输出安全,我们经常需要对一些特殊的字符进行转义,请写一个函数escapeHtml,将<, >, &, “进行转义
- function escapeHtml(str) {
return str.replace(/[<>”&]/g, function(match) {
switch (match) {
case “<”:
return “<”;
case “>”:
return “>”;
case “&”:
return “&”;
case “\””:
return “"”;
}
});
}
-
- 正则表达式构造函数var reg=new RegExp(“xxx”)与正则表达字面量var reg=//有什么不同?匹配邮箱的正则表达式?
- 当使用RegExp()构造函数的时候,不仅需要转义引号(即\”表示”),并且还需要双反斜杠(即\表示一个\)。使用正则表达字面量的效率更高
- 邮箱的正则匹配:
var regMail = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/;
-
- 写一个function,清除字符串前后的空格。(兼容所有浏览器)
- 使用自带接口trim(),考虑兼容性:
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^\s+/, “”).replace(/\s+$/,"");
}
}
// test the function
var str = " \t\n test string ".trim();
alert(str == “test string”); // alerts “true”
-
- 写出简单描述html标签(不带属性的开始标签和结束标签)的正则表达式,并将以下字符串中的html标签去除掉
var str = “这里是div”;里面的段落
- varreg = /</?\w+/?>/gi;
varstr = “这里是div”;里面的段落
alert(str.replace(reg,”"));
- 写出简单描述html标签(不带属性的开始标签和结束标签)的正则表达式,并将以下字符串中的html标签去除掉
十三、其他
-
- javascript 中的垃圾回收机制?
- 在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC(垃圾回收器)回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因(闭包)
-
- js特性不包括()?
A. 解释性
B. 用于客户端
C. 基于对象
D. 面向对象
-
结果:B
- JS特性:平台无关性
- js特性不包括()?
-
- HTML5中哪个方法用于获取用户当前位置()?
A. getPosition()
B. getCurrentPosition()
C. getUserPosition()
D. Positioin()
-
结果:C
- 解析:考察JS中命名规范
- HTML5中哪个方法用于获取用户当前位置()?
-
- JavaScript是一门什么样的语言,它有哪些特点?
-
javaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML网页上使用,用来给HTML网页增加动态功能。JavaScript兼容于ECMA标准,因此也称为ECMAScript
-
基本特点
-
- 是一种解释性脚本语言(代码不进行预编译)
-
- 主要用来向HTML(标准通用标记语言下的一个应用)页面添加交互行为
-
- 可以直接嵌入HTML页面,但写成单独的js文件有利于结构和行为的分离
-
- 跨平台特性,在绝大多数浏览器的支持下,可以在多种平台下运行(如Windows、Linux、Mac、Android、iOS等)
-
-
- javascript的同源策略?
- 一段脚本只能读取来自于同一来源的窗口和文档的属性,这里的同一来源指的是主机名、议和端口号的组合
-
- js延迟加载的方式有哪些?
-
- defer 和 async
-
- 动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)
-
- 按需异步载入js
-
- 一个页面上有大量的图片(大型电商网站),加载很慢,你有哪些方法优化这些图片的加载,给用户更好的体验?
-
- 图片懒加载,在页面上的未可视区域可以添加一个滚动条事件,判断图片位置与浏览器顶端的距离与页面的距离,如果前者小于后者,优先加载
-
- 如果为幻灯片、相册等,可以使用图片预加载技术,将当前展示图片的前一张和后一张优先下载
-
- 如果图片为 css 图片,可以使用 CSSsprite,SVGsprite,Iconfont、Base64 等技术
-
- 如果图片过大,可以使用特殊编码的图片,加载时会先加载一张压缩的特别厉害的缩略图,以提高用户体验
-
- 如果图片展示区域小于图片的真实大小,则因在服务器端根据业务需要先行进行图片压缩,图片压缩后大小与展示一致
-
- 哪些操作会造成内存泄漏?
-
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在
-
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收
-
包括
-
- setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏
-
- 闭包
-
- 控制台日志
-
- 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
-
五、Ajax
1. 封装ajax
-
function ajax({
url : url,
type : type,
data : data,
dataType : dataType
}){…}-
简写 =>
- function ajax({url,type,data,dataType}){…}
-
-
ajax({
url : “http://localhost:3000/users/sign”,
type : “post”,
data : “uname=dingding & upwd=123456”,
dataType : “json”
})-
调用结果,此时在函数中
- 形参url 获得 实参url 的值 “http://localhost:3000/users/sign”
- 形参type 获得 实参type 的值 “post”
- 形参data 获得 实参data 的值 “uname=dingding&upwd=123456”
- 形参dataType 获得 实参dataType 的值 “json”
-
2.什么情况下会遇到跨域,怎么解决?
3. 在浏览器中输入网址后的流程(三次挥手,四次握手)
-
第一步:浏览器向DNS服务器发起DNS查询请求(DNS查询)
-
在广域网中是基于IP地址进行通信的。但通常客户访问的是一个网址,为此需要先得到网址对应的IP地址,这就需要域名服务系统将域名转换成IP地址。在客户端浏览器中输入网址时,浏览器会根据本地客户端DNS服务器配置,向DNS服务器获取域名对应的IP地址
-
DNS 的查找过程
- 浏览器缓存->系统缓存->路由器缓存->ISP DNS缓存->递归搜索
- 递归搜索过程:从根域名服务器到顶级域名服务器到所查询的域名服务器
-
-
第二步:域名服务器向客户端返回查询结果域名,从而完成域名到IP地址的转换(DNS响应)
- 域名解析服务器是基于UDP协议实现的一个应用程序,通常通过监听53端口来获取客户端的域名解析请求
-
第三步:客户端向web服务器发送HTTP请求
-
客户端得到了域名对应的 IP 地址后,客户端便可向真正的web服务器发生HTTP请求。如果浏览器存储了该域名下的cookie,那么cookie也会放入http请求中
-
HTTP请求是一个基于TCP协议之上的应用层协议——超文本传输协议。浏览器通过DNS获取到web服务器真的IP地址后,便向Web服务器发起TCP连接请求,通过TCP三次握手建立好连接后,浏览器便可以将HTTP请求数据通过发送给服务器了
-
TCP三次握手连接
- 第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认
- 第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态
- 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手
-
注意:握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去
-
-
-
第四步:服务器给浏览器进行一个301永久重定向响应
- IP对应的服务器很可能是代理服务器,比如输入“http://baidu.com”,而不是“http://www.baidu.com”,这两个网址对应的是同一个网页,因此通过代理服务器的方式进行重定向响应,让这两个网址访问的同一个网页。 浏览器根据重定向地址再次进行HTTP请求
-
第五步:发送响应数据给客户端
- Web服务器通常通过监听80端口来获取客户端的HTTP请求。与客户端建立好TCP连接后,Web服务器开始接受客户端发来的数据,并通过HTTP解码,从接受到的网络数据中解析出请求的url信息以前其他诸如Accept-Encoding、Accept-Language等信息。Web服务器根据HTTP请求头的信息,得到响应数据返回给客户端。至此,一个HTTP通信过程完成。web服务器会根据HTTP请求头中的Connection字段值决定是否关闭TCP链接通道,当Connection字段值为keep-alive时,web服务器不会立即关闭此连接
-
第六步:浏览器响应过程
-
浏览器收到响应内容之后,生成主页框架,同时向服务端继续发送请求,请求的内容是主页里的一些资源,比如说图片、视频等。 对于静态的页面内容,浏览器通常进行缓存,对于动态的内容通常不缓存,缓存的时间也是有期限的。浏览器向服务器发送异步请求,因为有些页面显示完成之后客户端仍需要与服务端保持联系。整个过程结束之后,浏览器关闭TCP连接
-
TCP 四次挥手断开连接
- 假设Client端发起中断连接请求,即发送FIN报文。Server端接到FIN报文后,意思是说"Client端没有数据要发送了",但是如果Server端还有数据没有发送完成,则不必急着关闭Socket,可以继续发送数据。所以Server端先发送ACK,告诉Client端"请求已经收到,但是Server端还没准备好,请继续等待消息"。这个时候Client端进入FIN_WAIT状态,继续等待Server端的FIN报文。当Server端确定数据已发送完成,则向Client端发送FIN报文,告诉Client端"数据发送完成,准备好关闭连接"。Client端收到FIN报文后知道可以断开连接,但是怕Server端不知道要关闭,所以发送ACK后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。Server端收到ACK后断开连接。Client端等待了2MSL后依然没有收到回复,则证明Server端已正常关闭,则自身关闭连接
-
-
https和http区别,有没有用过其它安全的传输手段?
六、HTML5
1. 请你谈谈Cookie的弊端?
- 1.Cookie数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
- 2.安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
- 3.有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
七、jQuery
1. 一个ajax的请求?
- $.ajax({
url: ‘data1.json’,
type: ‘GET’,
success: function (res) {
console.log(res) // 请求成功,则得到结果res
},
error: function(err) {
console.log(err)
}
})
2. 多个ajax的请求(当得到的数据 res 需要用于另一个 ajax 请求时)?
-
$.ajax({
url: ‘data1.json’,
type: ‘GET’,
success: function (res) {
$.ajax({
url: res.url, // 将 第一个ajax请求成功得到的res 用于第二个ajax请求
type: ‘GET’,
success: function (res) {
$.ajax({
url: res.url, // 将第二个ajax请求成功得到的res 用于第三个ajax请求
type: ‘GET’,
success: function (res) {
console.log(res) // {url: “this is data3.json”}
},
error: function(err) {
console.log(err)
}
})
},
error: function(err) {
console.log(err)
}
})
},
error: function(err) {
console.log(err)
}
})- 出现多个回调函数的嵌套,可读性较差
-
使用promise链式操作
- function ajaxGet (url) {
return new Promise(function (resolve, reject) {
$.ajax({
url: url,
type: ‘GET’,
success: function (res) {
resolve(res);
},
error: function(err) {
reject(‘请求失败’);
}
})
})
};
- function ajaxGet (url) {
ajaxGet(‘data1.json’).then((d) => {
console.log(d); // {url: “data2.json”}
return ajaxGet(d.url);
}).then((d) => {
console.log(d); // {url: “data3.json”}
return ajaxGet(d.url);
}).then((d) => {
console.log(d); // {url: “this is data3.json”}
})-
使用async/await方法
-
执行一个ajax请求
- function ajaxGet (url) {
return new Promise(function (resolve, reject) {
$.ajax({
url: url,
type: ‘GET’,
success: function (res) {
resolve(res)
},
error: function(err) {
reject(‘请求失败’)
}
})
})
};
- function ajaxGet (url) {
-
async function getDate() {
console.log(‘开始’)
let result1 = await ajaxGet(‘data1.json’);
console.log('result1 —> ', result1); // result1 —> {url: “data2.json”}
};
getDate(); // 需要执行异步函数- 执行多个ajax请求- function ajaxGet (url) {
return new Promise(function (resolve, reject) {
$.ajax({
url: url,
type: ‘GET’,
success: function (res) {
resolve(res)
},
error: function(err) {
reject(‘请求失败’)
}
})
})
};async function getDate() {
console.log(‘开始’)
let result1 = await ajaxGet(‘data1.json’);
let result2 = await ajaxGet(result1.url);
let result3 = await ajaxGet(result2.url);
console.log('result1 —> ', result1); // result1 —> {url: “data2.json”}
console.log('result2 —> ', result2); // result2 —> {url: “data3.json”}
console.log('result3 —> ', result3); // result3 —> {url: “this is data3.json”}
};getDate(); // 需要执行异步函数
-
使用try…catch捕捉错误
- function ajaxGet (url) {
return new Promise(function (resolve, reject) {
$.ajax({
url: url111, // 此处为错误的 url
type: ‘GET’,
success: function (res) {
resolve(res)
},
error: function(err) {
reject(‘请求失败’)
}
})
})
};
- function ajaxGet (url) {
async function getDate() {
console.log(‘开始’)
try {
let result1 = await ajaxGet(‘data1.json’); // 执行到这里报错,直接跳至下面 catch() 语句
let result2 = await ajaxGet(result1.url);
let result3 = await ajaxGet(result2.url);
console.log('result1 —> ', result1);
console.log('result2 —> ', result2);
console.log('result3 —> ', result3);} catch(err) {
console.log(err) // ReferenceError: url111 is not defined
}
};getDate(); // 需要执行异步函数
3. 以下不正确的jquery表示方式是()?
A. $(this).hide()
B. $("*p")
C. $(".test").hide()
D. $("#test").hide()59. window.onload 和document.ready的区别?
- 引入js文件的两种方式:一种原生的 一种是jQuery库的入口函数
window.onload 是在dom文档树加载完和所有文件加载完之后执行一个函数Document.ready原生种没有这个方法,jquery中有 $(document).ready(function(){代码}),在dom文档树加载完之后执行一个函数(注意,这里面的文档树加载完不代表全部文件加载完)。
( d o c u m e n t ) . r e a d y 要 比 w i n d o w . o n l o a d 先 执 行 , 执 行 的 上 下 文 不 同 , w i n d o w . o n l o a d 只 能 出 来 一 次 , (document).ready要比window.onload先执行,执行的上下文不同, window.onload只能出来一次, (document).ready要比window.onload先执行,执行的上下文不同,window.onload只能出来一次,(document).ready可以出现多次
八、vue
1. 什么是MVVM?
- MVVM 是 Model-View-ViewModel 的缩写。MVVM 是一种设计思想。Model 层代表数据模型,也可以在 Model 中定义数据修改和操作的业务逻辑;View 代表 UI 组件,它负责将数据模型转化成 UI 展现出来,ViewModel 是一个同步 View 和 Model 的对象
在 MVVM 架构下,View 和 Model 之间并没有直接的联系,而是通过 ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此 View 数据的变化会同步到 Model 中,而 Model 数据的变化也会立即反应到 View 上
ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而 View 和
Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作 DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由MVVM 来统一管理2. 什么是MVC?
- MVC是 Model-View- Controller 的简写。即模型-视图-控制器。MVC中的M和V的意思和MVVM中的M和V指的意思一样。C即Controller指的是页面业务逻辑。使用MVC的目的就是将模型和视图的代码分离。MVC是单向通信。也就是View和Model必须通过Controller来承上启下。MVC和MVVM的区别并不是VM取代了C,ViewModel存在的目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作操作业务等还是应该放在Contronller中实现。也就是说MVVM实现的是业务逻辑组件的重用。由于MVC出现的时间比较早,前端并不那么成熟,很多业务逻辑也是在后端实现,所以前端并没有真正意义上的MVC模式
3. MVVM 和 MVC 的区别?
- mvc 和 mvvm 其实区别并不大。都是一种设计思想。主要就是 mvc 中 Controller 演变成 mvvm 中的 viewModel。mvvm 主要解决了 mvc 中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验
4. vue常见错误: Error compiling template?
- 说明HTML界面中某处写错了。一旦出错,找错误提示中一个 " - “,” - " 出现的位置就是出错的那句话和错误原因
5. v-show 和 v-if 指令的共同点和不同点?
- v-show 指令是通过修改元素的 display 的 CSS 属性让其显示或者隐藏
- v-if 指令是直接销毁和重建 DOM 达到让元素显示和隐藏的效果
6. 被 v-if 和 v-else 删除的DOM元素,怎么还能显示回来呢?
- Vue中显示哪个元素,不显示哪个元素,全由虚拟DOM树控制。标有v-if或v-else的元素,虽然被从界面上删除了。但是,在new Vue()首次扫描时,已经将v-if和v-else所在的元素添加了虚拟DOM树中永久保存。当v-if依赖的变量发生变化时,依然可以根据虚拟DOM树中保存的原始的v-if和v-else的元素对象信息,重新生成真实DOM树中的节点,显示到页面上
7. v-for为什么一定要加key?
-
如果不加:key=“i”,v-for生成的多个元素之间,除了内容之外,没有任何差别。如果数组中的某个元素需要更新,就无法精准的更新某一个元素,而必须将整个v-for重新执行一遍,效率极其低。如果给每个生成的元素都添加一个:key=“i”,当一个元素发生改变时,vue只需要根据key属性的值,找到要更新的一个元素即可,不用将整个v-for重新执行一遍,效率高
-
面试说法
- 因为 vue 在更新渲染 dom 的时候是根据新旧 dom 数进行对比的,使用 key 来给每个节点做一个唯一标识,Diff 算法就可以正确的识别此节点,找到正确的位置区插入新的节点
8. 每次修改数组元素时,v-for因为无法区分每个HTML元素副本,所以被迫删掉整个列表,创建整个列表?
- <元素 v-for="(当前元素值, 当前位置) of 数组" :key=“当前位置”>
- 绑定一个:key,:key是在内存中为每个HTML元素副本添加一个唯一标识。如果每个HTML元素副本都有唯一标识,则每次修改数组元素时,v-for只需要找到受影响的那一个HTML元素副本,修改即可。其余不受影响的HTML元素副本保持不变——效率高
9. 简单说一下 vue 的双向绑定原理?
- vue 双向数据绑定的原理主要通过数据劫持 Object.defineProperty 和 发布订阅模式 实现的,通过 Object.defineProperty 监听数据发生变化然后通知订阅者(watcher),订阅者触发响应的回调
- vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。
10. 说出至少 4 种 vue 当中的指令和它的用法?
- v-if:判断是否隐藏
- v-for:数据循环
- v-bind:class:绑定一个属性
- v-model:实现双向绑定
11. 为什么避免 v-if 和 v-for 用在一起?
- 当 Vue 处理指令时,v-for 比 v-if 具有更高的优先级,通过 v-if 移
动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,我们只检查它一次,且不会在 v-if 为否的时候运算 v-for
12. 虚拟 DOM 是什么?
- “虚拟 DOM”是由 Vue 组件树建立起来的整个 VNode 树的称呼
13. VNode 是什么?
- Vue 在 页面上渲染的节点,及其子节点称为“虚拟节点 (Virtual Node)”,简写为“VNode”
14. Vue 是什么?
- vue.js 是一套构建用户界面的渐进式框架,与其他重量级框架不同的是,Vue 采用自底向上增量开发的设计。Vue 的核心库只关注视图层,它不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与单文件组件和 Vue 生态系统支持的库结合使用时,Vue 也完全能够为复杂的单页应用程序提供驱动
15. Vue.js 核心思想?
-
- 数据驱动(基于操作 dom 的方式)
-
- Dom 是数据的一种自然映射(双向数据绑定),手动改变 DOM 非常麻烦,使用vue.js 之后,只需要改变数据,通过改变 Directives 指令,当数据发生变化,会通过数据指令去修改对应的 DOM
-
- Vue.js 还会对事件进行一定的监听,当我们改变视图(view)的时候通过 DOM Listeners 来改变数据
- 通过以上两点就实现了数据的双向绑定
-
- 组件化
- Vue-cli:(它是 vue 的脚手架工具)
- 作用:帮助我们完成基础的代码(包括:目录结构、本地调试、代码部署、热加载、单元测试)
- 组件的设计原则:页面上每一个独立的可视/可交互区域视为一个组件,每个组件对应一个工程目录,组件所需要的各种资源在这个目录下就近维护,展示面不过是组件的容器,组件可以嵌套自由组合形成完整的页面
16. vue 首屏加载过慢如何解决?
-
- 路由懒加载,会将原来打包一个 app.js 的文件打包成多个文件
-
- 异步组件,按需加载
-
- 组件异步加载,将子组件
-
- webpack 开启 gzip 压缩
-
- 如果图片过多,开启图片懒加载
-
- 使用 cdn 资源
-
- 如果首页是登录页,做多入口
17. 请列举出 3 个 Vue 中常用的生命周期钩子函数?(举两例)
- created: 实例已经创建完成之后调用,在这一步,实例已经完成数据观测, 属性和方法的运算, watch/event 事件回调. 然而, 挂载阶段还没有开始, $el 属性目前还不可见
- mounted: el 被新创建的 vm. e l 替 换 , 并 挂 载 到 实 例 上 去 之 后 调 用 该 钩 子 。 如 果 r o o t 实 例 挂 载 了 一 个 文 档 内 元 素 , 当 m o u n t e d 被 调 用 时 v m . el 替换,并挂载到实例上去之后调用该钩子。如果root 实例挂载了一个文档内元素,当 mounted 被调用时 vm. el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内元素,当mounted被调用时vm.el 也在文档内
18. Vue的适用场景?
- 对浏览器兼容要求不高,vuejs 是到 IE9
- 对 MVVM 有一定的经验
- 加载速度要求高
- 对性能要求比较高
- 需要组件化开发
- 喜欢对原生 js 对象操作
- SPA
19. React 和 Vue 的区别?
-
React 和 Vue 的相似之处
-
- 使用 Virtual DOM
-
- 提供了响应式(Reactive)和组件化(Composable)的视图组件
-
- 将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库
-
-
Vue 与 Angular、React 的对比
-
- vue.js 更轻量,gzip 后只有 20K+,angular:56K ,react:44K
-
- vue.js 更易上手,学习曲线平稳
-
- 吸收两家之长,有 angular 的指令和 react 组件化思想
-
-
优点
- 体积小。接口灵活。侵入性好,可用于页面的一部分,而不是整个页面。扩展性好。源码规范简洁。代码较为活跃,作者是中国人。基于组件化的开发。它是一个轻量级 mvvm 框架、数据驱动+组件化的前端开发、社区完善
-
缺点
- 社区不大,如果有问题可以读源码。功能仅限于 view 层,Ajax 等功能需要额外的库。对开发人员要求较高。开发的话,需要 webpack,不然很难用,最好配合 es6。
20. MVVM 和 jquery 的区别?
- vue 数据驱动,通过数据来显示视图层而不是节点操作
- jQuery 是一个快速、简洁的 JavaScript 框架 , jQuery 是基于事件驱动
21. Vue 的优点是什么?
-
- 低耦合,视图(View)可以独立于 Model 变化和修改,一个 ViewModel 可以绑定到不同的"View"上,当 View 变化的时候 Model 可以不变,当 Model 变化的时候View 也可以不变
-
- 可重用性,你可以把一些视图逻辑放在一个 ViewModel 里面,让很多 view 重用这段视图逻辑
-
- 独立开发,开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计
-
- 可测试,界面素来是比较难于测试的,而现在测试可以针对 ViewModel 来写
22. Vue 组件之间的传值?
-
- 父组件往子组件传值 props
-
- 子组件往父组件传值,通过 emit 事件
-
- 不同组件之间传值,通过 eventBus(小项目少页面用 eventBus,大项目多页面使用 vuex)
23. Vue 路由之间跳转有哪些?
-
- 声明式(标签跳转)
-
- 编程式( js 跳转)
- router.push(‘index’)
24. vue-cli 怎样使用自定义组件? 遇到过哪些问题?
- 第一步:在 components 目录新建你的组件文件(indexPage.vue),script 一定要 export default {}
- 第二步:在需要用的页面(组件)中导入:import indexPage from ‘@/components/indexPage.vue’
- 第三步:注入到 vue 的子组件的 components 属性上面,components:{indexPage}
- 第四步:在 template 视图 view 中使用,例如有 indexPage 命名,使用的时候则 index-page
25. vue 如何实现按需加载配合 webpack 设置?
- webpack 中提供了 require.ensure()来实现按需加载。以前引入路由是通过 import 这样的方式引入,改为 const 定义的方式进行引入
- 不进行页面按需加载引入方式 import home from …/…/common/home.vue’
- 进行页面按需加载的引入方式:const home = r => require.ensure( [], () => r (require(’…/…/common/home.vue’)))
26. vuex 是什么?怎么使用?哪种功能场景使用它?
- vuex 是 vue 框架中状态管理
- 使用方式: 在 main.js 引入 store,注入。新建一个目录 store,…… export
- 场景有:单页应用中,组件之间的状态。音乐播放、登录状态、加入购物车
27. vuex 有哪几种属性?
-
有五种,分别是 State、 Getter、Mutation 、Action、 Module
-
vuex 的 State 特性
- A. Vuex 就是一个仓库,仓库里面放了很多对象。其中 state 就是数据源存放地,对应于一般 Vue 对象里面的 data
- B. state 里面存放的数据是响应式的,Vue 组件从 store 中读取数据,若是 store 中的数据发生改变,依赖这个数据的组件也会发生更新
- C. 它通过 mapState 把全局的 state 和 getters 映射到当前组件的computed 计算属性中
-
vuex 的 Getter 特性
- A. getters 可以对 State 进行计算操作,它就是 Store 的计算属性
- B. 虽然在组件内也可以做计算属性,但是 getters 可以在多组件之间复用
- C. 如果一个状态只在一个组件内使用,是可以不用 getters
-
vuex 的 Mutation 特性
- Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态;Action 可以包含任意异步操作
-
vuex 的 Action 特性
- 包含任意异步操作,通过提交 mutation 间接更变状态
-
vuex 的 Module 特性
- 将 store 分割成模块,每个模块都具有 state、mutation、action、getter、甚至是嵌套子模块
28. 不用 Vuex 会带来什么问题?
-
- 可维护性会下降,想修改数据要维护三个地方
-
- 可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的
-
- 增加耦合,大量的上传派发,会让耦合性大大增加,本来 Vue 用 Component 就是为了减少耦合,现在这么用,和组件化的初衷相背
29. 如何让 CSS 只在当前组件中起作用?
- 将当前组件的
30. 的作用是什么?
- 包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态或避免重新渲染
31. Vue 中引入组件的步骤?
-
- 采用 ES6 的 import … from …语法或 CommonJS 的 require()方法引入组件
-
- 对组件进行注册
- Vue.component(“my-component”,{
template:`
my name is template!
})
-
- 使用组件
32. 指令 v-el 的作用是什么?
- 提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标,可以是 CSS 选择器,也可以是一个 HTMLElement 实例,vue2.0 当中改为 ref 属性
33. 在 Vue 中使用插件的步骤?
-
- 采用 ES6 的 import … from …语法或 CommonJS 的 require()方法引入插件
-
- 使用全局方法 Vue.use( plugin )使用插件,可以传入一个选项对象 Vue.use(MyPlugin, { someOption: true })
34. active-class 是哪个组件的属性?
- vue-router 模块的 router-link 组件
35. 怎么定义 vue-router 的动态路由以及如何获取传过来的动态参数?
-
- 在 router 目录下的 index.js 文件中,对 path 属性加上/:id
-
- 使用 router 对象的 params.id
36. vue-router 有哪几种导航钩子?
-
- 全局导航钩子:router.beforeEach(to,from,next)
- 作用:跳转前进行判断拦
-
- 组件内的钩子
-
- 单独路由独享组件
37. vue 生命周期?
-
Vue 生命周期总共分为 8 个阶段:创建前/后,载入前/后,更新前/后,销毁前/后
- 创建前/后: 在 beforeCreate 阶段,vue 实例的挂载元素 el 和数据对象 data 都为 undefined,还未初始化。在 created 阶段,vue 实例的数据对象 data 有了,el 还没有
- 载入前/后:在 beforeMount 阶段,vue 实例的$el 和 data 都初始化了,但还是挂载之前为虚拟的 dom 节点,data.message 还未替换。在mounted 阶段,vue 实例挂载完成,data.message 成功渲染
- 更新前/后:当 data 变化时,会触发 beforeUpdate 和 updated 方法
- 销毁前/后:在执行 destroy 方法后,对 data 的改变不会再触发周期函数,说明此时 vue 实例已经解除了事件监听以及和 dom 的绑定,但是dom 结构依然存在
38. 什么是 vue 生命周期?
- Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载 Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期
39. vue 生命周期的作用是什么?
- 它的生命周期中有多个事件钩子,让我们在控制整个 Vue 实例的过程时更容易形成好的逻辑
40. 第一次页面加载会触发哪几个钩子?
- 第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
41. DOM 渲染在 哪个周期中就已经完成?
- DOM 渲染在 mounted 中就已经完成了
42. 简单描述每个周期具体适合哪些场景?
- beforecreate : 可以在这加个 loading 事件,在加载实例时触发
- created : 初始化完成时的事件写在这里,如在这结束 loading 事件,异步请求也适宜在这里调用
- mounted : 挂载元素,获取到 DOM 节点
- updated : 如果对数据统一处理,在这里写上相应函数
- beforeDestroy : 可以做一个确认停止事件的确认框
43. vue-loader 是什么?使用它的用途有哪些?
- vue-loader 是解析.vue 文件的一个加载器
- 用途:js 可以写 es6、style 样式可以 scss 或 less、template 可以加 jade 等
44. scss 是什么?
- css 的预编译
45. scss 在 vue-cli 中的安装使用步骤是?
- 第一步:先装 css-loader、node-loader、sass-loader 等加载器模块
- 第二步:在 build 目录找到 webpack.base.config.js,在那个 extends 属性中加一个拓展.scss
- 第三步:在同一个文件,配置一个 module 属性
- 第四步:然后在组件的 style 标签加上 lang 属性 ,例如:lang=”scss”
46. scss 有哪几大特性?
-
- 可以用变量,例如($变量名称=值)
-
- 可以用混合器,例如()
-
- 可以嵌套
47. vue 中利用索引修改数组的时候,页面会跟着同步吗?
- 利用索引修改数组的时候,页面不会进行同步,此时应该利用 vue.set 的方法进行设置数据
48. 路由中如何去除 url 上的‘#’?
- 路由有两种模式,一种为 hash 模式,另一种为 history 模式,开启 history 模式后自动去除#,开启 history 模式需要后台配合
49. vue 中的单项数据流和双向数据绑定是什意思?
- 单项数据流是指数据是单向的,父组件的数据传递给子组件,只能单项绑定,不可以在子组件修改父组件的数据
- 双向数据绑定:是指数据和页面进行双向绑定,相互影响
50. 为什么 vue 组件中的 data 必须是函数?
- 因为如果默认为 data 是对象的话,对象为引用类型,这样的话,所有复用的组件都是引用的同一个数据,但是如果是函数的话,每次函数都会先创建一个新的数据,从而使每个组件的数据独立
51. 你知道 webpack 中 babel、plugin、loader 都有什么作用吗?
-
- babel 用来出来 es6 转 es5
-
- plugin 配置 webpack 的一些插件
-
- loader 用来配置解析处理第三方文件的
52. $route 和 router 的区别?
- $route : 包括 path,params,hash,query,fullPath,matched,name 等路由信息参数
- $router: 是路由的跳转方法,钩子函数等
九、Axios
1. axios 是什么?
-
- Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库
-
- react/vue 官方都推荐使用 axios 发 ajax 请求
2. axios 特点?
-
- 基于 promise 的异步 ajax 请求库,支持promise所有的API
-
- 浏览器端/node 端都可以使用,浏览器中创建XMLHttpRequests
-
- 支持请求/响应拦截器
-
- 支持请求取消
-
- 可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
-
- 批量发送多个请求
-
- 安全性更高,客户端支持防御 XSRF,就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略
3. axios 常用语法?
-
axios(config)
- 通用/最本质的发任意类型请求的方式
-
axios(url[, config])
- 指定 url 只发 get 请求
-
axios.request(config)
- 等同于 axios(config)
-
axios.get(url[, config])
- 发 get 请求,主要用于列表和信息和查询
-
axios.delete(url[, config])
- 发 delete 请求,用于删除
-
axios.post(url[, data, config])
- 发 post 请求,用于信息的添加
-
axios.put(url[, data, config])
- 发 put 请求,执行更新操作
-
axios.defaults.xxx: 请求的默认全局配置
-
axios.interceptors.request.use(): 添加请求拦截器
-
axios.interceptors.response.use(): 添加响应拦截器
-
axios.create([config]): 创建一个新的 axios(它没有下面的功能)
-
axios.Cancel(): 用于创建取消请求的错误对象
-
axios.CancelToken(): 用于创建取消请求的 token 对象
-
axios.isCancel(): 是否是一个取消请求的错误
-
axios.all(promises): 用于批量执行多个异步请求
-
axios.spread(): 用来指定接收所有成功数据的回调函数的方法
4. 说下你了解的axios相关配置属性?
-
url
是用于请求的服务器URL -
method
是创建请求时使用的方法,默认是get -
baseURL
将自动加在url
前面,除非url
是一个绝对URL。它可以通过设置一个baseURL
便于为axios实例的方法传递相对URL -
transformRequest
允许在向服务器发送前,修改请求数据,只能用在’PUT’,'POST’和’PATCH’这几个请求方法 -
headers
是即将被发送的自定义请求头- headers:{‘X-Requested-With’:‘XMLHttpRequest’}
-
params
是即将与请求一起发送的URL参数,必须是一个无格式对象(plainobject)或URLSearchParams对象- params:{
ID:12345
},
- params:{
-
auth
表示应该使用HTTP基础验证,并提供凭据- 这将设置一个
Authorization
头,覆写掉现有的任意使用headers
设置的自定义Authorization
头 - auth:{
username:‘janedoe’,
password:‘s00pers3cret’
},
- 这将设置一个
-
'proxy’定义代理服务器的主机名称和端口
- 这将会设置一个
Proxy-Authorization
头,覆写掉已有的通过使用header
设置的自定义Proxy-Authorization
头 - proxy:{
host:‘127.0.0.1’,
port:9000,
auth:{
username:‘mikeymike’,
password:‘rapunz3l’
}
}
- 这将会设置一个
十、node
1. 跨域问题
-
- cors
-
- 解析
-
- CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)
-
- 跨域资源共享( CORS )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。浏览器支持在 API 容器中(例如 XMLHttpRequest 或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险
-
- 可以发任意请求,但要求服务器必须给出特定的响应头,仅适用于服务器代码可修改的情形
-
- 预检请求
-
-
cors将请求场景分为 简单请求 和 非简单请求
-
- 简单请求
-
- 使用的方法是GET,HEAD,POST这三种之一
-
- Content-Type 的值是text/plain、 multipart/form-data、 application/x-www-form-urlencoded 这三种之一
-
- 非简单请求
-
- 浏览器检测到该请求非简单请求,会先发送一个预检请求到服务器,以获知服务器是否允许该实际请求
-
- 服务器会从预检请求拿到的以下3个信息去和服务器的Response的header对比,来决定是否允许该请求
- Access-Control-Request-Method :实际请求的方法
- Access-Control-Request-Headers:实际请求所携带的请求header字段
- origin:实际请求的源站,域名
-
-
-
- 服务器header使用字段
-
- Access-Control-Allow-Origin
-
- 必填字段,值:一个域名, *(表示接受任意域名的请求),也可以读取请求headers中的origin字段
-
- 如果请求的源与该字段不符合服务器会返回一个正常的HTTP回应,状态码可能为200,但不会包含Access-Control-开头的Origin、Credentials、Headers3个字段,浏览器发现,回应的头信息没有包含Access-Control-Allow-Origin字段就会抛出一个错误,会被XMLHttpRequest的onerror回调函数捕获
-
- Access-Control-Request-Method
-
- 可选字段,表明服务器支持的所有跨域请求的方法
-
- 如果你用到除了HEAD,GET,POST之外的方法那么这个字段为必填
-
- Access-Control-Allow-Credentials
-
- 可选字段,该字段若存在便只能为true,表示服务器许可Cookie可以包含在请求中一起发给服务器
-
- 对于某些浏览器即使服务器为true,有时候也需要前端设置
- var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
-
- 若为true Access-Control-Allow-Origin字段便不能为*,必须明确指定域名,Cookie遵循同源政策,只有用服务器域名设置的Cookie才会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie
-
- Access-Control-Allow-Headers
-
- 可选字段,设置Response的额外发送的header字段
-
- CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。
-
- Access-Control-Max-Age
- 设置预警请求的结果能够被缓存多久,单位为秒
-
- express使用cors跨域1
-
- 下载第三方模块
- npm install --save cors
-
- 引入第三方模块
- var express = require(‘express’)
var cors = require(‘cors’)
var app = express()
-
- 设置
- app.use(’’,function (req, res, next) {
res.header(‘Access-Control-Allow-Origin’, '’); //这样表示任意域名都可以访问,这样写不能携带cookie了。
//res.header(‘Access-Control-Allow-Origin’, ‘http://www.baidu.com’); //这样写,只有www.baidu.com 可以访问。
res.header(‘Access-Control-Allow-Headers’, ‘Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild’);
res.header(‘Access-Control-Allow-Methods’, ‘PUT, POST, GET, DELETE, OPTIONS’); //设置方法
if (req.method == ‘OPTIONS’) {
res.send(200); // 意思是,在正常的请求之前,会发送一个验证,是否可以请求。
}
else {
next();
}
});
-
- express使用cors跨域2
-
- 下载第三方模块
- npm install --save cors
-
- 引入第三方模块
- var express = require(‘express’)
var cors = require(‘cors’)
var app = express()
-
- 设置
- app.use(cors({
origin: [‘http://127.0.0.1:3006’, ‘http://127.0.0.1:5500’],
credentials: true
})) -
-
注
- 如果有更多的域名需要设置,直接在origin数组中添加即可
-
-
- jsonp
-
- 解析
- 只能发GET请求,且要求服务器返回数据必须拼接函数名,效率低
-
- js
-
通过
function jsonp_Script () {
var _script = document.createElement(“script”);
_script.type = “text/javascript”;
_script.src = “http://api.douban.com/v2/movie/top250?start=25&count=30&callback=jsonpProcess”;
document.head.appendChild(_script)
}jsonp_Script();
- * 注- 成功请求,注意src中还附加了请求参数,这是个GET请求,jsonp也仅仅支持GET请求。数据在自定义函数jsonpProcess中返回,注意使用callback=jsonpProcess调用- 方式二- 前端- <script> // 函数声明,函数的形参就能获得后端返回的数据 function aaa (data){console.log(data); }
- 后台- const express = require('express');
const app = express();
app.listen(8888, () => {
console.log(‘app_server is running…’);
});
app.get(’/jsonp’,(ewq,res) => {
// res.send(‘aaa(123)’);
res.send(‘aaa({code:200,message:“请求成功”})’);
});- 2. jquery ajax- 通过jquery ajax请求,jquery ajax进行jsonp请求需要额外设置两个属性:dataType,jsonpCallback- 方式一- function jsonp_jquery () {
var url = “http://api.douban.com/v2/movie/top250”
var data = JSON.stringify({
“start”: 25,
“count”: 30
})$.ajax({
type: “GET”,
url: url,
data: data,
dataType: “jsonp”,
jsonpCallback: “jsonpProcess”, // jsonpProcess自定义函数名
success: function (res) {
console.log(res)
}
});
}jsonp_jquery();
- * 注- jsonpCallback属性的值为自定义函数jsonpProcess- 方式二- 前端- <script> $.ajax({url : 'http://127.0.0.1:8888/getData',type : 'get',dataType : 'jsonp',jsonp : 'callback',// jsonpCallback : 'fun',success : function (msg){console.log(msg);} })
- 后台- const express = require('express');
const app = express();
app.listen(8888,()=> {
console.log(‘server is running’);
});app.get(’/getData’,(req,res) => {
console.log(req.query.callback);
const fun = req.query.callback;
res.send(fun+’(“www”)’);
});- 3. vue-resource- <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
-
- Proxy
- 代理请求,使用原始前端服务器接收所有的动态数据请求,转发给其它的后台数据服务器——跨域问题终极解决方案
十一、MySQL
1. MySQL中varchar与char的区别以及varchar(50)中的50代表的涵义?
- Varchar是变长字符串,最多存储的大小是65535字节,查询速度相对较慢;
Char 是定常字符串,最多存储的大小是255字节,查询速度相对较快;
varchar(50)表示:Mysql 4.0 表示存放50个字节,5.0存放50个字符。
2. 如何解决MySQL中存储中文乱码问题?
-
- 脚本文件采用UTF8编码
- 客户端连接数据库使用UTF8编码
- 服务器端创建数据库使用UTF8编码
3. Float和Double的区别是什么?
- FLOAT(单精度浮点数)类型 数据可以存储至多8位十进制数,并在内存中占4字节。
- DOUBLE(双精度浮点数)类型 数据可以存储至多18位十进制数,并在内存中占8字节。
4. 把数据id等于1的名字oldboy更改为oldgirl?
- update test set name=‘oldgirl’ where id=1;
5. 如何登录mysql数据?
- mysql -uroot -p
十二、微信小程序
十三、angular
十四、react
十五、逻辑推理
1. 你让工人为你工作7天,给工人的回报是一根金条,金条平分成相连的7段,你必须在每天结束时都付费,如果只许你两次把金条弄断,你如何给你的工人付费?
-
参考答案
-
分段 1 2 4
-
第一天给工人1段
- 1
-
第二天拿回1段,给工人2段
- 2
-
第三天给工人1段
- 3
-
第四天拿回1 2 段,给工人4段
- 4
-
第五天给工人1段
- 5
-
第六天拿回1段,给工人2段
- 6
-
第七天给工人1段
- 7
-
2. 烧一根不均匀的绳要用一个小时,现在有若干条材质相同的绳子,问:如果用烧绳的方法来判断半个小时?如果用烧绳的方法来计时一个小时十五分钟呢?
3. 一楼到十楼的每层电梯门口都放着一颗钻石,钻石大小不一。你乘坐电梯从一楼到十楼,每层楼电梯门都会打开一次,只能拿一次钻石,问怎样才能拿到最大的一颗?
-
参考答案
-
- 37%法则:先放弃前37%(1/e)的钻石,此后选择比前37%都大的第一颗钻石。注意这个策略只是以最大的概率获得最大的那颗钻石,并不考虑第二大的钻石和最小钻石的区别
-
- 前5层不拿,仅观察,然后再判断后面钻石的大小,如果遇到比前5层大的钻石就拿,否则就拿最后一颗钻石
-
- 考虑到哲学问题(和拾麦穗很相似)。不管最大的钻石在几楼,直接拿一楼的钻石。这里引出苏格拉底让弟子拾麦穗的故事。
古希腊有一位大学者,名叫苏格拉底。一天,他带领几个弟子来到一块麦地边。地里满是沉甸甸的麦穗。苏格拉底对弟子们说“你们要去地里挑一个最大的麦穗,只许进不许退,我在麦地的尽头等你们。”
弟子们听懂了老师的要求后,就走进了麦地。
地里到处都是大麦穗,哪一个才是最大的呢?弟子们埋头向前走。看看这一株,摇了摇头;看看那一株,又摇了摇头。他们总认为最大的那一穗还在前面呢。虽然,弟子们也试着摘了几穗,但并不满意,便随手扔掉了。他们总以为机会还很多,完全没有必要过早地定夺。
弟子们一边低着头往前走,一边用心地挑挑拣拣,经过了很长一段时间。
突然,大家听到了苏格拉底苍老的如同洪钟一般的声音:“你们已经到头了。”这时,两手空空的弟子们才如梦初醒,他们回头望了望麦垄,无数株小麦摇晃着脑袋,似乎在为他们惋惜。
苏格拉底对弟子们说:“这块麦地里肯定有一穗是最大的,但你们未必能碰见它;即使碰见了,也未必能作出准确的判断。因此最大的一穗就是你们刚刚摘下的。”
苏格拉底的弟子们听了老师的话,悟出了这样一个道理:人的一生仿佛也在麦地中行走,也在寻找那最大的一穗。有的人见到了颗粒饱满的“麦穗”,就不失时机地摘下它;有的人则东张西望,一再地错失良机。当然,追求应该是最大的,但把眼前的一穗拿在手中,这才是实实在在的
- 考虑到哲学问题(和拾麦穗很相似)。不管最大的钻石在几楼,直接拿一楼的钻石。这里引出苏格拉底让弟子拾麦穗的故事。
-
4. 一个人花8块钱买了一只鸡,9块钱卖掉了,然后他觉得不划算,花10块钱又买了回来,11块钱卖给了另外一个人,问他赚了多少?
- 第一种结果:获得9+11=20元,支出8+10=18元,赚了2元(不推荐)
- 第二种结果:第一次交易:8元买进,9元卖出,利润1元,第二次交易:9元卖出,10元买进,利润-1元,第三次交易:10元买进,11元卖出,利润1元。整个过程:1-1+1=1元
- 第三种结果:本来可以直接转11-8=3元,结果三次交易后利润只有1元,所有亏了2元
- 第四种结果:从经济学的角度去分析,第一次8块买9块卖赚了1块,第二次却花了10块钱买只值8块钱的鸡亏2块但上一次赚了1块所以是亏1块,然后把这只10块买的鸡卖了11块赚一块,抵消了第二次买鸡时的损失,所以是不赔不赚
5. 请把一盒蛋糕切成8份,分给8个人,但蛋糕盒里还必须留有一份
-
参考答案
- 把切成的8份蛋糕先拿出7份分给7人,剩下的1份连蛋糕盒一起分给第8个人
6. 小明一家过一座桥,过桥时是黑夜,所以必须有灯。现在小明过桥要1秒,小明的弟弟要3秒,小明的爸爸要6秒,小明的妈妈要8秒,小明的爷爷要12秒。每次此桥最多可过两人,而过桥的速度依过桥最慢者而定,而且灯在点燃后30秒就会熄灭。问:小明一家如何过桥?
- 明和弟弟先过桥(3秒)――小明返回(1秒)――小明和爸爸过桥(6秒)――小明返回(1秒)――妈妈和爷爷过桥(12秒)――弟弟返回(3秒)――小明和弟弟过桥(3秒),所用时间为3+1+6+1+12+3+3=29秒
7. 一群人开舞会,每人头上都戴着一顶帽子。帽子只有黑白两种,黑的至少有一顶。每个人都能看到其他人帽子的颜色,却看不到自己的。主持人先让大家看看别人头上戴的是什么帽子,然后关灯,如果有人认为自己戴的是黑帽子,就打自己一个耳光。第一次关灯,没有声音。于是再开灯,大家再看一遍,关灯时仍然鸦雀无声。一直到第三次关灯,才有劈劈啪啪打耳光的声音响起。问有多少人戴着黑帽子?
-
参考答案
- 假如只有一个人戴黑帽子,那他看到所有人都戴白帽,在第一次关灯时就应自打耳光,所以应该不止一个人戴黑帽子;如果有两顶黑帽子,第一次两人都只看到对方头上的黑帽子,不敢确定自己的颜色,但到第二次关灯,这两人应该明白,如果自己戴着白帽,那对方早在上一次就应打耳光了,因此自己戴的也是黑帽子,于是也会有耳光声响起;可事实是第三次才响起了耳光声,说明全场不止两顶黑帽,依此类推,应该是关了几次灯,有几顶黑帽
8. U2合唱团在17分钟内得赶到演唱会场,途中必需跨过一座桥,四个人从桥的同一端出发,你得帮助他们到达另一端,天色很暗,而他们只有一只手电筒。一次同时最多可以有两人一起过桥,而过桥的时候必须持有手电筒,所以就得有人把手电筒带来带去,来回桥两端。手电筒是不能用丢的方式来传递的。四个人的步行速度各不同,若两人同行则以较慢者的速度为准。Bono需花1分钟过桥,Edge需花2分钟过桥,Adam需花5分钟过桥,Larry需花10分钟过桥。他们要如何在17分钟内过桥呢?
9. 为什么下水道的盖子是圆的?
10. 有7克、2克砝码各一个,天平一只,如何只用这些物品三次将140克的盐分成50、90克各一份?
- 1、用天平将盐分成70g两份,即140 ->70 + 70
- 2、用天平将其中一份70g的盐分成35g两份,即70 ->35 + 35
-
- 把两个砝码放在天平两边,选择其中一份35g的盐,加到天平中,直至天平平衡,大的砝码的盐的重量为15g,将得到的15g与另一份35g相加得到50g,剩余的盐就是90g
11. 有一辆火车以每小时15公里的速度离开洛杉矶直奔纽约,另一辆火车以每小时20公里的速度从纽约开往洛杉矶。如果有一只鸟,以30公里每小时的速度和两辆火车同时启动,从洛杉矶出发,碰到另一辆车后返回,依次在两辆火车来回的飞行,直道两面辆火车相遇,请问,这只小鸟飞行了多长距离?
12. 你有两个罐子,50个红色弹球,50个蓝色弹球,随机选出一个罐子,随机选取出一个弹球放入罐子,怎么给红色弹球最大的选中机会?在你的计划中,得到红球的准确几率是多少?
13. 想象你在镜子前,请问,为什么镜子中的影像可以颠倒左右,却不能颠倒上下?
14. 你有四人装药丸的罐子,每个药丸都有一定的重量,被污染的药丸是没被污染的重量+1.只称量一次,如何判断哪个罐子的药被污染了?
15. 如果你有无穷多的水,一个3L的和一个5L的提桶,你如何准确称出4L的水?
16. 你有一桶果冻,其中有黄色,绿色,红色三种,,闭上眼睛选出同样颜色的两个,抓取同种颜色的两个。抓取多少个就可以确定你肯定有两个同一颜色的果冻?
17. 对一批编号为1~100 全部开关朝上开的灯进行以下操作,凡是1 的倍数反方向拨一次,开关2 的倍数反方向又拨一次,开关3 的倍数反方向又拨一次开关。问最后为关熄状态的灯的编号?
- 素数是关,其余是开
18. 假设一张圆盘像唱机上的唱盘那样转动。这张盘一半是黑色,一半是白色。假设你有数量不限的一些颜色传感器。要想确定圆盘转动的方向,你需要在它周围摆多少个颜色传感器?它们应该被摆放在什么位置?
19. 假设时钟到了12点。注意时针和分针重叠在一起。在一天之中,时针和分针共重叠多少次?你知道它们重叠时的具体时间吗?
20. 中间只隔一个数字的两个奇数被称为奇数对,比如17和19。证明奇数对之间的数字总能被6整除(假设这两个奇数都大于6)。现在证明没有由三个奇数组成的奇数对
21. 一个屋子有一个门(门是关闭的)和3盏电灯。屋外有3个开关,分别与这3盏灯相连。你可以随意操纵这些开关,可一旦你将门打开,就不能变换开关了。确定每个开关具体管哪盏灯
22. 假设你有8个球,其中一个略微重一些,但是找出这个球的惟一方法是将两个球放在天平上对比。最少要称多少次才能找出这个较重的球?
- 第一次 左右两边都放3个球。如果平衡,则那个重的在剩下的两个里边。再比一次就行了。
如果不平衡,那么那个重的球在下沉的那个托盘里。
把那3个球拿下来。拿其中的2个放到天平上。可能出现2种结果。
如果平衡,那么没放到天平的那个是重球。
如果不平衡,下沉的是重球。
也就是说:需要称两次
23. 下面玩一个拆字游戏,所有字母的顺序都被打乱。你要判断这个字是什么。假设这个被拆开的字由5个字母组成:
1.共有多少种可能的组合方式?2.如果我们知道是哪5个字母,那会怎么样? 3.找出一种解决这个问题的方法?
24. 有4个女人要过一座桥。她们都站在桥的某一边,要让她们在17分钟内全部通过这座桥。这时是晚上。她们只有一个手电筒。最多只能让两个人同时过桥。不管是谁过桥,不管是一个人还是两个人,必须要带着手电筒。手电筒必须要传来传去,不能扔过去。每个女人过桥的速度不同,两个人的速度必须以较慢的那个人的速度过桥。
第一个女人:过桥需要1分钟;
第二个女人:过桥需要2分钟;
第三个女人:过桥需要5分钟;
第四个女人:过桥需要10分钟。
比如,如果第一个女人与第4个女人首先过桥,等她们过去时,已经过去了10分钟。如果让第4个女人将手电筒送回去,那么等她到达桥的另一端时,总共用去了20分钟,行动也就失败了。怎样让这4个女人在17分钟内过桥?还有别的什么方法?25. 如果你有两个桶,一个装的是红色的颜料,另一个装的是蓝色的颜料。你从蓝色颜料桶里舀一杯,倒入红色颜料桶,再从红色颜料桶里舀一杯倒入蓝颜料桶。两个桶中红蓝颜料的比例哪个更高?通过算术的方式来证明这一点
26. 考虑一个双人游戏。游戏在一个圆桌上进行。每个游戏者都有足够多的硬币。他们需要在桌子上轮流放置硬币,每次必需且只能放置一枚硬币,要求硬币完全置于桌面内(不能有一部分悬在桌子外面),并且不能与原来放过的硬币重叠。谁没有地方放置新的硬币,谁就输了。游戏的先行者还是后行者有必胜策略?这种策略是什么?
- 先行者在桌子中心放置一枚硬币,以后的硬币总是放在与后行者刚才放的地方相对称的位置。这样,只要后行者能放,先行者一定也有地方放。先行者必胜
27. A、B两人分别在两座岛上。B生病了,A有B所需要的药。C有一艘小船和一个可以上锁的箱子。C愿意在A和B之间运东西,但东西只能放在箱子里。只要箱子没被上锁,C都会偷走箱子里的东西,不管箱子里有什么。如果A和B各自有一把锁和只能开自己那把锁的钥匙,A应该如何把东西安全递交给B?
- A把药放进箱子,用自己的锁把箱子锁上。B拿到箱子后,再在箱子上加一把自己的锁。箱子运回A后,A取下自己的锁。箱子再运到B手中时,B取下自己的锁,获得药物
28. 有25匹马,速度都不同,但每匹马的速度都是定值。现在只有5条赛道,无法计时,即每赛一场最多只能知道5匹马的相对快慢。问最少赛几场可以找出25匹马中速度最快的前3名?
- 每匹马都至少要有一次参赛的机会,所以25匹马分成5组,一开始的这5场比赛是免不了的。接下来要找冠军也很容易,每一组的冠军在一起赛一场就行了(第6场)。最后就是要找第2和第3名。我们按照第6场比赛中得到的名次依次把它们在前5场比赛中所在的组命名为A、B、C、D、E。即:A组的冠军是第6场的第1名,B组的冠军是第6场的第2名……每一组的5匹马按照他们已经赛出的成绩从快到慢编号:
A组:1,2,3,4,5
B组:1,2,3,4,5
C组:1,2,3,4,5
D组:1,2,3,4,5
E组:1,2,3,4,5
从现在所得到的信息,我们可以知道哪些马已经被排除在3名以外。只要已经能确定有3匹或3匹以上的马比这匹马快,那么它就已经被淘汰了。可以看到,只有上表中粗体的那5匹马是有可能为2、3名的。即:A组的2、3名;B组的1、2名,C组的第1名。取这5匹马进行第7场比赛,第7场比赛的前两名就是25匹马中的2、3名。故一共最少要赛7场。
这道题有一些变体,比如64匹马找前4名。方法是一样的,在得出第1名以后寻找后3名的候选竞争者就可以了
XMind: ZEN - Trial Version
-