Javascript编程“陷阱”总结

简介: javascript中有很多陷阱,现在来总结一下:

关于this关键字

首先看一段代码:

var obj = {
    id: "xyz",
    printId: function() {
        console.log('The id is '+ this.id + ' '+ this.toString());
    }
};
obj.printId();   //The id is xyz [object Object]
var callback=obj.printId;
callback();   //The id is undefined [object global]
setTimeout(obj.printId,1000);   //The id is undefined [object Object]

这样就出现问题了,只有obj.printId()返回了我们想要的结果,第二种调用只是个赋值,但this却指向global,第三种调用,this指向Object,但是显然不是我们定义的obj,因此它获取不到id属性。原因就在于,在javascript中,this关键字的指向是在函数调用的时候定义的。callback()在调用的时候,属于全局顶层的函数,已经不是我们定义的obj中的一个函数,所以this指向global,至于setTimeout的回调函数调用方式之所以指向一个Object,这应该和setTimeout这个api的实现方式有关

那我们有没有办法用callback和setTimeout方式显示出正常结果呢?你可以这样写:

obj.printId();   //The id is xyz [object Object]
var callback=function() { obj.printId(); };
callback();   //The id is xyz [object Object]
setTimeout(function() {obj.printId(); },1000);   //The id is xyz [object Object]

关于变量作用域

第一个,最简单的例子:

for(var i = 0; i < 5; i++) {
  console.log(i);   //0 1 2 3 4
}

第二个,加个异步函数,也很简单:

for(var i = 0; i < 5; i++) {
    setTimeout(function() {
        console.log(i);   //5 5 5 5 5
    }, 100);
}

第三个,我们制作一个方法数组:

var data = [];
for (var i = 0; i < 5; i++) {
    data[i] = function foo() {
        console.log(i);
    };
}
data[0](); data[1](); data[2](); data[3](); data[4]();   //5 5 5 5 5

第一个,如我们所想,输出0,1,2,3,4;可是第二个第三个都是5,5,5,5,5.

原因分析:我们在for循环中定义的变量i,在for循环结束后还没有走出它的作用域,也就是说for循环之后,i依然可以访问,值等于最后一次循环后的值,就是5了。第二段代码中,setTimeout的回调函数执行时,for循环已经完成,此时i就是5。同理,第三段代码,在data[i]()执行时,i已经是5了。当然,我们有办法让它显示正确结果,但要增加一个变量,像这样:

for(var i = 0; i < 5; i++) {
    (function() {
        var j = i;
        setTimeout( function() { console.log(j); }, 500*i);   //0 1 2 3 4
    })();
}

bonus:在object外面增加method的方法

var obj1 = { id: "Foo"};
var obj2 = { id: "Bar"};
function f1(a, b) {
    console.log(this, a, b);
}
f1.call(obj1, 'A', 'B'); //Object{id:"Foo"} "A" "B"
f1.apply(obj2, [ 'A', 'B' ]); //Object{id:"Bar"} "A" "B"
目录
相关文章
|
1月前
|
前端开发 JavaScript 开发者
探索JavaScript ES6的八种常见使用技巧:开启现代编程之旅
探索JavaScript ES6的八种常见使用技巧:开启现代编程之旅
|
1月前
|
JavaScript 前端开发 开发者
编程笔记 html5&css&js 071 JavaScript Symbol 数据类型
编程笔记 html5&css&js 071 JavaScript Symbol 数据类型
|
1月前
|
存储 JavaScript 编译器
这款国产中文编程火了!通过文言文编译生成Python、JS、Ruby代码!
这款国产中文编程火了!通过文言文编译生成Python、JS、Ruby代码!
|
1月前
|
JavaScript 前端开发
编程笔记 html5&css&js 079 JavaScript 循环语句
编程笔记 html5&css&js 079 JavaScript 循环语句
|
1月前
|
JavaScript 前端开发 开发者
编程笔记 html5&css&js 078 JavaScript 条件判断语句
条件判断语句是首先要接触的语句。通过条件判断来执行不同的代码块。
|
1月前
|
JavaScript 前端开发 编译器
编程笔记 html5&css&js 077 Javascript 关键字
编程笔记 html5&css&js 077 Javascript 关键字
|
1月前
|
JavaScript 前端开发
编程笔记 html5&css&js 076 Javascript 表达式
编程笔记 html5&css&js 076 Javascript 表达式
|
1月前
|
存储 JavaScript 前端开发
编程笔记 html5&css&js 075 Javascript 常量和变量
编程笔记 html5&css&js 075 Javascript 常量和变量
|
1月前
|
JavaScript 前端开发 程序员
编程笔记 html5&css&js 074 Javascript 运算符
编程笔记 html5&css&js 074 Javascript 运算符
|
1月前
|
JavaScript 前端开发 Java
编程笔记 html5&css&js 073 JavaScript Object数据类型
编程笔记 html5&css&js 073 JavaScript Object数据类型