您可以将函数作为对象调用吗?例如:
function Tip(txt){
this.content = txt;
this.shown = false;
}
和:
var tip = new Tip(elem.attr('title'));
我的问题:
- 你能调用
new
一个函数,比如一个对象吗? - 使“this”的使用成为可能,因为我们将那个函数用作对象?
您可以将函数作为对象调用吗?例如:
function Tip(txt){
this.content = txt;
this.shown = false;
}
和:
var tip = new Tip(elem.attr('title'));
我的问题:
new
一个函数,比如一个对象吗? 你正在寻找这个constructor
概念。
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}
但是,为了创建特定类型的新对象(也就是说,继承原型,具有构造函数等),函数可以引用this
,如果使用new
运算符调用它,则它将返回一个包含所有对象的对象this
在函数中定义的属性-this
在这种情况下引用我们正在创建的新对象。
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_person
和之间要注意的主要区别make_person_object
是调用new make_person()
(而不是简单的make_person()
)不会做任何不同的事情......两者都会产生相同的对象。然而,在make_person_object()
没有new
操作符的情况下调用将定义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 指出的那样,这种做事方式会创建对我们创建的每个“人”的prototype
属性的引用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
可能被误认为是普通函数的 a 。
也可以看看:
new
运营商 每个函数都有一个对this
. 如果调用Tip()
,this
将引用全局对象。如果调用new Tip()
,则会创建一个引用 Tip.prototype 的新对象,this
并将引用该新对象。
您不能new
在对象上使用,例如new {}
throws TypeError: object is not a function
。如果您指的是new Object()
那么有效,因为它Object
是一个函数。
是的。在 JavaScript 中,从技术上讲,一切都是对象。当您使用 new 时,它会创建一个 Tip 对象的实例,然后像调用构造函数一样调用 Tip 函数。
如果你想向 Tip 对象添加函数,你应该像这样将它们添加到 Tip 的原型中:
Tip.prototype.getContent = function() {
return this.content;
};
如果你有,然后你做:
var tip = new Tip("this is my content.");
alert(tip.getContent());
它会显示一条消息,说“这是我的内容”。
但是,如果对象具有功能实现,则只能使用 new。所以这行不通:
var Tip = { content: txt, show: false };
var tipObj = new Tip();
近 8 年(2008-2016 年)我一直在努力理解这些概念(作为对象的函数、原型对象、__proto__ 属性、构造函数属性)。首先,在多次阅读第 6、8、9 章后,我开始使用 David Flanagan “JavaScript Definitive Guide 5/6th ed” 4-5 年;这对我来说没有任何意义,但在互联网上挣扎之后,我可以将函数(具有属性的典型 C++ 函数)作为对象进行管理;因为对象也可以有方法。幸运的是,在 2015 年的第 7 年,我开始编写 Wrox Nicholas C. Zakas “Professional JavaScript for Web Developers 3rd ed”第 6,7 章;理解以上四个概念真的很有帮助。传统上,在 C/C++/C# 中,函数被认为是修改对象;或者换句话说,它们是为“做某事”而设计的 其中,对象用于维护全局运行上下文的状态,并使用更改其自身对象状态的方法。那么如果函数可以是一等对象,那么为什么对象不能像函数呢?
这里的主要关键问题应该是 WHY ?为什么不是像“关联函数”或“链式参数”这样的单一概念实体?这是我的理解:浏览器 exe 是一个单线程应用程序,这个 exe 控制调用具有预定义作用域链的 JS 解释器(有些类似于带有参数的命令字符串);现在在运行时,JS 引擎(不是解释器)以提升方式加载代码(因为没有 main 方法,所以提升了定义良好的关键字代码及其调用)。在这个提升的代码中,如果函数不被视为对象,那么它们必须在单独的调用上下文(范围链外)中维护,这在 c/c++/c#(多线程和无限内存的 bcoz)中很容易实现,但在 JS 中则不然. 因此“对链式对象的待办事项” 使java脚本函数作为第一类对象。事实上 JS 对象也做同样的事情;唯一的区别是“调用对象”不在对象中,而“调用函数”是有意义的链接上下文。函数也可以被认为是“一堆带有地址链接(链)的汇编语言指令的变量”。链接部分是故事的另一面,如顶部->底部链接(原型对象)与底部->顶部链接(__proto__ 属性)与对象蓝图->对象实例(构造函数属性)。几个月前,我发现下图有助于理解链接。函数也可以被认为是“一堆带有地址链接(链)的汇编语言指令的变量”。链接部分是故事的另一面,如顶部->底部链接(原型对象)与底部->顶部链接(__proto__ 属性)与对象蓝图->对象实例(构造函数属性)。几个月前,我发现下图有助于理解链接。函数也可以被认为是“一堆带有地址链接(链)的汇编语言指令的变量”。链接部分是故事的另一面,如顶部->底部链接(原型对象)与底部->顶部链接(__proto__ 属性)与对象蓝图->对象实例(构造函数属性)。几个月前,我发现下图有助于理解链接。
http://judis.me/wordpress/wp-content/uploads/2015/08/JavaScriptDiagram.png “JS 对象模型”
#1 :有一个名为 Function(大写 F)的对象
var f = new Function("x", "y", "返回 x*y;");
对于#2:“this”根据调用模式(如 Douglas Crockford 所称)的不同而不同。Crockford 说有 4 种模式(方法模式、函数模式、构造器模式和“应用”模式)