:
一些编程题
js算法题
答:
参考自:
ie6,7不支持display:inline-block
参考自:
答:
在服务器配置entity-tag if-none-match
(1) 可搜索型
(2) 开放性
(3) 费用
(4) 易用性
(5) 易于开发
(1) 多媒体处理
(2) 兼容性
(3) 矢量图形 比svg,canvas优势大很多
(4) 客户端资源调度,比如麦克风,摄像头
参考:
css3新特性:
参考:
参考:
答:
答:
参考自:
答:
.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) 移开文字:
<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达到隐藏文本的效果
<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值
<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”,来达到隐藏文本效果,这样阅读器就能完全阅读到,而且又达到了图片替换文本的效果
<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标签来放置背景图片,并对其进行绝对定位,使用覆盖文本,达到隐藏替换文本的效果。
<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) 设置字体为微小值,但这里需要注意一点不能忘了设置字体色和替换图片色一样,不然会有一个小点显示出来
<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属性来实现图片替换文本的效果
<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;
}
参考自:
<!--[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。参照下题“的答案。
2)规范命名。尤其对于没有语义化的html标签,例如div,所赋予的class值要特别注意。
2)抽取可重用的部件,注意层叠样式表的“优先级”。
针对打印机的样式: @media print{...}
参考:
答: 优点:
参考:
参考:
作者:张靖超链接: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盒子模型)。
因而解决兼容型为题最简洁和值得推荐的方式是:下述的第一条。
参考:
参考:
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媒体查询
答:
display:none或者visibility:hidden,overflow:hidden。
一般来讲,越详细的级别越高。css优先级包含四个级别(文内选择符,id选择符,class选择符,元素选择符)以及各级别出现的次数。根据这四个级别出现的次数计算得到css的优先级
参考:
答:
答: bfc指的是block formatting context, 它提供了一个环境, html元素在这个环境中按照一定规则进行布局. 一个环境中的元素不会影响到其他环境中的布局. 决定了元素如何对其内容进行定位, 以及和其他元素的关系和相互作用.
其中: fc(formatting context): 指的是页面中的一个渲染区域, 并且拥有一套渲染规则, 它决定了其子元素如何定位, 以及与其他元素的相互关系和作用.
bfc: 块级格式化上下文, 指的是一个独立的块级渲染区域, 只有block-level box参与, 该区域拥有一套渲染规则来约束块级盒子的布局, 且与区域外部无关.
参考:
答:
参考自:
答:
参考自:
答:
答:
答:
答: 采用统一编码utf-8模式
<meta http-equiv=“content-type” content=“text/html; charset=字符集">
不写,根据浏览器默认字符集显示
charset=gb2312 简体中文
charset=big5 繁体中文
charset=euc_kr 韩语
charset=shift_jis 或 euc_jp 日语
charset= koi8-r / windows-1251 俄语
charset=iso-8859-1 西欧语系(荷兰语,英语,法语,德语,意大利语,挪威语,葡萄牙语,瑞士语.等十八种语言)
charset=iso-8859-2 中欧语系
charset=iso-8859-5 斯拉夫语系(保加利亚语,byelorussian语,马其顿语,俄语,塞尔维亚语,乌克兰语等)
charset=uft-8 unicode多语言
参考自:
为前端开发者提供自定义的属性,这些属性集可以通过对象的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
答:
sessionstorage 和 localstorage 是html5 web storage api 提供的,这两种方式都允许开发者使用js设置的键值对进行操作,在在重新加载不同的页面的时候读出它们。这一点与cookie类似。可以方便的在web请求之间保存数据。有了本地数据,就可以避免数据在浏览器和服务器间不必要地来回传递。 sessionstorage、localstorage、cookie都是在浏览器端存储的数据, 其中sessionstorage的概念很特别,引入了一个“浏览器窗口”的概念。 sessionstorage是在同源的同窗口(或tab)中,始终存在的数据。也就是说只要这个浏览器窗口没有关闭,即使刷新页面或进入同源另一页面,数据仍然存在。关闭窗口后,sessionstorage即被销毁。同时“独立”打开的不同窗口,即使是同一页面,sessionstorage对象也是不同的。 web storage 数据完全存储在客户端, 不需要通过浏览器的请求将数据传给服务器, 因此比cookies能够存储更多的数据,大概5m左右 web storage带来的好处:使用 local storage和session storage主要通过在js中操作这两个对象来实现,分别为window.localstorage和window.sessionstorage. 这两个对象均是storage类的两个实例,自然也具有storage类的属性和方法。 减少网络流量:一旦数据保存在本地后,就可以避免再向服务器请求数据,因此减少不必要的数据请求,减少数据在浏览器和服务器间不必要地来回传递。 快速显示数据:性能好,从本地读数据比通过网络从服务器获得数据快得多,本地数据可以即时获得。再加上网页本身也可以有缓存,因此整个页面和数据都在本地的话,可以立即显示。 临时存储:很多时候数据只需要在用户浏览一组页面期间使用,关闭窗口后数据就可以丢弃了,这种情况使用sessionstorage非常方便。
答:
答:
答:
参考:
参考自:
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 中主要由以下五种使用场景。
参考:
答: 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. 线性探测法:
使用数组中的空位解决碰撞冲突
参考:
答:
参考自:
参考:
(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描绘了一个层次化的节点树, 允许开发人员添加, 移除和修改页面的某一部分.
参考:
答: 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; }
参考:
答:
答: 捕获->处于目标->冒泡,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是处理异步操作的一种模式
参考:
答: getelementbyid() getelementsbytagname()
节点遍历:
答: 可以自定义一个函数
.border-radius(@values) {
-webkit-border-radius: @values;
-moz-border-radius: @values;
border-radius: @values;
}
div {
.border-radius(10px);
}
答:
答:
答:
我在回答这个题的时候说是两个事件, 先执行捕获的后执行冒泡的. 其实是不对的.
绑定在目标元素上的事件是按照绑定的顺序执行的!!!!
即: 绑定在被点击元素的事件是按照代码顺序发生,其他元素通过冒泡或者捕获“感知”的事件,按照w3c的标准,先发生捕获事件,后发生冒泡事件。所有事件的顺序是:其他元素捕获阶段事件 -> 本元素代码顺序事件 -> 其他元素冒泡阶段事件 。
参考:
答:
块级作用域引入了两种新的声明形式,可以用它们定义一个只存在于某个语句块中的变量或常量.这两种新的声明关键字为:
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深克隆
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次以后停止,怎么办
想到了用闭包, 但是写错了...
一开始是这么写的
//注意!!这种写法是错误的!!!
for(var i=0; i<olis.length; i++){
olis[i].onclick = function(){
return (function(j){
alert(j);
})(i);
}
}
但是这样做的话, 点击所有的li都会弹出最后一个序号. 因为每个li对应的onclick事件的函数, 返回的那个函数的参数还是最后的那个i, 并没有改变. 应该是这么写
方法1 :
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的值.
另一种实现方法:(立即执行函数)
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: 设置属性:
var oli = document.getelementsbytagname('li');
for(var i=0; i<oli.length; i++){
oli[i].setattribute("onclick", "alert("+i+");");
}
方法4: 设置index保存
for(var i=0; i<oli.length; i++){
oli[i].index = i;
oli[i].onclick = function(){
alert(this.index);
}
}
或者也可以用事件代理来做.
参考:
方法1. 创建一个新的临时数组来保存数组中已有的元素
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. 使用哈希表存储已有的元素
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判断数组元素第一次出现的位置是否为当前位置
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. 先排序再去重
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, 方法四看着就效果还不错了
而第二种方法永远是最好的, 但是是以空间换时间
全部代码如下:
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));
参考:
了解前后端分离吗(当时真不了解,但他细心地给我解释了一下,还建议我去看淘宝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, 再来一个数组去重吧(这太经典了吧)
- mvc理解
二面问
项目中你解决过哪些比较困难的问题
参考博文: 不完全的搜狐前端面经
[这个姑娘博客里有超多干货~]
前端网:
markyun.github:前端开发面试题
如对本文有疑问, 点击进行留言回复!!
清除新版Google Chrome浏览器中表单控件(input,button...)默认的黑色边框
荐 20200714——git/mac配置/项目运行步骤/一些报错
antd 菜单组件 使用时报错:Cannot read property ‘isRootMenu‘ of undefined
CSS|div的style=“background-image: url(img/a.bmp)图片显示不出来
硬件仪表盘账号建立指导(一) --WHQL认证测试结果提交账号(一)
cookie的规范Cookie的不可跨域名性或Cookie与域名的关系
网友评论