您的位置:首页 > Web前端 > JavaScript

【JavaScript学习笔记】JavaScript踩坑

2018-03-30 11:52 267 查看
使用js的过程中出现过一些意向不到的输出,在这里做个整理,已备查阅。
一:["0", "1", "2"].map(parseInt)原因:输出结果为[0, NaN, NaN]。原因是map传递给parseInt的参数为3个,分别是element,index,array,指元素的值,索引,整个数组。parseInt接收2个参数,第一个为待转换字符,第二个为进制(2-36,0代表10进制)。当element为"1"时,index为1,不满足2-36之间;当element为"2"时,index为2,二进制时不能有数字大于等于2,因此仍是NaN。
二:NaN === NaN
NaN == NaN原因:返回值均为false,false。NaN不等于自身,要判断是否是NaN,要用isNaN()方法。isNaN(NaN)三:
在尝试自己写双向绑定时,发现通过Object.defineProperty()方法设置属性时,无法通过set外部修改属性的值,如下:var obj = {};
Object.defineProperty(obj, 'txt', {
get: function () {
return obj;
},
set: function (newValue) {
document.getElementById('input').value = newValue;
document.getElementById('show').innerHTML = newValue;
}
});
document.getElementById('input').addEventListener('keyup', function (e) {
obj.txt = e.target.value;
}); 在console中打印obj.txt,输出为undefined,说明obj.txt = e.target.value仅将将值传进set函数,并未真正改变obj.txt的值。尝试在set中赋值,如下:var obj = {};
Object.defineProperty(obj, 'txt', {
get: function () {
return obj;
},
set: function (newValue) {
obj.txt = newValue;
document.getElementById('input').value = newValue;
document.getElementById('show').innerHTML = newValue;
}
});
document.getElementById('input').addEventListener('keyup', function (e) {
obj.txt = e.target.value;
}); 会发生死循环,因为在set中又进行了赋值,会再次调用set。
解决办法,构造函数,保存变量。function defineProperty(obj, key){
var val;
Object.defineProperty(obj, 'txt', {
get: function () {
return val;
},
set: function (newValue) {
if(newValue === val){
return;
}
val = newValue;
document.getElementById('input').value = newValue;
document.getElementById('show').innerHTML = newValue;
}
});
}
var obj = {};
defineProperty(obj, 'txt');
document.getElementById('input').addEventListener('keyup', function (e) {
obj.txt = e.target.value;
}); 四:0.2-0.1 == 0.3-0.2结果为false,因为0.2-0.1=0.1,0.3-0.2=0.09999999。
五:var a = [];
for (var i = 0; i<3; i++){
a[i] = function () {
console.log(i);
};
}
a[0]();输出为3。a[i]绑定的i为全局变量i,当调用a[i]时,会输出全局变量i。var a = [];
for (let i = 0; i<3; i++){
a[i] = function () {
console.log(i);
};
}
a[0]();输出为0。a[i]绑定局部变量i,因此每次声明都会重新分配一个i给a[i],因此当调用a[i]时,输出的是单独分配的i。
六:
参考阮一峰的ESMAScript6入门,var变量提升会导致如下输出。var tmp = new Date();

function f() {
console.log(tmp);
if (false) {
var tmp = 'hello world';
}
}

f(); // undefinedvar会“穿过”if作用域,因此相当于外层会先声明var tmp,此时tmp未赋值,因此打印undefined。
七:function test(x) {
console.log(x);
var x = 2;
console.log(x);
}

test(1);输出为1,2。for (var x = 0; x < 3; x++) {
console.log(x);
var x = 2;
console.log(x);
}输出为0,2。上面两个例子说明function、for括号内的作用域是花括号{}的父作用域。for (var x = 0; x < 3; x++) {
let x = 2;
console.log(x);
}输出为3个2。此时内部使用let重新声明x,但不会改变圆括号内父作用域的同名变量。
八:var test1 = [1, 2],
test2 = 3;

function func1(test) {
test[0] += 1;
}

function func2(test) {
test += 1;
}

func1(test1);
func2(test2);
console.log(test1);//[ 2, 2 ]
console.log(test2);//3函数参数传递是按值传参,但当传入的是对象时,传入的是指向对象的指针。因此在函数内修改对象会改变对象本身。
九:function test (x, x, x) {
console.log(x);
}
test(1, 2, 3);//3非严格模式下,函数可以有同名参数,后面的会覆盖前面的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: