5 javascript constructor object
我最近一直在做很多研究,但还没有得到一个非常好的答案.我在某处读到当JavaScript引擎遇到函数语句时会创建一个新的Function()对象,这会让我相信它可能是一个对象的子对象(从而成为一个对象).所以我给Douglas Crockford发了电子邮件,答案是:
不完全是因为函数语句不调用编译器.
但它产生了类似的结果.
另外,据我所知,除非已将实例化为新对象,否则不能在函数构造函数上调用成员.所以这不起作用:
function myFunction(){
this.myProperty = "Am I an object!";
}
myFunction.myProperty; // myFunction is not a function
myFunction().myProperty; // myFunction has no properties
Run Code Online (Sandbox Code Playgroud)
但是,这将有效:
function myFunction(){
this.myProperty = "Am I an object!";
}
var myFunctionVar = new myFunction();
myFunctionVar.myProperty;
Run Code Online (Sandbox Code Playgroud)
这只是一个语义问题......在整个编程世界中,对象何时真正成为一个对象,以及它如何映射到JavaScript?
Eug*_*kin 13
关于函数和构造函数没有什么神奇之处.JavaScript中的所有对象都是......好吧,对象.但是有些对象比其他对象更特殊:即内置对象.差异主要在于以下几个方面:
null并且undefined是特殊对象.任何在这些对象上使用方法或定义新方法的尝试都会导致异常.+,-,*,/.+.()和new操作符.后者具有如何使用prototype构造函数的属性的先天知识,构造一个具有与原型的适当内部链接的对象,并在其上调用构造函数this正确设置.如果您查看ECMAScript标准(PDF),您将看到所有这些"额外"功能被定义为方法和属性,但其中许多功能不能直接供程序员使用.其中一些将在标准ES3.1的新版本中公开(截至2008年12月15日的草案:PDF).一个属性(__proto__)已在Firefox中公开.
现在我们可以直接回答您的问题.是的,函数对象具有属性,我们可以随意添加/删除它们:
var fun = function(){/* ... */};
fun.foo = 2;
console.log(fun.foo); // 2
fun.bar = "Ha!";
console.log(fun.bar); // Ha!
Run Code Online (Sandbox Code Playgroud)
这个功能实际上做了什么并不重要 - 它永远不会起作用,因为我们不称之为!现在让我们来定义它:
fun = function(){ this.life = 42; };
Run Code Online (Sandbox Code Playgroud)
它本身不是构造函数,它是一个在其上下文中运行的函数.我们可以很容易地提供它:
var context = {ford: "perfect"};
// now let's call our function on our context
fun.call(context);
// it didn't create new object, it modified the context:
console.log(context.ford); // perfect
console.log(context.life); // 42
console.log(context instanceof fun); // false
Run Code Online (Sandbox Code Playgroud)
如您所见,它为已存在的对象添加了一个属性.
为了使用我们的函数作为构造函数,我们必须使用new运算符:
var baz = new fun();
// new empty object was created, and fun() was executed on it:
console.log(baz.life); // 42
console.log(baz instanceof fun); // true
Run Code Online (Sandbox Code Playgroud)
正如你所看到的new,我们的函数是一个构造函数.以下行动由以下人员完成new:
{}创建了新的空对象().fun.prototype.在我们的例子中,它将是一个空对象({})因为我们没有以任何方式修改它.fun() 用这个新对象作为上下文调用.我们的功能是修改新对象.通常它会设置对象的属性,但它可以做任何它喜欢的事情.
有趣的琐事:
因为构造函数只是一个对象,我们可以计算它:
var A = function(val){ this.a = val; };
var B = function(val){ this.b = val; };
var C = function(flag){ return flag ? A : B; };
// now let's create an object:
var x = new (C(true))(42);
// what kind of object is that?
console.log(x instanceof C); // false
console.log(x instanceof B); // false
console.log(x instanceof A); // true
// it is of A
// let's inspect it
console.log(x.a); // 42
console.log(x.b); // undefined
// now let's create another object:
var y = new (C(false))(33);
// what kind of object is that?
console.log(y instanceof C); // false
console.log(y instanceof B); // true
console.log(y instanceof A); // false
// it is of B
// let's inspect it
console.log(y.a); // undefined
console.log(y.b); // 33
// cool, heh?
Run Code Online (Sandbox Code Playgroud)构造函数可以返回覆盖新创建的对象的值:
var A = function(flag){
if(flag){
// let's return something completely different
return {ford: "perfect"};
}
// let's modify the object
this.life = 42;
};
// now let's create two objects:
var x = new A(false);
var y = new A(true);
// let's inspect x
console.log(x instanceof A); // true
console.log(x.ford); // undefined
console.log(x.life); // 42
// let's inspect y
console.log(y instanceof A); // false
console.log(y.ford); // perfect
console.log(y.life); // undefined
Run Code Online (Sandbox Code Playgroud)
正如你所看到的那样x是A原型和所有,而y我们是从构造函数返回的"裸"对象.
niX*_*Xar 12
你的理解是错误的:
myFunction().myProperty; // myFunction has no properties
Run Code Online (Sandbox Code Playgroud)
它不起作用的原因是因为".myProperty"应用于"myFunction()"的返回值,而不是对象"myFunction".以机智:
$ js
js> function a() { this.b=1;return {b: 2};}
js> a().b
2
js>
Run Code Online (Sandbox Code Playgroud)
请记住,"()"是一个运营商."myFunction"与"myFunction()"不同.instanciang with new时你不需要"返回":
js> function a() { this.b=1;}
js> d = new a();
[object Object]
js> d.b;
1
Run Code Online (Sandbox Code Playgroud)
要回答您的具体问题,技术上的功能始终是对象.
例如,您可以随时执行此操作:
function foo(){
return 0;
}
foo.bar = 1;
alert(foo.bar); // shows "1"
Run Code Online (Sandbox Code Playgroud)
当Javascript函数使用this指针时,它们的行为有点像其他OOP语言中的类.可以使用new关键字将它们实例化为对象:
function Foo(){
this.bar = 1;
}
var foo = new Foo();
alert(foo.bar); // shows "1"
Run Code Online (Sandbox Code Playgroud)
现在,从其他OOP语言到Javascript的映射将很快失败.例如,Javascript中实际上没有类这样的东西 - 对象使用原型链来进行继承.
如果您打算在Javascript中进行任何重要的编程,我强烈推荐您通过电子邮件发送的Javascript: Crockford 的Good Parts.