eval()方法的替换方法
js里有个神奇的方法:eval()
,但是不建议使用,原因看看知乎的回答,但是有时候我们确实需要一个这样作用的方法,下面是替换的方法:
来源于这位前辈的文章
1 | //计算表达式的值 |
解释一下:
我们创建方法通常有三种方式:
1 | /*1.函数声明*/ |
所以,利用Function()
构造方法就可以实现eval()
的功能
对象的属性描述符
对象有很多属性来描述这个对象的特点,这些属性就叫属性描述符。属性描述符有两种主要形式:数据描述符 和 存取描述符 , 详细请参看 这儿
- 两者都是的描述符:
configurable
: 当且仅当该属性为true
时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。默认为false
, 当为false
时, 除writable
特性外的其他特性不可被修改enumerable
: 当且仅当该属性为true
时,该属性才能够出现在对象的枚举属性中。默认为false
, 当一个属性不可被枚举时,使用Object.keys(obj)
是获取不到该属性的,此时可以用Object.getOwnPropertyNames(obj)
- 数据描述符:
value
: 可以是任何有效的值(数值,对象,函数等)。默认为undefined
writable
: 当且仅当该属性为true
时,value
才能被赋值运算符改变。默认为false
- 存取描述符:
get
: 一个给属性提供getter
的方法,如果没有getter
则为undefined
。该方法返回值被用作属性值。默认为undefined
set
: 一个给属性提供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
的循环一定要倒序,这样才不会跳过某一项。