我正在尝试使用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
中声明它时,为什么将其视为全局函数?
答案 0 :(得分:4)
如果我声明不带此关键字的abc(),则其范围不在a()函数内。为什么在函数a中声明它时将其视为全局函数?
在任何地方都没有声明。 a
中的代码分配给一个未声明的变量,该变量创建一个隐式全局(默认为松散模式)。
这是使用严格模式(脚本顶部的"use strict";
)的许多良好原因之一。在严格模式下,分配给未声明的变量是一个错误(就像从未声明的变量中读取内容一样)。我的博客文章The Horror of Implicit Globals中有更多内容。
是的,正如您所发现的,this.
在JavaScript中从来不是可选的,而在Java或C#中却不是。要在执行a
时引用在new a()
中创建的实例,必须使用this
。
侧面说明:JavaScript中压倒性的惯例是构造函数(通过new
调用的函数)以大写字母开头。因此,A
而不是a
或Example
:
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