Javascript:按属性初始化对象

Javascript:按属性初始化对象,javascript,object,Javascript,Object,使用someObject的property时,应创建newObject的新实例。例如,当我使用本机DOM元素的nextSibling属性时,将返回一个新的DOM元素对象实例。我想知道是否有可能创造一个类似的结构。或者这样会导致无限递归?不,那是不可能的。您可以将函数设置为属性,但无论如何,您都需要以某种方式调用函数(使用property()符号或call/apply),因为函数本身就是一个对象,只有()或call/apply向解释器表示您要执行代码,但不仅仅是访问函数的对象数据 如果希望this

使用
someObject
property
时,应创建
newObject
的新实例。例如,当我使用本机DOM元素的nextSibling属性时,将返回一个新的DOM元素对象实例。我想知道是否有可能创造一个类似的结构。或者这样会导致无限递归?

不,那是不可能的。您可以将函数设置为属性,但无论如何,您都需要以某种方式调用函数(使用
property()
符号或
call/apply
),因为函数本身就是一个对象,只有
()
call/apply
向解释器表示您要执行代码,但不仅仅是访问函数的对象数据

如果希望
this.property()
返回一个新的
someObject
,可以编写如下类:

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
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(arg) {
    this.property = function() {
        // do something with the argument
        return arg;
    }();
};

var obj = new someObject(some argument);
// object.property instanceof "someObject" should be true
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

一个小注意事项—javascript中使用大写名称(
SomeObject
而不是
SomeObject
)声明类名的最佳实践是您对DOM中的nextSibling属性的理解是不正确的。它不创建新的domeElement,只引用现有的DOM节点

当您创建有引用的元素的同级(例如,通过jQuery或document.createElement)时,浏览器知道更新同级引用和父/子引用

所以,你试图模仿的行为根本不存在


正如其他人所暗示的,仅仅访问对象上的属性不足以让Javascript解释器“做”任何事情(除了尊重您正在查找的名称)。属性必须是函数。

nextSibling
不返回新元素,它返回一个现有元素,该元素是目标元素的下一个同级元素

可以将对象引用存储为另一个对象的属性,就像存储基元值一样

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)
但是,如果您希望在访问
SomeObject.obj
时动态创建
SomeObject
的新实例,或者希望根据每次访问属性时都应重新评估的条件返回现有对象,则需要使用函数或访问器

function SomeObject(obj) {
    this.obj = obj;
}

var someObject = new SomeObject(new SomeObject());

someObject.obj instanceof SomeObject //true
最后是访问器(请注意,它们不是跨浏览器的,不能填充)


严格地说,这在ES5中是可能的(所有最新的浏览器,是的,包括IE)

ES5通过
get
set
关键字或
Object.defineProperty
函数指定getter和setter,以便使函数的行为类似于属性(想想innerHTML)。以下是您如何做到这一点:

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}
因此,对象现在只需读取
子属性
即可创建自身的新实例:

function Mother () {
    this.name = '';
    Object.defineproperty(this,'child',{
        get: function(){
            return new Mother();
        }
    });
}

话虽如此,您对DOM元素的观察是错误的。DOM只是一个树结构。您可以使用老式javascript自己创建类似的结构:

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

除非您调用函数,否则函数将无法工作,如果您描述了它-它不是语义大小写中的属性,而是方法。@Ph0en1x您指的是哪个函数?属性()-它不是属性,这是一种方法。哦,没错,他要求的是一个链表,那么你为什么要这样做?
当我使用本机DOM元素的nextSibling属性时,会返回一个新的DOM元素对象实例
-这不是真的。你忘了这个问题了吗?
仅仅访问对象上的属性不足以让Javascript解释器运行”“是吗“任何事情
这都不完全正确。该属性可以定义为getter,因此访问它将执行get函数,该函数可以运行您想要的任何代码。它只在实现ES5 getter和setter的js引擎上工作,但现在比以前更为常见。slebetman是对的,但一定要注意ES5兼容性问题,以及getter/setter与其说是真正的属性,不如说是自动执行的方法。你的答案不正确。您可以定义属性访问器。请看我的答案。不幸的是,我在10分钟前就已经给出了答案。这真的很重要吗?26分钟前,我的评论让你写下了答案。再过一个小时,没有人能说出我们的答案中哪一个是第一个。因此,我将重复你对你的答案的评论,这将在一小时后让人们感到困惑:区别在于,我没有看到你的评论,因为你在写答案时没有收到关于张贴评论的通知,当您收到新答案已发布的通知时,最好查看这些答案以避免重复想法;)无论如何+1也是,这仍然是一个高质量的答案!哦向上投票只是为了友好:D