eval()方法的替换方法
js里有个神奇的方法:eval(),但是不建议使用,原因看看知乎的回答,但是有时候我们确实需要一个这样作用的方法,下面是替换的方法:
来源于这位前辈的文章
1  | //计算表达式的值  | 
解释一下:
我们创建方法通常有三种方式:
1  | /*1.函数声明*/  | 
所以,利用Function()构造方法就可以实现eval()的功能
对象的属性描述符
对象有很多属性来描述这个对象的特点,这些属性就叫属性描述符。属性描述符有两种主要形式:数据描述符 和 存取描述符 , 详细请参看 这儿
- 两者都是的描述符:
configurable: 当且仅当该属性为true时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false, 当为false时, 除writable特性外的其他特性不可被修改enumerable: 当且仅当该属性为true时,该属性才能够出现在对象的枚举属性中。默认为false, 当一个属性不可被枚举时,使用Object.keys(obj)是获取不到该属性的,此时可以用Object.getOwnPropertyNames(obj)
 - 数据描述符:
value: 可以是任何有效的值(数值,对象,函数等)。默认为undefinedwritable: 当且仅当该属性为true时,value才能被赋值运算符改变。默认为false
 - 存取描述符:
get: 一个给属性提供getter的方法,如果没有getter则为undefined。该方法返回值被用作属性值。默认为undefinedset: 一个给属性提供setter的方法,如果没有setter则为undefined。该方法将接受唯一参数,并将该参数的新值分配给该属性。默认为undefined
 
Object 有两个方法可以操作属性描述符,分别是:Object.defineProperties(obj, props) 与 Object.defineProperty(obj, prop, descriptor) ,我们知道, vue 的双向绑定就是利用 defineProperty 定义 get 与 set 实现的。
操作的描述符必须是这两种形式之一,不能同时是两者。所以下面这种是错误的:
1  | Object.defineProperty(obj, "conflict", {  | 
我们默认新创建的对象那些 configurable 等描述符对应的值都是 true,他们继承自原型链。如果要自己定义描述符, 用 Object.create(null) 来创建对象
setTimeout(fun,time)与setInterval(fun,time)
返回值是个唯一标识符,通常是个数字。 用于清除定时器和gc回收,比如:
1  | var timer = setTimeout(function() {}, 500)  | 
注意:
在
time的延迟之后才可以执行第一次,而不是马上开始执行。即使是setTimeout(fun, 0),也是在主线程执行后再执行fun.1
2
3
4
5
6setTimeout(function() {
console.log('a')
}, 0)
console.log('b')
// b
// a要想循环体立即执行,可以这样:
1
2
3
4
5
6function hand() {
setTimeout(function() {
hand()
}, 500)
console.log(new Date())
}
方法内部的return false
经常可以看到这样的语句:
1  | $('a').bind('click',test);  | 
return false等于e.preventDefault()
从一个数组中删除子数组
先看下第一版:
1  | function del(arr, delArr) {  | 
乍看之下没问题,但有问题。
1  | let arr = [1,2,3,4,5];  | 
原因很简单,先删除了4,此时5的下标已经往前移动了1,然而循环的i已经到了5当前的下标,所以就跳过了5的判断。下面来个修复版1:
1  | function del(arr, delArr) {  | 
只是换了两个循环的顺序,就ok了。因为两个数组里没有重复数据,所以在删除一个元素之后可以通过break直接进行下一次外层循环。得到正确的结果。试试下面的例子:
1  | let arr = [1,2,3,4,4,5];  | 
可能是del方法里用了break的原因,去掉之后发现还是同样的结果。原因同第一版。
再来看看修复版2:
1  | function del(arr, delArr) {  | 
再试试上面的例子,得到的结果正确。不论是数组中有没有重复数据,都可以得到正确的结果。原因想必大家一看就明白了,对arr的循环一定要倒序,这样才不会跳过某一项。


