Javascript:按属性初始化对象

时间:2013-10-23 12:37:39

标签: javascript object

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对象实例。我想知道是否有可能创建一个类似的结构。或者会导致无限递归?

5 个答案:

答案 0 :(得分:1)

严格地说,这可以在ES5中使用(所有最新的浏览器,包括IE)。

ES5通过getset关键字或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)声明类名的最佳做法