Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript - how to use "self" from current JS Class

Tags:

javascript

I tried to create this syntax for JavaScript:

var user = new Class({
    name: 'No name',
    sayHello: function () {
        console.log(self.name);
    }
});

user.sayHello();  // will print "undefined" because "self" isn't visible

And I created this implementation of Class:

function Class (_properties) {
    var self = this;

    // copy all properties and methods to this class
    for (var _property_name in _properties) {
        self[_property_name] = _properties[_property_name];
    }
}

But the problem is in self that I wish to use in each class. The self.name will be undefined because self is a [Window object].


Question: how to modify my code to use self inside all functions in class instances? The self is needed to not drop context if the function will be called from external context.

Expected result (I mean that code above should be executed as code below):

function Class (_properties) {
    var self = this;

    // properties

    self.name = 'No name';

    // methods
    self.sayHello = function sayHello () {
        console.log(self.name);
    };
}

var user = new Class();
user.sayHello();

The goal of my experiment is to use self that always is reference to current object. Because sometimes when we use calls like this $.get('...', function () { console.log(this); }) - this is set to function local scope. But I wish to use self (magic property) that always be a reference to object of current class (scope of current class).

like image 574
Anton Danilchenko Avatar asked Nov 17 '14 18:11

Anton Danilchenko


1 Answers

So I finally figured out that you are talking about the self variable in the sayHello method that is giving you problems.

You need to google JavaScript scope this tutorial - it's not the most intuitive concept, but once you get it, everything will make sense.

In the mean time, it's worth pointing out that self is not a reserved word in JavaScript and doesn't do anything special, but this is.

So what you want, is something like this:

function Class (_properties) {

    // copy all properties and methods to this class
    for (var _property_name in _properties) {
        this[_property_name] = _properties[_property_name];
    }
}

var User = new Class({
    name: 'No name',
    sayHello: function () {
        console.log(this.name);
    }
});
var user1 = new User();
var user2 = new User();

The keyword new in front of the Class() function causes it to be executed as a constructor function meaning that, inside of the constructor function this will reference it's own scope.

Also, because the property sayHello is a function to be executed inside the scope that you created, you can use this.name - as this will refer to the scope that you created when you instantiated a new Class.

And just because this scope thing is no doubt confusing (don't worry, it probably will be for a while) - if you haven't created a scope (by using a constructor or object literal) you're working inside of the global scope which, in the case of the browser, is the Window object.

like image 110
Adam Avatar answered Nov 11 '22 16:11

Adam