var someObject = function(arg) {
this.property = function() {
// do something with the argument
return arg;
}();
};
var obj = new someObject(some argument);
// object.property instanceof "someObject" should be true
使用property
someObject
时,应创建newObject
的新实例。例如,当我使用本机DOM Element的nextSibling属性时,将返回一个新的DOM Element对象实例。我想知道是否有可能创建一个类似的结构。或者会导致无限递归?
答案 0 :(得分:1)
严格地说,这可以在ES5中使用(所有最新的浏览器,包括IE)。
ES5通过get
和set
关键字或Object.defineProperty
函数指定getter和setter,因此您可以使函数的行为类似于属性(想想innerHTML)。这是你如何做到的:
function Mother () {
this.name = '';
Object.defineproperty(this,'child',{
get: function(){
return new Mother();
}
});
}
因此,对象现在可以通过阅读child
属性来创建自己的新实例:
var a = new Mother();
a.name = 'Alice';
b = a.child;
b.name = 'Susan';
alert(a.name) // Alice
alert(b.name) // Susan
a instanceof Mother; // true
b instanceof Mother; // true
话虽如此,您对DOM元素的观察是错误的。 DOM只是一种树形结构。您可以使用old-school javascript创建类似的结构:
function MyObject () {}
var a = new MyObject();
var b = new MyObject();
var c = new MyObject();
a.children = [b,c];
b.nextSibling = c;
c.prevSibling = b;
// now it works like the DOM:
b.nextSibling; // returns c
a.children[1]; // returns c
b.nextSibling.prevSibling instanceof MyObject; // true
答案 1 :(得分:0)
不,那是不可能的。您可以将函数设置为属性,但无论如何,您需要以某种方式调用函数(使用property()
表示法或使用call/apply
),因为它本身就是一个对象,并且只有()
或call/apply
向解释器说你想要执行代码,但不仅可以访问函数的对象数据。
答案 2 :(得分:0)
您对DOM中nextSibling属性的理解不正确。它不会创建新的DOMElement,它只是引用现有的DOM Node。
当你创建一个你有引用的元素的兄弟(例如,通过jQuery或document.createElement)时,浏览器知道更新兄弟和父/子引用。
因此,您尝试模拟的行为甚至不存在。
正如其他人所暗示的那样,仅仅访问对象上的属性并不足以使Javascript解释器“执行”任何操作(除了尊重您正在查找的名称)。你需要财产作为一种功能。
答案 3 :(得分:0)
nextSibling
不返回 new 元素,它返回一个现有元素,它是目标元素的下一个兄弟。
您可以将对象引用存储为另一个对象的属性,就像存储原始值一样。
function SomeObject(obj) {
this.obj = obj;
}
var someObject = new SomeObject(new SomeObject());
someObject.obj instanceof SomeObject //true
但是,如果要在访问SomeObject
时动态创建someObject.obj
的新实例,或者希望根据每次访问该属性时要重新评估的条件返回现有对象,您需要使用功能或访问者。
function SomeObject(obj) {
this.obj = obj;
}
SomeObject.prototype.clone = function () {
//using this.constructor is a DRY way of accessing the current object constructor
//instead of writing new SomeObject(...)
return new this.constructor(this.obj);
};
var someObject = new SomeObject(new SomeObject());
var someObjectClone = someObject.clone();
最后使用访问者(要知道它们不是跨浏览器且无法填充)
function SequentialObj(num) {
this.num = num;
}
Object.defineProperty(SequentialObj.prototype, 'next', {
get: function () {
return new this.constructor(this.num + 1);
},
configurable: false
});
var seq = new SequentialObj(0);
console.log(seq.next); //SequentialObj {num: 1}
console.log(seq.next.next.next); //SequentialObj {num: 3}
答案 4 :(得分:-1)
如果您希望this.property()
返回新的someObject
,您可以按如下方式编写课程:
var someObject = function(arg) {
this.arg = arg;
};
someObject.prototype.property = function(arg) {
// do something with the argument
return new someObject(arg||this.arg);
}();
var obj = new someObject(/*some argument*/);
// object.property instanceof "someObject" should be true
如果您希望它返回一些已经实例化的版本,您可以按如下方式编写代码:
var someObject = (function() {
var previous;
function(arg) {
this.arg = arg;
this.propertyBefore = previous;//refers to the someObject created before this one
if(previous) previous.property = this; //before.property now references this class
//this.property will be undefined until another instance of someObject is created
previous = this;
};
})()
var obj = new someObject(/*some argument*/);// returns someObject already created earlier (similar to nextSibling)
一个小注释 - 在javascript中使用大写名称(SomeObject
而不是someObject
)声明类名的最佳做法