简体   繁体   中英

Javascript literal object, reference to itself

I have this example code:

var foo = {

    self: this,

    init: function(){

        self.doStuff();
    },

    doStuff: function(){
        alert('doing stuff');   
    }

}

foo.init();

Why the refence "self" doesn't work?

Thanks!

因为在您声明对象文字时, this不是对对象的引用,而是对调用上下文的引用。

The value of this is determined by how the current function was called. It does not refer to the current object.

This will work:

var foo = {
    init: function(){
        this.doStuff();
    },
    doStuff: function(){
        alert('doing stuff');   
    }
};

foo.init();

Since when you call foo .init() , this becomes foo .

Following up on Qeuntin's response you would use the following to achieve what you're looking for

var foo = {

    self: false,

    init: function(){
        self = this
        self.doStuff();
    },

    doStuff: function(){
        alert('doing stuff');   
    },
}

EDIT: Since it's been pointed out that whilst this solves OP's problem (ie it works) it isn't exactly how you should go about it. So, here's a scoping reference.

function A()
{
    //Semi-private / hidden var
    var pVar = "I'm a private, err hidden, variable",
        //fn (technically a var)
        pFn = function(){},
        //empty var, placholder for hidden fn
        privatePlaceholderFn;

    //Instance-time... public fn
   this.instancePublicFn = function()
    {
        console.log("--- instace public ---");
        //Print hidden var to cosole
        console.log(pVar);
        //Call hidden fn
        instancePrivateFn();
        console.log("--->Setting  private from instance public")
        //Set the hidden fn
        setPrivate();
        console.log("--- / instance public ---");
    }
    //Pass fn to private method.
    this.setPrivFromOutside = function(fn)
    {
        setPrivateFromPrivateYetOutside(fn);
    }

    //Set the hidden fn
    this.iPFnPlaceholderSetter = function(fn)
    {
        privatePlaceholderFn = fn;
    }

    //Call the semi-private / hidden fn
    this.callPrivate = function()
    {
       privatePlaceholderFn();
    }
    //A misnomer, proves the scope exists. See "function setPrivate()"
    this.setPrivateFromInstance = function()
    {
        //Prove scope exists
        console.log(privatePlaceholderFn);
        console.log("Private From instance - gets inside scope");

    }
    //Set hidden fn from private method
    function setPrivate()
    {
        privatePlaceholderFn = function()
        {
            //Show scope exists
            console.log(pVar);
        }
    }
    //Set the hidden fn from hidden method
    function setPrivateFromPrivateYetOutside(fn)
    {
        //fn's scope won't resolve to inside
        privatePlaceholderFn = fn;
    }
    //Private / hidden messager
    function instancePrivateFn()
    {
        //Just loggin' something
        console.log("Instance Private method");
    }
}
//Add an object method to the prototype
A.prototype.protoPuFn = function(){
    console.log("---> Private var from object literal method");
    //console.log(pVar)
}

//...
a = new A();

//Add object literal fn
a.objFn = function()
{
    console.log("Object literal defined public fn - Gets outside scope");
    //console.log(pVar);
}
//Set private / hidden placeholder fn
a.iPFnPlaceholderSetter(function()
{
    console.log("Hidden fn, passed through instance public - gets outside scope");
    //console.log(pVar);
});
//Attempt to read hidden var
console.log(a.pVar);
//Call object literal defined fn
a.objFn();
//Call the hidden fn
a.callPrivate();
//Call prototype added fn
a.protoPuFn();
//Call instance added public fn
a.instancePublicFn();
//Call private / hidden method (set
a.callPrivate();
//Same as iPFnPlaceholderSetter except the param is passed to a hidden method, before seting.
a.setPrivFromOutside(function()
{
    console.log("-->Passed from outside, through public then private setters");
    //console.log(pVar)
})
//Call the hidden method
a.callPrivate();
//Set hidden fn from instance public
a.setPrivateFromInstance();
//Call the hidden method.
a.callPrivate();
//Use evi(a)l fn to steal scope.
a.evil("this.meth = function(){console.log(pVar)}");
//Call fn with stolen scope
a.meth();

ES6 provides getters for the object properties, so you can use them to reference the object itself and to use its other members:

var foo = {
     prop1: 1,

     get prop2() { return this.prop1 + 1; }
}

// foo.prop2 = 2;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM