不是一个函数?

6
当我运行以下代码时,会提示talk不是一个函数。为什么?
function cat(name) {
    talk = function() {
        alert(" say meeow!" )
    }
} 

cat("felix");
cat.talk()

你是想创建一个名为 cat 的类,还是定义一个具有 talk 函数的对象? - Chris Carew
4个回答

9
你想要做的是创建一个函数作为构造函数的对象,但实际上代码所做的是将变量talk设置为一个函数。你需要的是:
function cat(name) {
    this.talk = function() {
        alert(" say meeow!" )
    }
} 

var myCat = new cat("felix");
myCat.talk()

编辑:

相关的JavaScript技术讲解:http://www.youtube.com/watch?v=ljNi8nS5TtQ

他在大约30分钟处谈到了使用函数构造对象。他发布的代码是:

function Circle(radius){
    this.radius = radius;
    this.area = function(){
        return this.radius * this.radius * Math.PI;
    };
}
var instance = {};
Circle.call(instance, 5);
instance.area(); // ==> 78.5398
var instance2 = new Circle(5);
instance2.area() // ==> 78.5398
instance instanceof Circle // ==> false
instance2 instanceof Circle // ==> true

相关引用:

新关键字只是一种简写方式,表示“创建一个新对象并在其上调用构造函数...新关键字没有其他含义”

换句话说,他的意思是当使用new关键字时,您正在将变量定义为对象,并在该对象的上下文中调用函数(this指向您的对象)。

new关键字额外做的事情是将新创建的对象的原型设置为构造函数的原型。因此,如果我们执行以下操作:

function Circle(radius){
    this.radius = radius;
    this.area = function(){
        return this.radius * this.radius * Math.PI;
    };
}
var instance = {};
Circle.call(instance, 5);
instance.__proto__ = Circle.prototype; // we set the prototype of the new object to that of the constructor
instance.area(); // ==> 78.5398
var instance2 = new Circle(5);
instance2.area() // ==> 78.5398
instance instanceof Circle // ==> true // this is now true 
instance2 instanceof Circle // ==> true

instance instanceof Circle现在为真。


2
+1,比我先发了。虽然你可能应该解释一下为什么这个方法可行,而原帖的版本不行。 - RMorrisey
我也点赞,而且我要发表的示例代码与你的完全相同(逐字逐句)。 - pete
@RMorrisey,是的,没错。我正在寻找我刚刚发布的技术讲座,以验证我将要说的任何内容。我仍然可能不会做得很好,但我马上就会发布它。 - mowwwalker

2
为了使您的代码按照预期工作,您需要编写以下内容:
function Cat(name) {
    this.talk = function() {
        alert(" say meeow!" )
    }
};

var c = new Cat("felix");
c.talk()

Cat 函数是一个构造函数,返回的对象有一个属性 (talk),它是一个可以调用的函数。

您原来的代码实际上声明了一个全局函数 talk,它并不属于 cat 函数,因为它缺少了 var 关键字。


2
那是因为它并不是这样的。
你创建了一个函数,并将其分配给变量在cat函数中,但该变量并不属于该函数。由于您没有在任何地方声明变量,它会隐式成为全局变量,因此实际上可以在函数外部使用它,但不能以您尝试使用的方式使用它。
您必须将函数添加为cat函数对象的属性,以便您能够以那种方式调用它:
function cat(name) {
  cat.talk = function() {
    alert(" say meeow!" )
  }
} 

cat("felix");
cat.talk()

然而,您可能正在寻找一个具有方法的对象,而不是一个具有方法属性的函数:

function Cat(name) {
  this.name = name;
}

Cat.prototype.talk = function() {
  alert(this.name + " says meeow!");
}

var felix = new Cat("Felix");
felix.talk();

实际上他的 talk 函数是全局的,不是局部的。 - Alnitak
@Guffa,请检查一下我的编辑是否符合您的要求。顺便说一句,您的示例实现了大多数人意想不到的功能——给定函数的加法属性,而不是由“cat”构造函数创建的新对象的属性。 - Alexei Levenkov
是的,你说得对,这是一个全局变量。我自己进行了一些广泛的编辑,但我也融入了你的观点。 - Guffa

0

cat不是一个对象。它是一个函数,我认为JavaScript不支持这个。


4
函数也是对象,所以你实际上可以向函数添加属性。 - Guffa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接