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。同理,第三段代码,在datai执行时,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"
时间: 2024-09-23 06:48:08

Javascript编程“陷阱”总结的相关文章

初学者应该了解的编程陷阱:javascript篇

对于初学编程语言的朋友来说,经常会犯一些比较"经典"的错误.在这一系列文章中,我们将介绍如何让初学编程的朋友避免一些基本的错误,并且了解如何正确的编程和开发代码. 这一篇文章中,我们介绍5个javascript代码开发中需要注意的问题和技巧. 冗余的DOM操作 DOM操作众所周知是比较重量级的.有效的限制交互可以大大的帮助你提高你的代码的性能.看看下面这段代码: // anti-pattern for (var i = 0; i < 100; i++){ var li = $(&

《第三方JavaScript编程》——1.4 第三方开发的挑战

1.4 第三方开发的挑战 你已经了解了第三方JavaScript是编写高度分发应用的一种强大方式.但是编写在其他人网站上执行的脚本,同传统的JavaScript编程相比有一系列独特的挑战.具体而言,你的代码将在一个完全不受控制.一个不同域的DOM环境中执行.这意味着你必须面对一些难以预料的复杂情况,比如未知的网页上下文,一个同其他第一方.第三方脚本共享的JavaScript环境,甚至浏览器的一些限制.我们快速的浏览一下涉及的挑战. 1.4.1 未知的上下文 当一个发布者在他们的Web页面中引入你

深入理解JavaScript编程中的同步与异步机制

  这篇文章主要介绍了深入理解JavaScript编程中的同步与异步机制,不仅仅是AJAX已经深入到了各个角落,Node.js的火爆也让JS的异步编程格外引人注目,需要的朋友可以参考下 JavaScript的优势之一是其如何处理异步代码.异步代码会被放入一个事件队列,等到所有其他代码执行后才进行,而不会阻塞线程.然而,对于初学者来说,书写异步代码可能会比较困难.而在这篇文章里,我将会消除你可能会有的任何困惑. 理解异步代码 JavaScript最基础的异步函数是setTimeout和setInt

百度WEB前端JavaScript编程题和HTML/CSS面试题

文章简介:笔试题,百度流程信息管理部Web前端实习研发工程师. 笔试题,百度流程信息管理部Web前端实习研发工程师. JavaScript编程题1.实现输出document对象中所有成员的名称和类型:2.如何获得一个DOM元素的绝对位置?(获得元素位置,不依赖框架)3.如何利用JS生成一个table?4.实现预加载一张图片,加载完成后显示在网页中并设定其高度为50px,宽度为50px:5.假设有一个4行td的table,将table里面td顺序颠倒:6.模拟一个HashTable类,包含有add

面向对象的JavaScript编程及其 Scope 处理

本文首先对 JavaScript 的机制进行讲解,并结合当前流行的开源 JavaScript 框架讲解如何在 JavaScript 中实现面向对象和继承机制:之后本文将对面向对象 JavaScript 编程中容易引起误解和 Scope 的几个问题做详细阐述:最后针对面向对象的 JavaScript 编程中的 Scope 问题给出几点建议. 面向对象和模拟继承 JavaScript 是一种弱类型解释运行的脚本语言,就语言本身来讲它不是一门面向对象语言.但是我们可以利用一些语言的特性来模拟面向对象编

Javascript编程语言和DOM接口系列教程(1)

Hello,今天开始彬Go将以系列教程的方式为大家讲解Javascript编程语言和DOM接口,本篇教程为该系列的第一部分. 虽然现在一些js框架诸如jQuery.Prototype和MooTools能提高我们的前端开发效率而且很好的解决了浏览器兼容性问题,但我们仍要打好javascript技术基础.Javascript DOM 控制系列教程将告诉你你需要了解的javascript和文档对象模型(DOM)的本质. 引言 JavaScript JavsScript是可以在各种不同环境下使用的动态的

面向对象的JavaScript编程

javascript|编程|对象 面向对象的JavaScript编程对于做过Web程序的人不应该是陌生,初期是用来做一些简单的FORM验证,基本上是在玩弄一些技巧性的东西.IE 4.0引入了DHTML,同时为了对抗Netscape的Javascript,提出了自己的脚本语言JScript,除了遵循EMAC的标准之外,同时增加了许多扩展,如下要提到的OOP编程就是其中的一个,为了命且概念,我以下提到的Javascript都是Microsoft Internet Explorer 4.0以上实现的J

Dojo Javascript编程规范

前言 相当不错的 Javascript 编程风格规范,建议大家采用此规范编写 Javascript.原文链接:http://dojotoolkit.org/developer/StyleGuide . 翻译(Translated by):i.feelinglucky{at}gmail.com from http://www.gracecode.com ,转载请注明出处.作者和翻译者,谢谢配合. 本文地址:http://code.google.com/p/grace/wiki/DojoStyle

深入理解JavaScript编程中的原型概念

  这篇文章主要介绍了深入理解JavaScript编程中的原型概念,包括prototype属性的使用等一些相关知识,需要的朋友可以参考下 JavaScript 的原型对象总是让人纠结.即使是经验丰富的JavaScript专家甚至其作者,经常对这一概念给出很有限的解释.我相信问题来自于我们对原型最早的认识.原型总是与new, constructor 以及令人困惑的prototype属性紧密联系.事实上,原型是一个相当简单的概念.为了更好地理解它,我们需要忘记我们所'学到'的构造原型,然后,追本溯源