【问题标题】:javascript var vs this [duplicate]javascript var vs this [重复]
【发布时间】:2014-12-21 12:48:40
【问题描述】:

如果我的代码看起来像这样,使用 var 与 this 的首选方法是什么?

function MyObject() {
    var self = this;

    var a = 1;
    this.b = 2;

    var innerMethod = function() {

        logMessage(a); 
        logMessage(self.b); 
    }
}

据我了解,只要 MyObject 存在,var 就会一直存在,所以这和使用 this 不一样吗?

编辑:

为了进一步澄清这个问题,我只对从对象内部访问变量感兴趣,而不是从外部访问。

【问题讨论】:

标签: javascript variables


【解决方案1】:

使用var a,您无法访问范围外的变量,但是在创建对象时可以访问使用this 分配的变量

当我们希望属性与对象的生命周期一起存在时,我们将属性添加到 this。我们使用 var 作为局部变量。

“我只对从对象内部访问变量感兴趣, 不是从外面来的。”

如果您只想在函数内部而不是外部使用,则此语句的答案是使用var,因为用 var 定义的变量只能被声明它们的范围内或词法嵌套范围内的代码访问。

因此,正如 Shomz 建议的那样,您可以将其检查为:

var o = new MyObject();

a 将是未定义的,因为它是用var 定义的

  o.a; // undefined

而 b 将在 this 上返回 2

 o.b; // 2

【讨论】:

    【解决方案2】:

    如果你定义一个变量为var,那么它的作用域就被限制在函数内(从外面看不到)。在 OO 术语中,它有点像私有财产,实际上根本不是财产。

    如果您将变量定义为属性 (this.name),则可以从外部访问它。

    函数也是如此。在函数范围内声明但未分配给属性的函数只能从内部可见。如果将函数分配给属性,则可以从外部访问该函数(只要该属性一直指向该函数)。

    function Person(){
    
        // Declared variable, function scope
        var name = "John";          
    
        // Property        
        this.surname = "Doe";       
    
        // Assign anonymous function to property
        this.getName = function(){  
            return name;
        }
    
        // Assign anonymous function to property
        this.getSurname = function(){ 
            return this.surname;
        }
    
        // Declare function
        function saluteCasually(){      
            console.log("Hi folks!");
        }
    
        // Declare function
        function salutePolitely(){          
            console.log("Nice to meet you");
        }
    
        // Assign (not anonymous) function to property
        this.salutePolitely = salutePolitely;
    
    }
    
    var person = new Person();
    
    console.log(person.name);           // undefined
    console.log(person.getName());      // "John"
    console.log(person.surname);        // "Doe"
    console.log(person.getSurname());   // "Doe"
    
    person.saluteCasually(); // Error: person has not a property "saluteCasually".
    person.salutePolitely(); // Prints "Nice to meet you";
    
    person.salutePolitely = function(){ // Properties can be messed with from anywhere!
        console.log("Bananas");
    }
    person.salutePolitely(); // Prints "Bananas";
    

    【讨论】:

    • 你为什么要这样做? this.salutePolitely = 礼节礼貌;而不是直接 this.salutePolitely = function(){ }
    • @Toniq 我认为它至少具有三个(也许是主观的)优势。 (1) 即使属性的值是从外部更改的,也可以从构造函数的范围访问命名函数。 (2) 构造函数中的代码更简洁一些,因为您没有到处都有this 或self。 (3) 构造函数中的代码更简洁,因为您在视觉上将函数的实现与它是否是公共的分开。首先定义所有函数,然后只将公共函数分配给属性,因此您可以一目了然地看到哪些是公共的,哪些不是。
    • saluteCasually 函数的作用域是什么?
    • @ssal 函数 saluteCasually() 的范围仅限于声明它的函数 Person。 Person()内的所有代码都可以看到saluteCasually()。请注意,每次调用 Person() 时都会创建函数 saluteCasually() 的新“实例”。
    【解决方案3】:

    这取决于您想要什么,在函数内部使用 VAR 不会使其在函数范围之外可访问,但从性能的角度来看,如果您使用对象,请将所有内容都保留在其中,您已经将此对象存储在记忆为什么要再定义另一个变量。

    如 Memory Analysis 101 form chrome devtools 文档中所说:

    一个对象可以通过两种方式持有内存:直接由对象本身持有,以及隐含地持有对其他对象的引用,从而防止它们被垃圾收集器(简称 GC)自动释放。

    对象本身持有的内存大小称为浅大小。典型的 JavaScript 对象会保留一些内存用于描述和存储即时值。

    通常,只有数组和字符串可以具有显着的浅大小。但是,字符串通常主要存储在渲染器内存中,只在 JavaScript 堆上暴露一个小的包装器对象。

    尽管如此,即使是一个小对象也可以通过防止其他对象被自动垃圾收集过程丢弃而间接持有大量内存。当对象本身被删除,并且其依赖对象无法从 GC 根访问时,将释放的内存大小称为保留大小。

    Devtools Docs

    【讨论】:

    • 这可能是最好的答案。
    • 所以使用它是更好的性能明智?我对此没有任何问题,除了带有前缀 self 的代码看起来很乱。无处不在。
    • 它与在任何地方使用 var 一样,我大部分时间都使用前缀“vars”,所以当我看到 var 时它是一个新变量,当我看到 vars 时它是一个使用它的变量。所以这取决于你,你可以让它看起来凌乱或看起来很好。
    【解决方案4】:

    如果你想在实例化对象后使用属性,var 将不起作用,见下文:

    function MyObject() {
        var self = this;
    
        var a = 1;
        this.b = 2;
    
        var innerMethod = function() {
    
            logMessage(a); 
            logMessage(self.b); 
        }
    }
    
    var o = new MyObject();
    console.log(o.a); // undefined
    console.log(o.b); // 2

    【讨论】:

    • 我明白这一点,请阅读我的编辑。
    • 在这种情况下,您可以只使用var。
    猜你喜欢
    • 2017-09-18
    • 2016-04-05
    • 2018-06-08
    • 2018-09-24
    • 2012-09-04
    • 2011-07-18
    • 1970-01-01
    • 2014-03-08
    • 2018-03-13
    相关资源
    最近更新 更多