为什么在JavaScript的构造函数中需要'this'关键字?

时间:2019-04-15 09:01:30

标签: javascript function object scope this

我正在尝试使用JavaScript中的new关键字实例化构造函数。但是,它无法正常工作-

var a = function () {
            abc = function () {
                      return  "abc";
                  }
        }

var obj = new a();

如果我愿意-

obj.a();。它说-

Uncaught TypeError: obj.abc is not a function

但是,如果我只是在没有对象obj的情况下访问它,它将起作用

abc();

但是,如果我对内部函数使用this,则整个问题都可以解决-

var a = function () {
            this.abc = function () {
                           return  "abc";
                       }
        }

所以我的问题是,如果我声明不带'this'关键字的abc(),它的作用域是否不在a函数内。在函数a中声明它时,为什么将其视为全局函数?

3 个答案:

答案 0 :(得分:4)

  

如果我声明不带此关键字的abc(),则其范围不在a()函数内。为什么在函数a中声明它时将其视为全局函数?

在任何地方都没有声明a中的代码分配给一个未声明的变量,该变量创建一个隐式全局(默认为松散模式)。

这是使用严格模式(脚本顶部的"use strict";)的许多良好原因之一。在严格模式下,分配给未声明的变量是一个错误(就像从未声明的变量中读取内容一样)。我的博客文章The Horror of Implicit Globals中有更多内容。


是的,正如您所发现的,this.在JavaScript中从来不是可选的,而在Java或C#中却不是。要在执行a时引用在new a()中创建的实例,必须使用this

侧面说明:JavaScript中压倒性的惯例是构造函数(通过new调用的函数)以大写字母开头。因此,A而不是aExample

var Example = function () {
    this.abc = function(){
        return "abc";
    };
};

var obj = new Example();
console.log(obj.abc());

您可以考虑将abc放在原型上,而不是在每次调用a时都重新创建它:

var Example = function () {
};
Example.prototype.abc = function(){
    return "abc";
};

var obj = new Example();
console.log(obj.abc());

或使用ES2015 + class语法:

class Example {
    abc(){
        return "abc";
    }
}

var obj = new Example();
console.log(obj.abc());

答案 1 :(得分:0)

这是因为您尚未将abc声明为新构造对象的属性-通过省略var关键字将其变为全局可用的函数。如果您希望不使用this就可以访问它,请尝试以下操作:

var a = function() {
  var abc = function() {
    return "abc";
  }
  return { abc };
}

var obj = new a();
console.log(obj.abc());

答案 2 :(得分:-1)

声明一个没有任何按键作用的变量/函数将使其变成全局的:

abc();

abc = function() {
  console.log('global abc');
};

// same as:
//window.abc = function() {...};
window.abc();

使用let,您的函数将被设置范围:

{
  let abc = function() {
    console.log('let abc');
  }
}

abc(); // ReferenceError: abc is not defined

如果使用var声明一个函数,则即使在闭包结束之后(但不能在闭包结束之前)也可以执行该函数,并且如果未声明insinde一个函数,则可以执行该函数:

//abc(); // TypeError: abc is not a function

{
  var abc = function() {
    console.log('var abc');
  }
}

abc(); // will work

let a = function() {
  var cde = function() {
    console.log('var cde');
  }
  
  cde(); // will work
}

cde(); // ReferenceError: cde is not defined

最后,this将成为对象属性:

let a = function() {
    this.abc = function() {
      console.log('this.abc');
    };
}

let obj = new a();
obj.abc();

a.abc(); // TypeError: abc is not a function