Javascript Tips(1)
项目中遇到的问题总结,怕以后会忘记,遂在此记录一下。
- 1. 内部函数的变量 与 外部的变量 重名时 的相互关系
- 2. 函数形参 与 实参 关系
- 3. var 的声明
- 4. 检测滚动事件(scroll down / scroll up)
- 5. documentElement 、 window.scrollY 、 window.pageYOffset
- 6. 注意字符串拼接时的数学计算
- 7. 对象间复制
- 8. 调用浏览器全屏模式
- 9. 几种js运算
Math
vsBitwise
1. 内部函数的变量 与 外部的变量 重名时 的相互关系
① 外部变量 与 函数形参 重名 —— 两者互不影响(函数内部只用来调用,外部变量不会被重新赋值)
var x = { }, b= 123
function define(x, b){
x = {a: 22 };
b = "jjj";
}
define(x , b);
console.log(x); // Object {} 未变化
console.log(b); // 123
var x = { }, b= 123
// var x = { a:123 } 这样定义时,也会被函数重新定义。 因为传递时,实参只是 x,而非x.a ,因此函数内部会把 x.a看出新的变量。
function define(x, b){
x.a= 22; // 注意与上者的区别, 此时相当于 定义了一个新的全局变量 x.a
b = "jjj"; // 此时相当于 只重新定义了 形参,但外部变量未不会重定义。
console.log(arguments[1]); // 可用此做测试,第二个形参被改变了,输出 "jjj"
}
define(x , b);
console.log(x); // Object {a:22}
console.log(b); // 123
② 外部变量 与 函数形参 无重名 —— 若函数内使用的是全局变量,则重新覆盖外部的。否则互不影响
var x = { }, b= 123
function define(){
x.a= 22; // 亦可写为x = {a: 22 };
b = "jjj"; // 与外部的 b 类型不一样
}
define();
console.log(x); // Object {a:22}
console.log(b); // “jjj”
2. 函数形参 与 实参 关系
1. 调用时实参与定义时形参数量一致时,实参与arguments互相影响,修改其中的一个其对应的也会被修改。
function func(x,y){
//alert(x);
y = 6;
console.log(arguments[1]);
}
func(3, 2); // --> 6
2. 实参与形参数量不一致时,不关联,不互相影响。
function func(x,y){
//alert(x);
y = 6;
console.log(arguments[1]);
}
func(3); // --> undefined
参考:
[1] http://www.cnblogs.com/snandy/archive/2011/03/17/1987084.html
3. var 的声明
如果变量在中间 声明,javascript会默认提到首行,但不执行,只有到该行才会执行。
function callName(){
alert(name);
var name = "marry";
}
callName(); // 提示undefined , 此时只声明了 var name, 但未赋值 name = "marry";
参考:
[1] javascript函数内部用var声明临时变量需要注意的
4. 检测滚动事件(scroll down / scroll up)
检测滚动:
Firefox: dom.on('DOMMouseScroll',function(){} );
IE \ Opera \ Safari:mousewheel
// Jquery
var lastScrollTop = 0;
$(window).scroll(function(event){
var st = $(this).scrollTop();
if (st > lastScrollTop){
// downscroll code
} else {
// upscroll code
}
lastScrollTop = st;
});
// Firefox
$('#elem').bind('DOMMouseScroll', function(e){
if(e.originalEvent.detail > 0) {
//scroll down
console.log('Down');
}else {
//scroll up
console.log('Up');
}
//prevent page fom scrolling
return false;
});
// IE, Opera, Safari
$('#elem').bind('mousewheel', function(e){
if(e.originalEvent.wheelDelta < 0) {
//scroll down
console.log('Down');
}else {
//scroll up
console.log('Up');
}
//prevent page fom scrolling
return false;
});
5. documentElement 、 window.scrollY 、 window.pageYOffset
IE下会分quick mode, standard mode两种,
quick mode下
For cross-browser compatibility, use window.pageYOffset instead of window.scrollY.Additionally, older versions of Internet Explorer (< 9) do not support either property and must be worked around by checking other non-standard properties. A fully compatible example:
var x = (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
var y = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
或者
return window.pageYOffset || documentElement.scrollTop || body.scrollTop || 0;
// or this
Math.max(window.pageYOffset, documentElement.scrollTop, body.scrollTop)
附:
测试结果
各浏览器对 document、document.body、document.documentElement 对象的 onscroll 事件支持情况
6. 注意字符串拼接时的数学计算
不加括号的则直接拼接,不会计算
var a =1, b =2;
var s = 'xxx' + a + b + 'xxx' // xxx12xxx
var s = 'xxx' + (a + b) + 'xxx' // xxx3xxx
7. 对象间复制
如果直接定义,改变现有对象,则会影响原有对象
var a = {s:123 }
var b = a
b.s = 333
a // {s:333}
因此,最简洁方法,使用jquery的 $.extend
var b = $.extend({}, a, {s:333})
此时a
对象不会受影响
同时,可以利用此特性,共享数据
var x = {a:33, b: 22}
x.share = x
x.share.a =44 // 此时,x.a = 44
8. 调用浏览器全屏模式
addEventListener("click", function() {
var el = document.documentElement,
rfs = el.requestFullScreen || el.webkitRequestFullScreen || el.mozRequestFullScreen;
rfs.call(el);
});
9. 几种js运算 Math
vs Bitwise
Math.round
—— 四舍五入
Math.ceil
—— 向上取整
Math.floor
—— 向下取整(只能是数字,但纯数字的字符串也可以)
Math.floor('12ppp') // NaN
Math.floor('12') // 12
parseInt
—— 向下取整(可将字符串转为数字)
parseInt('12ppp') // 12
以上四种,parseInt
最慢
最快的是 位运算, 其次是Math
, parseInt
最慢
测试结果:
http://jsperf.com/math-floor-vs-math-round-vs-parseint/55
http://jsperf.com/math-ceil-vs-bitwise
Math.ceil
var f = (n << 0),
f = f == n ? f : f + 1;
关于小数点截取,舍位运算:
思路如下:乘以10的N次方,向下取整,再除以10的N次方(N为小数位数)
( Math.floor( num * Math.pow(10, digits) ) / Math.pow(10, digits) ).toString()
需要toString
,由于浮点运算的准确性问题,详见此 .toFixed() returns a string in JavaScript