官术网_书友最值得收藏!

Objects in JavaScript

JavaScript is an object-oriented language, but most people don't make use of the object-oriented features of it except in passing. JavaScript uses a mixed object model in that it has some primatives as well as objects. JavaScript has five primitive types:

  • Undefined
  • Null
  • Boolean
  • String
  • Number

Of these five, really only three of them are what one would expect to be an object anyway. The other three, boolean, string, and number all have wrapped versions, which are objects: Boolean, String, and Number. They are distinguished by starting with uppercase. This is the same sort of model used by Java: a hybrid of objects and primitives.

JavaScript will also box and unbox the primitives as needed.

In the following code, you can see the boxed and unboxed versions of JavaScript primitives at work:

var numberOne = new Number(1);
var numberTwo = 2;
typeof numberOne; //returns 'object'
typeof numberTwo; //returns 'number'
var numberThree = numberOne + numberTwo;
typeof numberThree; //returns 'number'

Creating objects in JavaScript is trivial. This can be seen in the following code for creating an object in JavaScript:

var objectOne = {};
typeof objectOne; //returns 'object'
var objectTwo = new Object();
typeof objectTwo; //returns 'object'

Because JavaScript is a dynamic language, adding properties to objects is also quite easy. This can be done even after the object has been created. The following code creates:

var objectOne = { value: 7 };
var objectTwo = {};
objectTwo.value = 7;

Objects contain both data and functionality. We've only seen the data part so far. Fortunately, in JavaScript, functions are first class objects. Functions can be passed around and assigned to variables. Let's try adding some functions to an object, as seen in the following code:

var functionObject = {};
functionObject.doThings = function() {
  console.log("hello world");
}
functionObject.doThings(); //writes "hello world" to the console

This syntax is a bit painful, building up objects an assignment at a time. Let's see if we can improve upon the syntax for creating objects:

var functionObject = {
  doThings: function() {
    console.log("hello world");
  }
}
functionObject.doThings();//writes "hello world" to the console

This syntax seems, at least to me, to be a much cleaner, more traditional way of building objects. Of course, it is possible to mix data and functionality in an object in the following fashion:

var functionObject = {
  greeting: "hello world",
  doThings: function() {
    console.log(this.greeting);
  }
}
functionObject.doThings();//prints hello world

There are a couple of things to note in this piece of code. The first is that the different items in the object are separated using a comma, not a semicolon. Those coming from other languages such as C# or Java are likely to make this mistake, I know that I did.

The next item of interest is that we need to make use of the this qualifier to address the greeting variable from within the doThings function. This would also be true if we had a number of functions within the object, as shown in the following code:

var functionObject = {
  greeting: "hello world",
  doThings: function() {
    console.log(this.greeting);
    this.doOtherThings();
  },
  doOtherThings: function() {
    console.log(this.greeting.split("").reverse().join(""));
  }
}
functionObject.doThings();//prints hello world then dlrow olleh

The this keyword behaves differently in JavaScript from what you might expect coming from other C-syntax languages. This is bound to the owner of the function in which it is found. However, the owner of the function is sometimes not what you expect. In the preceding example, this is bound to functionObject; however, if the function was declared outside of an object, this would refer to the global object. In certain circumstances, typically event handlers, this is rebound to the object firing the event.

Thus, in the following code, this takes on the value of target. Getting used to the value of this is, perhaps, one of the trickiest things in JavaScript:

var target = document.getElementById("someId");
target.addEventListener("click", function() {
  console.log(this);
}, false);

We have built up a pretty complete model of how to build objects within JavaScript. However, objects are not the same thing as classes. Objects are instances of classes. If we want to create multiple instances of our functionObject instance, we're out of luck. Attempting to do so will result in an error. In the case of Node.js, the error will be as follows:

var obj = new functionObject();
TypeError: object is not a function
    at repl:1:11
    at REPLServer.self.eval (repl.js:110:21)
    at repl.js:249:20
    at REPLServer.self.eval (repl.js:122:7)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)
    at Interface._onLine (readline.js:202:10)
    at Interface._line (readline.js:531:8)
    at Interface._ttyWrite (readline.js:760:14)
    at ReadStream.onkeypress (readline.js:99:10)

The stack trace here shows an error in a module called repl. This is the read-execute-print loop that is loaded by default when starting Node.js.

Each time that a new instance is required, the object must be reconstructed. To get around this, we can define the object using a function, as shown in the following code:

var ThingDoer = function(){
  this.greeting = "hello world";
  this.doThings = function() {
    console.log(this.greeting);
    this.doOtherThings();
  };
  this.doOtherThings = function() {
    console.log(this.greeting.split("").reverse().join(""));
  };
}
var instance = new ThingDoer();
instance.doThings();//prints hello world then dlrow olleh

This syntax allows for a constructor to be defined and for new objects to be created from this function. Constructors without return values are functions that are called as an object is created. In JavaScript, the constructor actually returns the object created. You can even assign internal properties using the constructor by making them part of the initial function, as follows:

var ThingDoer = function(greeting){
  this.greeting = greeting;
  this.doThings = function() {
    console.log(this.greeting);
  };
}
var instance = new ThingDoer("hello universe");
instance.doThings();

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

主站蜘蛛池模板: 洱源县| 灵宝市| 沅江市| 乡城县| 陈巴尔虎旗| 南陵县| 凯里市| 庐江县| 丁青县| 手游| 巨野县| 兴业县| 理塘县| 晴隆县| 四川省| 乌鲁木齐市| 施甸县| 长丰县| 黑山县| 丘北县| 临高县| 南靖县| 巨鹿县| 岳普湖县| 噶尔县| 仁怀市| 封丘县| 巴彦县| 陇南市| 西华县| 绍兴市| 鹤庆县| 苏尼特左旗| 宁南县| 巍山| 烟台市| 宜良县| 怀仁县| 金阳县| 东乡| 河津市|