javascript:函数和对象…?

你可以调用一个函数作为一个对象? 例如:

function Tip(txt){ this.content = txt; this.shown = false; } 

和:

 var tip = new Tip(elem.attr('title')); 

我的问题:

  1. 你可以调用一个new的函数,如一个对象?
  2. 使用“这个”是可能的,因为我们使用这个函数作为一个对象?

您正在寻找constructor概念。

JavaScript 中的所有函数都是对象 ,可以用来创build对象:

 function make_person(firstname, lastname, age) { person = {}; person.firstname = firstname; person.lastname = lastname; person.age = age; return person; } make_person("Joe", "Smith", 23); // {firstname: "Joe", lastname: "Smith", age: 23} 

然而,为了创build一个特定types的新对象(也就是说,inheritance一个原型,有一个构造函数等),一个函数可以引用this如果用new运算符调用它,那么它将返回一个对象在函数中定义了所有这些属性 – 在这种情况下,引用我们正在创build的新对象。

 function make_person_object(firstname, lastname, age) { this.firstname = firstname; this.lastname = lastname; this.age = age; // Note, we did not include a return statement } 

make_personmake_person_object之间关键的区别在于,调用new make_person() (而不是简单的make_person() )将不会做任何不同的事情…两者都会产生相同的对象。 然而,调用没有new运算符的make_person_object()会在当前this对象上定义你的this属性(如果你在浏览器中运行的话,通常是window )。

从而:

 var Joe = make_person_object("Joe", "Smith", 23); console.log(Joe); // undefined console.log(window.firstname) // "Joe" (oops) var John = new make_person_object("John", "Smith", 45); console.log(John); // {firstname: "John", lastname: "Smith", age: 45} 

另外,正如@RobG所指出的,这种做事的方式在我们创build的每个“Person”上创build一个对make_person_objectprototype属性的make_person_object 。 这使我们能够在事实之后向人们添加方法和属性:

  // Assuming all that came before make_person_object.prototype.full_name = "N/A"; make_person_object.prototype.greet = function(){ console.log("Hello! I'm", this.full_name, "Call me", this.firstname); }; John.full_name // "N/A" John.full_name = "John Smith"; make_person_object.full_name // Still "N/A" John.greet(); // "Hello! I'm John Smith Call me John" 

公约认为像make_person_object这样的构造函数被大写,单数化和“名”(因为没有更好的术语) – 所以我们将有一个Person构造函数,而不是一个可能被误认为是普通函数的make_person_object

也可以看看:

  • new运营商
  • bobince很好的介绍了JavaScript的子类化 (无论是否有原型inheritance)。

每个function都有这个参考。 如果你调用Tip()this将引用全局对象。 如果您调用new Tip() ,则会创build一个引用Tip.prototype的新对象,并将引用该新对象。

你不能在对象上使用new ,例如new {} throws TypeError: object is not a function 。 如果你是引用new Object()那么工作,因为Object是一个函数。

是。 在JavaScript中,技术上所有东西都是一个对象。 当你使用new的时候,它会创build一个Tip对象的实例,然后像Tip是一个构造函数一样调用Tip函数。

如果你想添加函数到Tip对象,你应该把它们添加到Tip的原型,如下所示:

 Tip.prototype.getContent = function() { return this.content; }; 

如果你有,那么你做:

 var tip = new Tip("this is my content."); alert(tip.getContent()); 

它会显示一条消息,说“这是我的内容”。

但是,如果对象具有function实现,则只能使用new。 所以这不起作用:

 var Tip = { content: txt, show: false }; var tipObj = new Tip(); 

该函数充当一个类的构造函数。 或者,你可以这样做:

 function Tip(txt) { return { content: txt, shown: false } } 

并获得一个新的实例: var myTip = new Tip("my epic tip"); 这类似于,比如说c#:

 public class Tip { string text = ""; public Tip(string txt) { text = txt; } } 

所以,有点。 1)你正在调用new,因为函数本质上是作为一个类来使用的,2) this是指类的当前实例。

对于#1:有一个对象叫做Function(大写字母F)

var f = new Function(“x”,“y”,“return x * y;”);

对于#2:“这个”是不同的,取决于存储模式(如道格拉斯·克罗克福德所说)。 Crockford说有4种模式(方法模式,函数模式,构造模式和“应用”模式)

  1. 实际上,像数组,数据types的每个数据types都是对象。
  2. 当我们把函数作为一个类声明的时候,这是有效的。

我已经努力了解这些概念(函数作为对象,原型对象,__proto__属性,构造函数属性)近8年(2008-2016)。 首先,我在多次阅读第6,8,9章之后,开始了David Flanagan的“JavaScript权威指南第5版/第6版” 它对我来说没有任何意义,但在互联网上挣扎后,我能够将一些能够pipe理函数(典型的具有属性的C ++函数)作为对象的东西; 因为对象也可以有方法。 幸运的是,在2015年的第七年,我开始了Wrox Nicholas C. Zakas“Web开发人员的专业JavaScript第三版”第6,7章; 了解以上四个概念真的很有帮助。 传统上在C / C ++ / C#函数中被认为是修改一个对象; 或者换言之,它们是为了“做某事”而制造的,其中对象被用来维持全局运行上下文的状态,以及用于改变它自己的对象状态的方法。 所以,如果函数可以是第一类对象,那么为什么对象不能像function?

这里的主要关键问题应该是为什么? 为什么不像“联合函数”或“链式参数”这样的概念实体? 这里是我的理解:浏览器EXE是一个单线程的应用程序,这个exe控制调用JS预定义的范围链(有些类似于一串命令与参数)解释器; 现在在运行时,JS引擎(而不是解释器)以提升方式加载代码(因为没有主要的方法来提升已定义好的密钥代码及其调用)。 在这个悬而未决的代码中,如果函数不被视为对象,那么它们必须在单独的调用上下文(在作用域链之外)进行维护,这在c / c ++ / c#(multithreading和无限制内存的bcoz) 。 因此,“链接对象上的待办事项”使Java脚本函数成为第一类对象。 实际上JS对象也是这样做的; 唯一的区别是“调用一个对象”并不存在于“调用一个函数”的链接上下文中。 函数也可以被认为是“带有地址链接(链)的汇编语言指令的一堆variables”。 链接部分是故事的另一端,如顶部 – >底部链接(原型对象)与底部 – >顶部链接(__ proto__属性)vs对象蓝色 – >对象实例(构造函数属性)。 几个月前,我发现下面的图像有助于理解链接。

http://judis.me/wordpress/wp-content/uploads/2015/08/JavaScriptDiagram.png“JS对象模型”;