解释下浏览器是如何判断元素是否匹配某个 CSS 选择器?javascript
伪类的用法:html
css动画和js动画的优缺点html5
一些编程题
js算法题
答:
ie6,7不支持display:inline-block
参考自: 常见浏览器兼容性问题与解决方案
答:
在服务器配置Entity-Tag if-none-match
(1) 可搜索型
(2) 开放性
(3) 费用
(4) 易用性
(5) 易于开发
(1) 多媒体处理
(2) 兼容性
(3) 矢量图形 比SVG,Canvas优点大不少
(4) 客户端资源调度,好比麦克风,摄像头
参考:前端开发的优化问题
CSS3新特性:
参考:CSS3中的一些属性
答:
答:
参考自: 经验分享:CSS浮动(float,clear)通俗讲解
答:
1
2
|
.clearfloat:after{display:block;clear:both;content:
""
;visibility:hidden;height:0}
.clearfloat{zoom:1}
|
zoom:1的做用: 触发IE下的hasLayout。zoom是IE浏览器专有属性,能够设置或检索对象的缩放比例。
当设置了zoom的值以后,所设置的元素就会扩大或缩小,高度宽度就会从新计算了,这里一旦改变zoom值时其实也会发生从新渲染,运用这个原理,也就解决了ie下子元素浮动时候父元素不随着自动扩大的问题。
答: CSS Sprites其实就是把网页中一些背景图片整合到一张图片文件中,再利用CSS的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position能够用数字能精确的定位出背景图片的位置。
答:
1) <h1><img src="image.gif" alt="Image Replacement"></h1>
2) 移开文字:
1
2
3
4
|
<
h1
><
span
>Image Replacement</
span
></
h1
>
h1{ background:url(hello_world.gif) no-repeat; width: 150px; height: 35px; }
span { display: none; }
|
注意问题:①结构性须要增长一个标签包裹文本 ②须要把背景图设置在外标签上,并把文本外标签隐藏.
缺点: 不利于阅览器浏览网页
3) text-indent属性,而且给其设置一个较大的负值,x达到隐藏文本的效果
1
2
3
4
5
6
7
8
|
<
h1
class="technique-three">w3cplus</ h1 >
.technique-three {
width: 329px;
height: 79px;
background: url(images/w3cplus-logo.png);
text-indent: -9999px;
}
|
4) 咱们此处使用一个透明的gif图片,经过在img标签中的“alt”属性来弥补display:none。这样阅读器之类的就能阅读到所替换的文本是什么
<h1 class="technique-five"> <img src="images/blank.gif" alt="w3cplus" /< <span>w3cplus</span> </h1> .technique-five { width: 329px; height: 79px; background: url(images/w3cplus-logo.png); } .technique-five span { display: none; }
5) 使用零高度来隐藏文本,但为了显示背景图片,须要设置一个与替换图片同样的大小的padding值
1
2
3
4
5
6
7
8
9
10
|
<
h1
class="technique-six">w3cplus</ h1 >
.technique-six {
width: 329px;
padding: 79px 0 0 0;
height: 0px;
font-size: 0;
background: url(images/w3cplus-logo.png);
overflow: hidden;
}
|
6) 经过把span的大小都设置为“0”,来达到隐藏文本效果,这样阅读器就能彻底阅读到,并且又达到了图片替换文本的效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<
h1
class="technique-seven">
<
span
>w3cplus</
span
>
</
h1
>
.technique-seven {
width: 329px;
height: 79px;
background: url(images/w3cplus-logo.png);
}
.technique-seven span {
display: block;
width: 0;
height: 0;
font-size: 0;
overflow: hidden;
}
|
7) 利用一个空白的span标签来放置背景图片,并对其进行绝对定位,使用覆盖文本,达到隐藏替换文本的效果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<
h1
class="technique-eight">
<
span
></
span
>w3cplus
</
h1
>
.technique-eight {
width: 329px;
height: 79px;
position: relative;
}
.technique-eight span {
background: url(images/w3cplus-logo.png);
position: absolute;
width: 100%;
height: 100%;
}
|
8) 设置字体为微小值,但这里须要注意一点不能忘了设置字体色和替换图片色同样,否则会有一个小点显示出来
1
2
3
4
5
6
7
8
9
|
<
h1
class="technique-nine">w3cplus</ h1 >
.technique-nine {
width: 329px;
height: 79px;
background: url(images/w3cplus-logo.png);
font-size: 1px;
color: white;
}
|
9) 使用css的clip属性来实现图片替换文本的效果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<
h1
class="technique-ten">< span >w3cplus</ span ></ h1 >
.technique-ten {
width: 329px;
height: 79px;
background: url(images/w3cplus-logo.png);
}
.technique-ten span {
border: 0 !important;
clip: rect(1px 1px 1px 1px);
clip: rect(1px,1px,1px,1px);
height: 1px !important;
margin: -1px;
overflow: hidden;
padding: 0 !important;
position: absolute !important;
width: 1px;
}
|
参考自: 十种图片替换文本CSS方法
1
2
3
4
5
6
7
8
9
10
|
<!--[if !IE]><!-->
除IE外均可识别 <!--<![endif]-->
<!--[if IE]> 全部的IE可识别 <![endif]-->
<!--[if IE 6]> 仅IE6可识别 <![endif]-->
<!--[if lt IE 6]> IE6以及IE6如下版本可识别 <![endif]-->
<!--[if gte IE 6]> IE6以及IE6以上版本可识别 <![endif]-->
<!--[if IE 7]> 仅IE7可识别 <![endif]-->
<!--[if lt IE 7]> IE7以及IE7如下版本可识别 <![endif]-->
<!--[if gte IE 7]> IE7以及IE7以上版本可识别 <![endif]-->
<!--[if IE 8]> 仅IE8可识别 <![endif]-->
<!--[if IE 9]> 仅IE9可识别 <![endif]-->
|
答: 功能限制的浏览器, 好比低版本IE, 手机浏览器, 等会在不少功能上不符合Web标准, 而应对方式主要有:
参考自: 如何为有功能限制的浏览器提供网页
答:
1)reset。参照下题“描述下 “reset” CSS 文件的做用和使用它的好处”的答案。
2)规范命名。尤为对于没有语义化的html标签,例如div,所赋予的class值要特别注意。
2)抽取可重用的部件,注意层叠样式表的“优先级”。
针对打印机的样式: @media print{...}
参考:如何优化网页的打印样式? 移动端H5知识普及 - CSS3媒体查询
答: 优势:
参考: 再谈 CSS 预处理器
做者:张靖超连接:https://www.zhihu.com/question/24959507/answer/29672263来源:知乎著做权归做者全部,转载请联系做者得到受权。
body.ready #wrapper > .lol233
答:
盒模型:文档中的每一个元素被描绘为矩形盒子,渲染引擎的目的就是断定大小,属性——好比它的颜色、背景、边框方面——及这些盒子的位置。
在CSS中,这些矩形盒子用标准盒模型来描述。这个模型描述了一个元素所占用的空间。每个盒子有四条边界:外边距边界margin edge,边框边界border edge,内边距边界padding edge和内容边界content edge。
内容区域是真正包含元素内容的区域,位于内容边界的内部,它的大小为内容宽度或content-box宽及内容高度或content-box高。若是box-sizing为默认值,width、min-width、max-width、height、min-height和max-height控制内容大小。
内边距区域padding area用内容可能的边框之间的空白区域扩展内容区域。一般有背景——颜色或图片(不透明图片盖住背景颜色)。
边框区域扩展了内边距区域。它位于边框边界内部,大小为border-box宽和border-box高。
外边距区域margin area用空白区域扩展边框区域,以分开相邻的元素。它的大小为margin-box的高宽。
在外边距合并的状况下,因为盒之间共享外边距,外边距不容易弄清楚。
对于非替换的行内元素来讲,尽管内容周围存在内边距与边框,但其占用空间(行高)由line-height属性决定。
盒子模型分为两类:W3C标准盒子模型和IE盒子模型 (微软确实不喜欢服从他家的标准)
这二者的关键差异就在于:
咱们在编写页面代码的时候应该尽可能使用标准的W3C盒子模型(须要在页面中声明DOCTYPE类型)。
各浏览器盒模型的组成结构是一致的,区别只是在"怪异模式"下宽度和高度的计算方式,而“标准模式”下则没有区别。组成结构以宽度为例:总宽度=marginLeft+borderLeft+paddingLeft+contentWidth+paddingRight+borderRight+marginRight(W3C标准盒子模型)。页面在“怪异模式”下,css中为元素的width和height设置的值在标准浏览器和ie系列(ie9除外)里的表明的含义是不一样的(IE盒子模型)。
于是解决兼容型为题最简洁和值得推荐的方式是:下述的第一条。
参考: 解释一下你对盒模型的理解,以及如何在 CSS 中告诉浏览器使用不一样的盒模型来渲染你的布局。
reset.css可以重置浏览器的默认属性。不一样的浏览器具备不一样的样式,重置可以使其统一。好比说ie浏览器和FF浏览器下button显示不一样,经过reset可以统同样式,显示相同的效果。可是不少reset是不必的,多写了会增长浏览器在渲染页面的负担。
好比说,
1)咱们不该该对行内元素设置无效的属性,对span设置width和height,margin都不会生效的。
2)对于absolute和fixed定位的固定尺寸(设置了width和height属性),若是设置了top和left属性,那么bottom和right,margin和float就没有做用。
3)后面设置的属性将会覆盖前面重复设置的属性。
说到 IE 的 bug,在 IE6之前的版本中,IE对盒模型的解析出现一些问题,跟其它浏览器不一样,将 border 与 padding 都包含在 width 以内。而另一些浏览器则与它相反,是不包括border和padding的。对于IE浏览器,当咱们设置 box-sizing: content-box; 时,浏览器对盒模型的解释听从咱们以前认识到的 W3C 标准,当它定义width和height时,它的宽度不包括border和padding;对于非IE浏览器,当咱们设置box-sizing: border-box; 时,浏览器对盒模型的解释与 IE6以前的版本相同,当它定义width和height时,border和padding则是被包含在宽高以内的。内容的宽和高能够经过定义的“width”和 “height”减去相应方向的“padding”和“border”的宽度获得。内容的宽和高必须保证不能为负,必要时将自动增大该元素border box的尺寸以使其内容的宽或高最小为0。
使用 * { box-sizing: border-box; }可以统一IE和非IE浏览器之间的差别。
答:
CSS3的动画
JavaScript的动画
结论
答:
经过媒体查询能够为不一样大小和尺寸的媒体定义不一样的css,适合相应的设备显示;即响应式布局
参考自: CSS3媒体查询 使用 CSS 媒体查询建立响应式网站 《响应式Web设计实践》学习笔记
答:
display:none或者visibility:hidden,overflow:hidden。
通常来说,越详细的级别越高。CSS优先级包含四个级别(文内选择符,ID选择符,Class选择符,元素选择符)以及各级别出现的次数。根据这四个级别出现的次数计算获得CSS的优先级
参考: CSS样式选择器优先级
答:
答: BFC指的是Block Formatting Context, 它提供了一个环境, html元素在这个环境中按照必定规则进行布局. 一个环境中的元素不会影响到其余环境中的布局. 决定了元素如何对其内容进行定位, 以及和其余元素的关系和相互做用.
其中: FC(Formatting Context): 指的是页面中的一个渲染区域, 而且拥有一套渲染规则, 它决定了其子元素如何定位, 以及与其余元素的相互关系和做用.
BFC: 块级格式化上下文, 指的是一个独立的块级渲染区域, 只有block-level box参与, 该区域拥有一套渲染规则来约束块级盒子的布局, 且与区域外部无关.
参考: 我对BFC的理解 CSS BFC和IE Haslayout介绍
答:
参考自: 猿教程
答:
参考自: 理解HTML语义化
答:
答:
答:
答: 采用统一编码utf-8模式
参考自: 多语言的网站怎么作呀 多语言网站设计须要注意的问题
为前端开发者提供自定义的属性,这些属性集能够经过对象的dataset属性获取,不支持该属性的浏览器能够经过 getAttribute方法获取
<div data-author="david" data-time="2011-06-20" data-comment-num="10">...</div>
div.dataset.commentNum; // 可经过js获取 10
答:
1)Web Storage API
2)基于位置服务LBS
3)无插件播放音频视频
4)调用相机和GPU图像处理单元等硬件设备
5)拖拽和Form API
答:
答:
答:
答:
参考: 《JavaScript》高级程序设计第21章:Ajax和Comet
参考自: 区别和详解:js中call()和apply()的用法
new
操做符建立对象:这种行为就像把原函数当成构造器。提供的 this 值被忽略,同时调用时的参数被提供给模拟函数。 答: 事件委托利用了事件冒泡, 只指定一个事件处理程序, 就能够管理某一类型的全部事件.
例:
html部分: 要点击li弹出其id
<ul id="list"> <li id="li-1">Li 2</li> <li id="li-2">Li 3</li> <li id="li-3">Li 4</li> <li id="li-4">Li 5</li> <li id="li-5">Li 6</li> <li id="li-6">Li 7</li> </ul>
//js部分
document.getElementById("list").addHandler("click", function(e){ var e = e || window.event; var target = e.target || e.srcElement; if(target.nodeName.toUpperCase == "LI"){ console.log("List item", e,target.id, "was clicked!"); } });
答:
this 在 JavaScript 中主要由如下五种使用场景。
参考:js怎么实现继承?
答: AMD是依赖提早加载,CMD是依赖延时加载
答: 哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它经过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫作散列函数,存放记录的数组叫作散列表。
使用哈希查找有两个步骤:
元素特征转变为数组下标的方法就是散列法。散列法固然不止一种,下面列出三种比较经常使用的:
1,除法散列法
最直观的一种,上图使用的就是这种散列法,公式:
index = value % 16
学过汇编的都知道,求模数实际上是经过一个除法运算获得的,因此叫“除法散列法”。
2,平方散列法
求index是很是频繁的操做,而乘法的运算要比除法来得省时(对如今的CPU来讲,估计咱们感受不出来),因此咱们考虑把除法换成乘法和一个位移操做。公式:
index = (value * value) >> 28 (右移,除以2^28。记法:左移变大,是乘。右移变小,是除。)
若是数值分配比较均匀的话这种方法能获得不错的结果,但我上面画的那个图的各个元素的值算出来的index都是0——很是失败。也许你还有个问题,value若是很大,value * value不会溢出吗?答案是会的,但咱们这个乘法不关心溢出,由于咱们根本不是为了获取相乘结果,而是为了获取index。
3,斐波那契(Fibonacci)散列法
解决冲突的方法:
1. 拉链法
将大小为M 的数组的每个元素指向一个条链表,链表中的每个节点都存储散列值为该索引的键值对,这就是拉链法.
对采用拉链法的哈希实现的查找分为两步,首先是根据散列值找到等一应的链表,而后沿着链表顺序找到相应的键。
2. 线性探测法:
使用数组中的空位解决碰撞冲突
参考: 哈希表的工做原理 浅谈算法和数据结构: 十一 哈希表
答:
参考自: js闭包的用途
参考: 伪数组
(1) 做为函数的参数,表示该函数的参数不是对象。
(2) 做为对象原型链的终点。
(1)变量被声明了,但没有赋值时,就等于undefined。
(2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。
(3)对象没有赋值的属性,该属性的值为undefined。
(4)函数没有返回值时,默认返回undefined。
从目标元素开始,往顶层元素传播。途中若是有节点绑定了相应的事件处理函数,这些函数都会被一次触发。若是想阻止事件起泡,能够使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来组织事件的冒泡传播。
答:
而函数定义(语句以function关键字开始)是不能被当即执行的,这无疑会致使语法的错误(SyntaxError)。当函数定义代码段包裹在括号内,使解析器能够将之识别为函数表达式,而后调用。IIFE: (function foo(){})()
区分 (function(){})(); 和 (function(){}()); 其实二者实现效果同样。
函数字面量:首先声明一个函数对象,而后执行它。(function () { alert(1); })();
优先表达式:因为Javascript执行表达式是从圆括号里面到外面,因此能够用圆括号强制执行声明的函数。(function () { alert(2); }());
答:
DOM元素的attribute和property二者是不一样的东西。attribute翻译为“特性”,property翻译为“属性”。
attribute是一个特性节点,每一个DOM元素都有一个对应的attributes属性来存放全部的attribute节点,attributes是一个类数组的容器,说得准确点就是NameNodeMap,不继承于Array.prototype,不能直接调用Array的方法。attributes的每一个数字索引以名值对(name=”value”)的形式存放了一个attribute节点。<div class="box" id="box" gameid="880">hello</div>
property就是一个属性,若是把DOM元素当作是一个普通的Object对象,那么property就是一个以名值对(name=”value”)的形式存放在Object中的属性。要添加和删除property和普通的对象相似。
不少attribute节点还有一个相对应的property属性,好比上面的div元素的id和class既是attribute,也有对应的property,无论使用哪一种方法均可以访问和修改。
总之,attribute节点都是在HTML代码中可见的,而property只是一个普通的名值对属性。
答:
在全部的函数 (或者全部最外层函数) 的开始处加入 "use strict"; 指令启动严格模式。
"严格模式"有两种调用方法
1)将"use strict"放在脚本文件的第一行,则整个脚本都将以"严格模式"运行。若是这行语句不在第一行,则无效,整个脚本以"正常模式"运行。若是不一样模式的代码文件合并成一个文件,这一点须要特别注意。
2)将整个脚本文件放在一个当即执行的匿名函数之中。
好处
- 消除Javascript语法的一些不合理、不严谨之处,减小一些怪异行为;
- 消除代码运行的一些不安全之处,保证代码运行的安全;
- 提升编译器效率,增长运行速度;
- 为将来新版本的Javascript作好铺垫。
坏处
一样的代码,在"严格模式"中,可能会有不同的运行结果;一些在"正常模式"下能够运行的语句,在"严格模式"下将不能运行
答: 核心( ECMAScript) , 文档对象模型(DOM), 浏览器对象模型(BOM)
答: DOM是针对HTML和XML文档的一个API(应用程序编程接口). DOM描绘了一个层次化的节点树, 容许开发人员添加, 移除和修改页面的某一部分.
参考: HTML DOM 方法
答: Undefined, Null, Boolean, Number, String
Object是复杂数据类型, 其本质是由一组无序的名值对组成的.
答:
参考: 《JavaScript高级程序设计》
js是一门具备自动垃圾回收机制的编程语言,开发人员没必要关心内存分配和回收问题
答: try-catch 和with延长做用域. 由于他们都会建立一个新的变量对象.
这两个语句都会在做用域链的前端添加一个变量对象. 对with语句来讲, 会将指定的对象添加到做用域链中. 对catch语句来讲, 会建立一个新的变量对象, 其中包含的是被抛出的错误对象的声明.
function buildUrl(){ var qs = "?debug=true"; //with接收location对象, 所以其变量对象中就包含了location对象的全部属性和方法, 而这个变量对象被添加到了做用域链的前端 with(location){ //这里的href实际上是location.href. 建立了一个名为url的变量, 就成了函数执行环境的一部分 var url = href + qs; } return url; }
参考: js try、catch、finally语句还有with语句 JavaScript 开发进阶:理解 JavaScript 做用域和做用域链
答:
答: 捕获->处于目标->冒泡,IE应该是只有冒泡没有捕获。
事件代理就是在父元素上绑定事件来处理,经过event对象的target来定位。
答: 用定时器 setTimeout和setInterval
答:
transition-delay
transition-duration
transition-property
transition-timing-function
,对应动画的4种属性: 延迟、持续时间、对应css属性和缓动函数,transform 包含7种属性:animation-name
animation-duration
animation-timing-function
animation-delay
animation-direction
animation-iteration-count
animation-fill-mode
animation-play-state
,它们能够定义动画名称,持续时间,缓动函数,动画延迟,动画方向,重复次数,填充模式。
参考自: 前端动画效果实现的简单比较
答: 封装, 继承, 多态
答: hasOwnPrototype
答:
1) 箭头操做符 inputs=>outputs: 操做符左边是输入的参数,而右边则是进行的操做以及返回的值
2) 支持类, 引入了class关键字. ES6提供的类实际上就是JS原型模式的包装
3) 加强的对象字面量.
1. 能够在对象字面量中定义原型 __proto__: xxx //设置其原型为xxx,至关于继承xxx
2. 定义方法能够不用function关键字
3. 直接调用父类方法
4) 字符串模板: ES6中容许使用反引号 ` 来建立字符串,此种方法建立的字符串里面能够包含由美圆符号加花括号包裹的变量${vraible}。
5) 自动解析数组或对象中的值。好比若一个函数要返回多个值,常规的作法是返回一个对象,将每一个值作为这个对象的属性返回。但在ES6中,利用解构这一特性,能够直接返回一个数组,而后数组中的值会自动被解析到对应接收该值的变量中。
6) 默认参数值: 如今能够在定义函数的时候指定参数的默认值了,而不用像之前那样经过逻辑或操做符来达到目的了。
7) 不定参数是在函数中使用命名参数同时接收不定数量的未命名参数。在之前的JavaScript代码中咱们能够经过arguments变量来达到这一目的。不定参数的格式是三个句点后跟表明全部不定参数的变量名。好比下面这个例子中,…x表明了全部传入add函数的参数。
8) 拓展参数则是另外一种形式的语法糖,它容许传递数组或者类数组直接作为函数的参数而不用经过apply。
9) let和const关键字: 能够把let当作var,只是它定义的变量被限定在了特定范围内才能使用,而离开这个范围则无效。const则很直观,用来定义常量,即没法被更改值的变量。
10) for of值遍历 每次循环它提供的不是序号而是值。
11) iterator, generator
12) 模块
13) Map, Set, WeakMap, WeakSet
14) Proxy能够监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操做。一会儿让咱们对一个对象有了很强的追踪能力,同时在数据绑定方面也颇有用处。
15) Symbols Symbol 经过调用symbol函数产生,它接收一个可选的名字参数,该函数返回的symbol是惟一的。以后就能够用这个返回值作为对象的键了。Symbol还能够用来建立私有属性,外部没法直接访问由symbol作为键的属性值。
16) Math, Number, String, Object的新API
17) Promises是处理异步操做的一种模式
参考: ES6新特性概览
答: getElementById() getElementsByTagName()
节点遍历: 先序遍历DOM树的5种方法
答: 能够自定义一个函数
1
2
3
4
5
6
7
8
|
.border-radius(@values) {
-webkit-border-radius: @values;
-moz-border-radius: @values;
border-radius: @values;
}
div {
.border-radius(10px);
}
|
答:
答:
我在回答这个题的时候说是两个事件, 先执行捕获的后执行冒泡的. 实际上是不对的.
绑定在目标元素上的事件是按照绑定的顺序执行的!!!!
即: 绑定在被点击元素的事件是按照代码顺序发生,其余元素经过冒泡或者捕获“感知”的事件,按照W3C的标准,先发生捕获事件,后发生冒泡事件。全部事件的顺序是:其余元素捕获阶段事件 -> 本元素代码顺序事件 -> 其余元素冒泡阶段事件 。
参考: JavaScript-父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序
答:
块级做用域引入了两种新的声明形式,能够用它们定义一个只存在于某个语句块中的变量或常量.这两种新的声明关键字为:
let
: 语法上很是相似于var
, 但定义的变量只存在于当前的语句块中const
: 和let
相似,但声明的是一个只读的常量使用let
代替var
能够更容易的定义一个只在某个语句块中存在的局部变量,而不用担忧它和函数体中其余部分的同名变量有冲突.在let
语句内部用var
声明的变量和在let
语句外部用var
声明的变量没什么差异,它们都拥有函数做用域,而不是块级做用域.
答:
1. 直接调用function,每个类的实例都会拷贝这个函数,弊端就是浪费内存(如上)。prototype方式定义的方式,函数不会拷贝到每个实例中,全部的实例共享prototype中的定义,节省了内存。
2. 可是若是prototype的属性是对象的话,全部实例也会共享一个对象(这里问的是函数应该不会出现这个状况),若是其中一个实例改变了对象的值,则全部实例的值都会被改变。同理的话,若是使用prototype调用的函数,一旦改变,全部实例的方法都会改变。——不能够对实例使用prototype属性,只能对类和函数用。
答:
由于js中数据类型分为基本数据类型(number, string, boolean, null, undefined)和引用类型值(对象, 数组, 函数). 这两类对象在复制克隆的时候是有很大区别的. 原始类型存储的是对象的实际数据, 而对象类型存储的是对象的引用地址(对象的实际内容单独存放, 为了减小数据开销一般放在内存中). 此外, 对象的原型也是引用对象, 它把原型的属性和方法放在内存中, 经过原型链的方式来指向这个内存地址.
因而克隆也会分为两类:
深度克隆实现:
function clone(obj){ if(typeof(obj)== 'object'){ var result = obj instanceof Array ? [] : {}; for(var i in obj){ var attr = obj[i]; result[i] = arguments.callee(attr); } return result; } else { return obj; } };
参考: JavaScript深克隆 javascript中对象的深度克隆
1. var obj = {a : 1}; (function (obj) { obj = {a : 2}; })(obj); //问obj怎么变?
答: 外部的obj不变. 由于匿名函数中obj传入参数等因而建立了一个局部变量obj, 里面的obj指向了一个新的对象 . 若是改为(function () { obj = {a : 2}; })(obj); 就会变了
2. var obj = { a:1, func: function() { (function () { a=2; }(); }} ; obj.fun() //a 怎么变? 匿名函数里的this 是什么?
答: obj里的a不会变. 匿名函数里的this指向全局对象window. 这等因而给window加了一个名为a的属性
要改变obj中a的值 , 应当:
(function() { this.a = 2}).call(this);
或者obj中定义func : func: function() { var self = this; (function(){self.a=2;})();}
3. 要实现函数内每隔5秒调用本身这个函数,100次之后中止,怎么办
想到了用闭包, 可是写错了...
一开始是这么写的
1
2
3
4
5
6
7
|
//注意!!这种写法是错误的!!! for(var i=0; i<oLis.length; i++){
oLis[i].onclick =
function
(){
return
( function (j){
alert(j);
})(i);
}
}
|
可是这样作的话, 点击全部的li都会弹出最后一个序号. 由于每一个li对应的onclick事件的函数, 返回的那个函数的参数仍是最后的那个i, 并无改变. 应该是这么写
方法1 :
1
2
3
4
5
6
7
|
for
(
var
i=0; i<oLis.length; i++){
oLis[i].onclick = (
function
(j){
return
function (){
alert(j);
}
})(i);
}
|
这样的话, 给每一个li绑定onclick事件时, 其实绑的是一个当即执行函数, 这个当即执行函数的参数是i, 由于它是当即执行的, 循环时已经把i的值赋给了li的onclick事件, 因此在外部函数里的i改变后并不会影响i的值.
另外一种实现方法:(当即执行函数)
1
2
3
4
5
6
7
|
for
(
var
i=0; i<oLi.length; i++){
(
function
(j){
oLi[j].onclick =
function
(){
alert(j);
};
})(i);
}
|
或者不用闭包
方法2:
var oLi = document.getElementsByTagName('li'); function func(obj,i){ obj.onclick = function(){ alert (i); } } for(var i = 0; i<oLi.length; i++){ func(oLi[i], i); }
方法3: 设置属性:
1
2
3
4
|
var
oLi = document.getElementsByTagName( 'li' );
for
(
var
i=0; i<oLi.length; i++){
oLi[i].setAttribute(
"onclick"
,
"alert("
+i+
");"
);
}
|
方法4: 设置index保存
1
2
3
4
5
6
|
for
(
var
i=0; i<oLi.length; i++){
oLi[i].index = i;
oLi[i].onclick =
function
(){
alert(
this
.index);
}
}
|
或者也能够用事件代理来作.
方法1. 建立一个新的临时数组来保存数组中已有的元素
1
2
3
4
5
6
7
8
9
10
11
12
|
var
a = new Array(1,2,2,2,2,5,3,2,9,5,6,3);
Array.prototype.unique1 =
function
(){
var
n = []; //一个新的临时数组
for
(
var
i=0; i< this .length; i++){
//若是把当前数组的第i已经保存进了临时数组, 那么跳过
if
(n.indexOf(
this
[i]) == -1){
n.push(
this
[i]);
}
}
return
n;
}
console.log(a.unique1());
|
方法2. 使用哈希表存储已有的元素
1
2
3
4
5
6
7
8
9
10
11
|
Array.prototype.unique2 =
function
(){
var
hash = {},
n = [];
//hash 做为哈希表, n为临时数组
for
(
var
i=0; i< this .length; i++){
if
(!hash[
this
[i]]){
//若是hash表中没有当前项
hash[
this
[i]] =
true
;
//存入hash表
n.push(
this
[i]);
//当前元素push到临时数组中
}
}
return
n;
}
|
方法3. 使用indexOf判断数组元素第一次出现的位置是否为当前位置
1
2
3
4
5
6
7
8
9
10
11
12
|
Array.prototype.unique3 =
function
(){
var
n = [ this [0]];
for
(
var
i=1; i< this .length; i++) //从第二项开始遍历
{
//若是当前数组元素在数组中出现的第一次的位置不是i
//说明是重复元素
if
(
this
.indexOf(
this
[i]) == i){
n.push(
this
[i]);
}
}
return
n;
}
|
方法4. 先排序再去重
1
2
3
4
5
6
7
8
9
10
|
Array.prototype.unique4 =
function
(){
this
.sort(
function
(a, b){
return
a - b;});
var
n = [ this [0]];
for
(
var
i=1; i< this .length; i++){
if
(
this
[i] !=
this
[i-1]){
n.push(
this
[i]);
}
}
return
n;
}
|
第一种方法和第三种方法都使用了indexOf(), 这个函数的执行机制也会遍历数组
第二种方法使用了一个哈希表, 是最快的.
第三种方法也有一个排序的复杂度的计算.
而后作了个测试, 随机生成100万个0-1000的数组结果以下:
第三种方法老是第二种方法的将近两倍, 而第四种方法与数组的范围有关,
若是是0-100的数组
而若是是0-10000, 方法四看着就效果还不错了
而第二种方法永远是最好的, 可是是以空间换时间
所有代码以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
var
a = [];
for
(
var
i=0; i<1000000; i++){
a.push(Math.ceil(Math.random()*10000));
}
Array.prototype.unique1 =
function
(){
var
n = []; //一个新的临时数组
for
(
var
i=0; i< this .length; i++){
//若是把当前数组的第i已经保存进了临时数组, 那么跳过
if
(n.indexOf(
this
[i]) == -1){
n.push(
this
[i]);
}
}
return
n;
}
Array.prototype.unique2 =
function
(){
var
hash = {},
n = [];
//hash 做为哈希表, n为临时数组
for
(
var
i=0; i< this .length; i++){
if
(!hash[
this
[i]]){
//若是hash表中没有当前项
hash[
this
[i]] =
true
;
//存入hash表
n.push(
this
[i]);
//当前元素push到临时数组中
}
}
return
n;
}
Array.prototype.unique3 =
function
(){
var
n = [ this [0]];
for
(
var
i=1; i< this .length; i++) //从第二项开始遍历
{
//若是当前数组元素在数组中出现的第一次的位置不是i
//说明是重复元素
if
(
this
.indexOf(
this
[i]) == i){
n.push(
this
[i]);
}
}
return
n;
}
Array.prototype.unique4 =
function
(){
this
.sort(
function
(a, b){
return
a - b;});
var
n = [ this [0]];
for
(
var
i=1; i< this .length; i++){
if
(
this
[i] !=
this
[i-1]){
n.push(
this
[i]);
}
}
return
n;
}
var
begin1 = new Date();
a.unique1();
var
end1 = new Date();
var
begin2 = new Date();
a.unique2();
var
end2 = new Date();
var
begin3 = new Date();
a.unique3();
var
end3 = new Date();
var
begin4 = new Date();
a.unique4();
var
end4 = new Date();
console.log(
"方法一执行时间:"
+ (end1 - begin1));
console.log(
"方法二执行时间:"
+ (end2 - begin2));
console.log(
"方法三执行时间:"
+ (end3 - begin3));
console.log(
"方法四执行时间:"
+ (end4 - begin4));
|
参考: js数组去重
了解先后端分离吗(当时真不了解,但他细心地给我解释了一下,还建议我去看淘宝ued团队的文章)
用什么版本控制工具在用mac吗用什么来管理各类依赖数组去重position的几种值css选择器优先级伪类的用法闭包闭包的实现举例浮动清除浮动jsonp是啥gulp怎么用,用过啥你以为你还有什么闪光点我没有问到的(这个太囧了,我竟然反问了面试官你以为我刚才闪不闪?面试官呵呵呵呵)require的读取顺序图片轮播(虽然不少面试题都有这个,可是我本身真的没有实现过,说了一个opacity与setTimeout的组合运用,最后没有实现到面试官要求的效果,可是他说还行)sass的伪类怎么嵌套jsonp是啥怎么用jsonp发送jsonp时候的那个消息头长什么样子?(这个我直接跟他说没看过不知道)一个文本框,须要两个控件对里面的值进行控制,一个是+1一个是-1,要求每点击一次就有个提示框冒出来。并且文本框是可修改的,每次修改也会冒出提示框。(这个我回答的很模糊,我说应该有个监听的事件的,可是我忘了是啥了,面试官说也行)css定位百度(很惊奇的是面试个人三个面试官都是女生,简直了)一面css position的几种值与区别闭包偏向于什么语言?html、css or javascript开发中偏于jQuery仍是原生js为何选择原生js?最近作过的项目那个系统还在用吗你是怎么学的?看英文有障碍吗(卧槽,当时我回答了彻底没有问题,不知道哪里来的自信)二面html5的新功能了解多少说说离线存储它们与cookie的区别this的理解怎么传入thisapply和call的区别项目您说说你github上面那个打字机的效果是怎么实现的(这是我fork了一位小伙伴的,但幸亏我也花了一点时间弄懂了他的作法,要否则确定囧死。插播一个很硬的广告 github.com/sidkwok/typing)前端优化你用过哪些优化(我说了css sprite和减小http请求,顺便引出了webpack,但没想到她也没有问)gulp你是怎么用的jsonp是啥怎么跨域为何要跨域怎么学习的position几种值具体运用是什么display几种值兼容性你懂多少(我就说了Ajax的还有盒子模型,但她说还有不少,但以前我说了没有系统地去学过css,都是不会的时候查文档的,估计由于这样因此她也没有追问下去)说说你了解的框架(我说了react和vue)react你以为怎样(我说了一些组件化和虚拟dom树的东西)AngularJS呢(我说没有学过,但了解过一点,我把我了解的都说了给她听)两个的比较为何你会以为AngularJS笨重?(也是本身的见解,mvc框架嘛,一整套什么都有)jQuery仍是原生js(百度的面试官都问了这个问题,我直接说对于jQuery我并非很熟悉,由于我更喜欢研究原生js。)为何选择原生js(我认为要把原生吃透再去理解其余类库的话会更好一点,她说也是)三面(二面问面试官我表现怎样的时候她说,我能够跟你讲你已通过了,个人助理会跟你通知的。觉得是hr面没想到仍是技术面)介绍本身说说框架比较一下框架你打算怎么去学这些框架据说你在浏览器兼容性这边学习的不是很好(不慌,她只是建议我这方面其实也很重要)对本身的规划喜欢用什么系统来,咱们聊聊人生daocloud一面html语义化h5新标签es6promisepromise解决了你什么问题跨域的方法jsonp怎么用用过什么库gulp的插件用过啥webpack为何要打包 (我说了http请求那点事)介绍一下react组件化是啥你觉的react的优势为何没有选择学习AngularJSflex响应式布局是啥响应式布局是根据什么进行响应css中用什么进行屏幕的断定css中实现阴影的有什么二面点击a标签发生了啥http2您说说说说各类框架聊聊AngularJS(说了个人理解,但不怎么了解)那你熟悉哪一个框架(正在玩React,vue也懂一点)你给我说说你那个博客生成器(github.com/sidkwok/tech-dairy)(我知道我知道,不少广告!)聊聊项目聊聊模块化吧sass你怎么用gulp用过啥介绍一下webpack实现sum(2,3);sum(2,3,4);sum(2,3,4,5);(我用了比较原始的方法,if来判断)那若是sum里面的参数不肯定呢(提取arguments的长度,用for循环)你知道伪数组吗?ok, 再来一个数组去重吧(这太经典了吧)若是能帮到你,打赏我吧~