JavaScript中的小技巧和注意点(二)
来源:互联网 发布:大学生防网络诈骗 编辑:程序博客网 时间:2024/05/21 08:48
tip:自己收集的一些前端注意事项
https://github.com/Nirvana-cn/WebTechnology
1.函数优先
函数声明和变量声明都会被提升,但是一个值得注意的细节是函数会首先被提升,然后才是变量
foo();//1var foo;function foo(){ console.log(1);}foo=function(){ console.log(2);};
会输出1而不是2,这个代码片会被引擎理解如下形式:
function foo(){ console.log(1);}foo();//1foo=function(){ console.log(2);};
注意,var foo尽管出现在function foo()…的声明之前,但它是重复的声明(因此被忽略了),因为函数声明会被提升到普通变量之前。
2.循环和闭包
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。
for(var i=1;i<=5;i++){ setTimeout(function timer() { console.log(i); },i*1000);}
正常情况下,我们对这段代码行为的预期是分别输出数字1-5,每秒一个,每次一个,但实际上,这段代码在运行时会以每秒依次的频率输出五次6。
(1)通过立即执行函数IIFE进行修正。
for(var i=1;i<=5;i++){ (function (j) { setTimeout(function timer() { console.log(j); },j*1000); })(i);}
(2)更简单的方法,使用let生成块级作用域。
for(let i=1;i<=5;i++){ setTimeout(function timer() { console.log(i); },i*1000);}
3.被忽略的this
如果你把null或者undefined作为this的绑定对象传入call,apply或者bind,这些值在调用时会被忽略,实际应用的是默认绑定规则
function foo(){ console.log(this.a);}var a=2;foo.call(null);//2
一种非常常见的做法是使用apply()来展开一个数组,并当作参数传入一个函数;类似的,bind()可以对参数进行柯里化。
然而,总是使用null来忽略this绑定可能产生一些副作用,导致一些难以分析和追踪的bug。更安全的做法是传入一个空对象。在JavaScript中创建一个空对象最简单的方法是Object.create(null)。
Object.create(null)和 { }很像,但是并不会创建Object.prototype这个委托,所以它比 { } “更空”
4.隐式丢失
一个最常见的this绑定问题就是被隐式绑定的函数会丢失绑定对象,从而把this绑定到全局对象或者undefined上,取决去是否是严格模式。
参数传递就是一种隐式赋值,因此传入函数时会被隐式赋值。
function foo(){ console.log(this.a)}var obj={ a:2, foo:foo};var a='oops,global';setTimeout(obj.foo,1000);//oops,global
JavaScript环境中内置setTimeout()函数实现和下面的伪代码类似,可以看出obj.foo被赋值给了fn,所以foo中的this被绑定到了全局对象上。
function setTimeout(fn,delay){ //等待delay毫秒 fn();}
5.对象属性存在性
var obj={ a:undefined}
对象属性访问返回值可能是undefined,但是这个值有可能是属性中存储的undefined,也可能是因为属性不存在而返回undefined
"a" in obj;//trueobj.hasOwnProperty("a");//true
但是有的对象可能没有连接到Object.prototype(比如通过Object.create(null)来创建的),这种情况下形如obj.hasOwnProperty()就会失败,这时可以使用一种更加强硬的方法来进行判断。
Object.prototype.hasOwnProperty.call(obj,"a");
6.计时器
由于历史原因,setTimeout()和setInterval()的第一个参数可以作为字符串传入。如果这么做,那么这个字符串就会在指定的间隔之后进行求值(相当于执行eval())
setTimeout('console.log(123)',1000)
7.值和类型
JavaScript中的变量是没有类型的,只有值才有,变量可以随时持有任何类型的值,即一个变量可以现在被赋值为字符串类型值,随后又被赋值为数字类型值。
在对变量执行typeof操作时,得到的结果并不是该变量的类型,而是该变量持有的值的类型,因为JavaScript中的变量没有类型。
已在作用域中声明但还没赋值的变量是undefined。相反,还没有在作用域中声明过的变量是undeclared,让人抓狂的是typeof处理undeclared变量的方式同样返回“undefined”
var a;typeof a;//undefinedtypeof b;//undefined
- JavaScript中的小技巧和注意点(二)
- JavaScript中的小技巧和注意点(一)
- MySQL数据库小技巧(注意点)
- 程序设计中的小技巧和注意
- javascript小技巧(二)
- javascript(注意点) 数据类型和变量
- iOS 小技巧及注意点(OC)
- JAVASCRIPT中的数字,注意点
- javascript中的小技巧
- JavaScript中的小技巧!
- javascript中的小技巧
- JavaScript中的this关键字的用法和注意点
- JavaScript中的this关键字的用法和注意点
- JavaScript中的this关键字的用法和注意点
- JavaScript中的this关键字的用法和注意点
- JavaScript中的this关键字的用法和注意点
- JavaScript中的this关键字的用法和注意点
- JavaScript中的this关键字的用法和注意点
- OC
- Error in invoking target 'client_sharedlib' of makefile '/crm/bip/Oracle_BI1/rdbms/lib/ins_rdbms.mk'
- Zabbix使用微信发送告警
- VC++实现按钮控件的底色、字体、颜色。亲测可用
- android 动画animation setRepeatCount不起作用
- JavaScript中的小技巧和注意点(二)
- Windows下编译libxls32位和64位链接库
- day04_元素案例
- SAA3010T红外解码
- 设置Tomcat的UTF-8编码
- js面试题
- js 各种事件 如:点击事件、失去焦点、键盘事件等
- 进程的状态转换、进程间通信的方式
- SSM 框架搭建