zoukankan      html  css  js  c++  java
  • js的oop方式和this指针问题

       js的oop其实很简单,function本身就充当了类和构造函数的角色。然后通过传给构造函数的参数,完成类属性的赋值,从而实际化不同的对象。

       可是,js的oop也有很让人头疼的地方,其中之一就是this的指向。在js中,普通的函数,this指向的是window对象,因为所有的全局函数都是window对象的方法。而对于类和对象中的方法,this指向的是这个类和对象。可是,this指针并不是那么老实的,如果在一个类中的方法,调用了另一个类的方法,那么这个this的指向就变得很奇怪了。举个简单的例子。

    var a = 0;
    function test()

    {

       this.a=123;

        this.b = function()

       {

         alert(this.a);

       }

    this.init = function()

    {

    alert(this.a);
        setTimeout(this.b,1000);

    }

    this.init();

    }

    var adang = new test();

    你猜结果会是什么?一开始弹出一个123,然后一秒后又弹出一个123??错!一开始的确是弹出123,一秒后弹出的却是0!因为setTimeout是window对象的方法,所以做为参数被传入setTimeout方法的this.b()函数,运行的闭包空间,对象是window,而不再是test类,this指针指向了window,也就是说,里面的alert(this.a)等于window.a,而不是test.a。

       这的确有点让人费解。想来想去,想到的一个解释是这样的:因为js中对复杂数据类型是通过传址方式进行赋值的,所以setTimeout中的第一个参数,也就是要运行的函数,是传递的this.b()这个方法的地址给setTimeout方法使用的,这个地址保存的是this.b方法中的所有"字符",是个string!!!然后再在setTimeout内部用eval(str)来运行。这么一来,this关键字完全没有连到test类的地址,而是直接使用新闭包的对象。

       这个问题应该怎么解决呢??如果我想在setTimeout里正确运行test类的b方法,正解调用test的属性,应该怎么做呢?方法很简单,去掉this,把a由this.a换成var a,让它从一个公开属性,变成私有属性,因为a定义在test内部的最外一级,所以它的作用域是整个test类,类里的b方法可以调用到它。而它又去掉了this关键字,不会错误地指到别的对象上。

        总结一下,心得就是,在用oop方式写js的时候,少用this关键字,除了必要的方法和属性写成公开属性/方法,应该尽量用var 定义成私有属性/方法。

  • 相关阅读:
    销傲中国式销售过程管理系统功能概述
    真正高效的SQLSERVER分页查询(多种方案)
    request.getScheme()的使用方法
    用户'sa'登录失败(错误18456)解决方案图解
    在SQL Server中创建用户角色及授权
    大话设计模式--外观模式 Facade -- C++实现实例
    大话设计模式--模板方法模式 TemplateMethod -- C++ 实现
    大话设计模式--原型模式 Prototype -- C++实现
    C++拷贝构造函数(深拷贝,浅拷贝)
    大话设计模式--工厂方法模式 Factory Method -- C++实现
  • 原文地址:https://www.cnblogs.com/cly84920/p/4427145.html
Copyright © 2011-2022 走看看