-
::before 和 :after中双冒号和单冒号 有什么区别?解释一下这2个伪元素的作用
经常会遇到的的伪元素有:::before, ::after
,伪类包括::focus, :hover, :link
。
在css2中,对两者没有特别的区分,单冒号和双冒号都可以;css3中的伪元素需要用双冒号表示。
CSS3伪类和伪元素的特性和区别
:before和::before的区别 -
undefined与null的区别
js最早只有null,后来设计者认为null是个对象,需要一个非对象的类型,进而引入了undefined,其实两者差别不大。
-
null:
- 转为数字为0
- 作为函数的参数,表示该函数的参数不是对象
- 作为对象原型链的终点
-
undefined:
- 变量被声明了,但没有赋值时,就等于undefined。
- 调用函数时,应该提供的参数没有提供,该参数等于undefined
- 对象没有赋值的属性,该属性的值为undefined
- 函数没有返回值时,默认返回undefined
有必要解释下undefined:在IE8以下的浏览器,undefined是可以把覆盖的;在IE8+的浏览器中,undefined是不可以被覆盖的。因此早期的框架需要用函数多一个参数的方式来显示指定undefined,防止其被覆盖:
(function(a,b,undefined){
})("arg1","arg2");//最后一个形参不传值,则没传值得形参值为undefined类型
同理,判断一个值是不是undefined的最好办法是typeof
,而不是直接对比值:
typeof(value) === 'undefined'
value === undefined // undefined有被覆盖的危险
当然 可以采用通用的判断类型的方式进行判断:
var o = {};
o.toString.call(window.aaa).toLowerCase() // [object undefined]
还可以采用下面的方式:(events模块采用的方法)
return value === void 0; //
参考: 双面undefined
-
['1', '2', '3'].map(parseInt)
的结果为什么是1, NaN, NaN
?
parseInt接受两个参数:数字和进制。
map会给callback函数提供三个参数,分别是值、索引和数组本身。
因此执行的结果应该是:parseInt(1,0), parseInt(2,1), parseInt(3,2)
-
use strict
的作用 -
消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为
-
消除代码运行的一些不安全之处,保证代码运行的安全
-
提高编译器效率,增加运行速度
-
为未来新版本的Javascript做好铺垫
禁止以下用法:
-
不允许一个变量没有声明就赋值,默认是全局变量
-
with和eval的使用
-
禁止this指向window
-
对象重名属性,函数重名参数
-
怎么利用js检测浏览器是否支持某个css特性
判断DOM元素的style属性,如:document.body.style
里是否含有这个属性。程序如下:
var supports = (function() {
var div = document.createElement('div'),
vendors = 'Khtml O Moz Webkit'.split(' '),
len = vendors.length;
return function(prop) {
if (prop in div.style) return true;
if ('-ms-' + prop in div.style) return true;
prop = prop.replace(/^[a-z]/, function(val) {
return val.toUpperCase();
});
while (len--) {
if (vendors[len] + prop in div.style) {
return true;
}
}
return false;
};
})();
// use
if (supports('textShadow')) {
document.documentElement.className += ' textShadow';
}
-
0.1+0.2 为什么不等于0.3 而是0.30000000000000004
计算机中数字的表示都是通过二进制实现的。0.1到0.9的9个小数中,只有0.5是可以准确表示的,其余的几个都是一种近似的表示;因此数字相加过程中的精度丢失是个很正常的事情。
JavaScript奇味探索 -
call和apply的第一个参数是null/undefined是什么意思?
非严格模式下,是把函数的执行环境指定为全局变量(window或global);严格模式下不进行转换,传入什么是什么:
function aa(){console.log(this);}
aa.call(null) // 严格模式 输出null; 非严格模式 输出window
- 为什么 parseInt(0.0000008) === 8?
当小数点后面大于等于7为的时候,会转成科学计数法。因此会有以下的转换:
parseInt(0.0000008) == parseInt('8e-7') == 8
parseInt(0.000008) == 0
Paste_Image.png
- 一道题目的思考:
var a = {n:1};
var b = a; // 持有a,以回查
a.x = a = {n:2};
alert(a.x);// --> undefined
alert(b.x);// --> {n:2}
关键是a和a.x赋值的时候,对象的指向:
Paste_Image.png-
浏览器缓存控制
Last-Modified和if-modified-since
服务端在Response Header中返回 Last-Modified,下次请求的时候浏览器带上 if-modified-since字段,服务器依据此判断是不是有更新。
expires
过期时间,如果没有过期
etag和if-none-match
根据etag是不是一致决定要不要走缓存,但是由于etag在分布式服务器中不一致,不推荐使用。
cache-control:max-age=秒
通过max-age,去更新expires时间:Expires =max-age + “每次下载时的当前的request时间”
浏览器缓存详解:expires,cache-control,last-modified,etag详细说明 -
script中的async defer:
-
<script src="script.js"></script>
:
没有 defer或 async,浏览器会立即加载并执行指定的脚本,“立即”指的是在渲染该 script 标签之下的文档元素之前,也就是说不等待后续载入的文档元素,读到就加载并执行。 -
<script async src="script.js"></script>
:
有 async,加载和渲染后续文档元素的过程将和 script.js 的加载并行进行(异步),加载完成后立即执行。 -
<script defer src="myscript.js"></script>
:
有 defer,加载后续文档元素的过程将和 script.js 的加载并行进行(异步),但是 script.js 的执行要在所有元素解析完成之后,DOMContentLoaded 事件触发之前完成。
采用了defer机制时,需要在 DOMContentLoaded 事件中进行DOM操作,如Angular1.x的手动bootstrap。
defer和async的区别
- observable数据监听的实现
数据observable的实现方法包括以下几种:
- 脏检测(Angular)
- Object.defineProperty(vue avalon)
- 低版本浏览器借助VbScript(avalon)
- 属性转成函数:(knockout)
function observable(val){ return function(newVal){ if (arguments.length > 0){ val = newVal; notifyChanges(); }else{ return val; } } } var data = {}; var data.a = observable(1); var value = data.a() //取值 data.a(2); //赋值
- Es6 Proxy:proxy
上述是是现在比较流行的方法。数组的话,需要对其方法进行监听, 如push/unshift/splice
这三种添加方法会对新加对象进行监听,而其他函数则直接触发依赖更新。如: [1,2,3]
这种数组,由于元素是简单对象,当其改变的时候不会触发模块更新。
网友评论