我希望能够做到以下几点:
person('male');
person.age(34);
如您所见,我希望person object
同时为function
和object
。我的意思是这样做:
function person(gender){
this.gender = gender || 'unknown';
}
让我无法这样做:
person.gender; // undefined
除非我从person函数创建一个新对象,如下所示:
var me = new person();
me.gender; // 'unknown'
我不想要,因为我仍然希望能够设置其他属性,如:
person.age = 34;
这有可能吗?我是在尝试完成不可能的事情吗?
澄清:我不想创建实例。关键是我只想将函数person
称为function.property()
。
编辑:也许我通过使用错误的例子让很多人(包括我自己)感到困惑。一个更简单的问题是:我如何能够调用该函数的函数和'属性',如下所示:
car();
car.start();
同时无需创建汽车实例?
答案 0 :(得分:4)
如果你能解释你想做什么背后的动机,我们或许可以给出更好的答案。但是,是的,你所描述的是可能的。在JavaScript中,函数只是另一种类型的对象。这意味着您可以定义一个函数,然后像这样设置属性:
var person = function () {
return "Hi, I am a person!";
};
person.species = "human";
person.foo = 42;
console.log( person() ); // prints: Hi, I am a person!
console.log( person.species ): // prints: human
console.log( person.foo ); // prints: 42
或者从第二个例子开始:
var car = function () {
return {
model: "Focus",
make: "Ford",
year: 2010
};
};
car.start = function () {
return "Vroom!";
};
console.log ( car.make ); // prints: Ford
console.log ( car.start() ); // prints Vroom!
顺便说一下, 与返回对象的函数相同。这可能是这样的:
var person = function () {
return {
species: "human",
name: "Bob",
age: 27
};
};
var bob = person();
bob.occupation = "cubicle drone";
console.log( bob.name ); // prints: Bob
console.log( bob.occupation ); // prints: cubicle drone
console.log( person.occupation ); // prints: undefined
console.log( bob == person ); // prints: false
变量bob
和person
都包含对象,但不包含相同的对象,甚至不包含相同类型的对象。
答案 1 :(得分:3)
而不是在函数内部使用this
,它引用通过使用new
运算符调用此函数作为构造函数创建的Object实例,您可以使用arguments.callee
来引用到功能本身
function person(gender){
arguments.callee.gender = gender || 'unknown';
}
如果要确保函数始终用作构造函数,即使在没有new
运算符的情况下调用它,也可以通过隐式调用它来实现。
function person(gender){
if(!(this instanceof person)){ return new person(gender); }
this.gender = gender || 'unknown';
}
在所有其他方面,函数可以做任何常规对象可以做的事情,这就是为什么它们经常被描述为"第一类对象"。
您只需为对象或类似
等方法指定属性即可function car(){
}
car.start = function(){
}
您也可以让他们使用__proto__
属性从函数继承方法。
function bird(){}
function platypus(){}
bird.layEggs = function(){};
platypus.__proto__ = bird;
platypus.layEggs() // now you know
答案 2 :(得分:1)
使用@Winchestro正在使用的实例方式的一个小例子
on jsfiddle:http://jsfiddle.net/47EEr/
'use strict';
function person(gender, age, name) {
if (!(this instanceof person)) {
return new person(gender, age, name);
}
var props = { gender: '', age: 0, name: '' }, fnCreateProp = function(prop, value) {
Object.defineProperty(this, prop, {
get: function() {
return props[prop];
},
set: function(val) {
console.log('setting prop ' + prop + ' to ' + val);
props[prop] = val;
}
});
}.bind(this);
for (var prop in props) {
if (!props.hasOwnProperty(prop)) {
continue;
}
fnCreateProp(prop, props[prop]);
}
this.gender = gender;
this.age = age;
this.name = name;
this.toString = function(element) {
var str = '[Person=(';
for (var prop in props) {
if (!props.hasOwnProperty(prop)) {
continue;
}
if (str.indexOf('(') !== str.length-1) {
str += ',';
}
str += prop +': ' + props[prop];
}
str += ')]';
if (typeof element !== 'undefined') {
var el = document.getElementById(element);
if (el) {
el.innerHTML = str;
}
}
return str;
};
this.birthday = function() {
this.age++;
};
}
var p1 = person('male', 33, 'male 1');
var p2 = new person();
p2.age = 32; p2.gender = 'female'; p2.name = 'female 1';
p1.toString('person1');
p2.toString('person2');
p2.birthday();
p2.toString('person2birthday');
答案 3 :(得分:0)
你也可以这样做:
function person(gender){
return {
gender: gender || 'unknown'
};
}
var p = person('male');
p.age = 34;
p.name = 'John';
etc...
不使用“新”,您仍然可以重复使用人物功能。
答案 4 :(得分:0)
您的修改
编辑:也许我通过使用错误的例子让许多人(包括我自己)感到困惑。一个更简单的问题是:我怎么能够 称一个函数和一个属性'该功能,如下:
car(); car.start();
同时无需创建汽车实例?
这是您要找的吗?
function car() {
console.log("car called");
car.start = function() {
console.log("car.start called");
}
}
car();
car.start();
/**** output:****
car called
car.start called
*/