请考虑以下代码:
var f = function() { return 10; }
typeof f; // returns "function"
f(); // returns 10
var g = f;
g(); // returns 10, obviously
var h = new f;
h; // console evaluates to f - ????
h(); // Type error - called_non_callable
typeof h; // returns "object"
那么,这里有什么? Chrome控制台似乎将其评估为f,但它不可调用。 “新”这样的功能意味着什么?现在如何与f相关?
顺便说一下,这两行看起来是等价的:
var h = new f;
var h = new f();
这是怎么回事?
答案 0 :(得分:4)
这就是JavaScript中面向对象的方式。如果你在一个函数上调用new
,这个函数将被视为它是一个类的构造函数(关键字class
来定义一个类,就像其他语言在js中不存在一样)。 / p>
所以调用var h = new f();
会使h
成为类f
的对象,并且对象本身不可调用(这就是为什么你得到called_non_callable
)。
如果你想给你的“课堂”一些mehots,你应该这样做:
function cat(name) {
this.name = name;
this.talk = function() {
alert( this.name + " says meeow!" )
}
}
cat1 = new cat("felix")
cat1.talk() //alerts "felix says meeow!"
cat2 = new cat("ginger")
cat2.talk() //alerts "ginger says meeow!"
这是来自page 2的this tutorial的示例。有关更多信息,请阅读或ask Google for object-orientation in JavaScript。
答案 1 :(得分:4)
您混淆的根源是Chrome在其控制台上表示对象的方式。
您示例中的表达式new f()
在Chrome的控制台输出中表示为“f
”,但仅作为此特定控制台的“便利”,例如,记录以下对象:
({constructor: function Foo(){}});
将其显示为“Foo
”。基本上,控制台试图找到表示,其构造函数对象是 的实例。
因此,控制台会向您显示f
,但您没有记录该函数,new
运算符会生成一个继承自f.prototype
的对象。
您正在从函数返回10
,但由于您使用new
调用它,并且返回类型是原语,因此将丢弃该值,新创建返回继承表单f.prototype
的对象。
例如:
var F = function () { return 10; };
F.prototype.inherited = 'foo';
var h = new F(); // the 10 returned is ignored
h instanceof F; // true
h.inherited; // "foo"
另一方面,如果从构造函数返回一个对象,new
运算符在scened后面创建的对象实例(并继承自构造函数的原型)将丢失,例如:
var F = function () { return {}; };
F.prototype.inherited = 'foo';
var h = new F(); // the empty object is returned
h instanceof F; // false
h.inherited; // undefined
是的,new f;
和new f();
完全相同,但人们建议使用括号来增加代码的清晰度。
答案 2 :(得分:2)
我建议阅读https://developer.mozilla.org/en/JavaScript/Reference/Operators/Special/this,尤其是关于“功能背景”的部分。
简而言之,当您new
运行时,您正在创建一个新对象:
var h = new f;
这说:“创建一个名为h
的{{1}}变量引用的新对象”。然后将该函数视为构造函数而不是您期望的那样。
创建对象后,它就不再可调用了(这就是为什么你在行f
上遇到错误的原因。
在大多数语言中(不排除Javascript),构造函数的h()
是可选的(除非有必要的参数(在某些语言中))。
答案 3 :(得分:1)
基本上,new关键字将f调用为新对象的构造函数。在StackOverflow上对这个问题的第一个回答总结得非常好:
答案 4 :(得分:1)
在JavaScript中,函数不仅仅是函数,它们不仅仅是对象;它们也用于定义类型的构造函数。
一般来说,当你有一个函数f
时,该函数定义一个类型,无论是否有意。这一行
var h = new f();
定义了一个类型为h
的对象f
。
我从未见过该行
var h = new f;
但我假设它和另一行一样。