22
5/13/2009 1 IF2032 Pemrograman Berorientasi Objek Javascript - Prototype Achmad Imam Kistijantoro ([email protected]) Yani Widyani ([email protected] ) Februari 2009 Informatika STEI ITB Sumber: Object-Oriented JavaScript, Create scalable, reusable high-quality JavaScript applications, and libraries, Stoyan Stefanov, 2008

JavaScript Properties

Embed Size (px)

DESCRIPTION

Slide mata kuliah Pemrograman Berorientasi Objek : Javascript Properties

Citation preview

Page 1: JavaScript Properties

5/13/2009 1

IF2032Pemrograman Berorientasi ObjekJavascript - Prototype

Achmad Imam Kistijantoro ([email protected])Yani Widyani ([email protected])Februari 2009Informatika – STEI – ITB

Sumber: Object-Oriented JavaScript, Create scalable, reusable high-quality JavaScript applications, and libraries, Stoyan Stefanov, 2008

Page 2: JavaScript Properties

prototype Property

Property of the function objects created as soon as you define the function

its initial value is an empty object

>>> function foo(a, b){return a * b;}

>>> typeof foo.prototype

"object“

You can augment this empty object with properties and methods They won't have any effect of the foo() function itself

they'll only be used when you use foo() as a constructor

Page 3: JavaScript Properties

Adding methods and properties

function Gadget(name, color) { this.name = name; this.color = color; this.whatAreYou = function(){

return 'I am a ' + this.color + ' ' + this.name; }

}

Adding methods and properties:Gadget.prototype.price = 100;Gadget.prototype.rating = 3;Gadget.prototype.getInfo = function() {

return 'Rating: ' + this.rating + ', price: ' + this.price;};

Adding methods and properties to the prototype property of the constructor function is another way to add functionality to the objects this constructor produces

Page 4: JavaScript Properties

Adding methods and properties (2)

Gadget.prototype = { price: 100, rating: 3, getInfo: function() {

return 'Rating: ' + this.rating + ', price: ' + this.price; }

};

Page 5: JavaScript Properties

Using the Prototype’s methods and properties

>>> var newtoy = new Gadget('webcam', 'black');>>> newtoy.name; "webcam“

>>> newtoy.color; "black“

>>> newtoy.whatAreYou(); "I am a black webcam"

>>> newtoy.price; 100

>>> newtoy.rating; 3

>>> newtoy.getInfo(); "Rating: 3, price: 100“

Page 6: JavaScript Properties

Using the Prototype’s methods and properties (2)

Gadget.prototype.get = function(what) { return this[what];};

Even though newtoy was created before the get() method was defined, newtoy will still have access to the new method:

>>> newtoy.get('price'); 100>>> newtoy.get('color'); "black"

Page 7: JavaScript Properties

Own vs prototype properties

>>> var newtoy = new Gadget('webcam', 'black');

When you try to access a property of newtoy, say newtoy.name the JavaScript engine will look through all of the properties of the object searching for one called name and, if it finds it, will return its value.>>> newtoy.name "webcam“

What if you try to access the rating property, the JavaScript engine will examine all of the properties of newtoy and will not find the one called rating.

The script engine will identify the prototype of the constructor function used to create this object

If the property is found in the prototype, this property is used.>>> newtoy.rating 3

Page 8: JavaScript Properties

Own vs prototype properties (2)

Every object has a constructor

The prototype is an object, so it must have a constructor too, which in turn has a prototype>>> newtoy.constructor.prototype.constructor

Gadget(name, color)

>>> newtoy.constructor.prototype.constructor.prototype

Object price=100 rating=3

prototype chain

Page 9: JavaScript Properties

Overwriting prototype’s property with own property If the own property has the same name with the prototype’s property, the own

property takes precedence over the prototype'sfunction Gadget(name) {

this.name = name;}Gadget.prototype.name = 'foo'; "foo"

Creating a new object and accessing its name property gives you the object's own name property

>>> var toy = new Gadget('camera');>>> toy.name; "camera"

If you delete this property, the prototype's property with the same name "shines through":

>>> delete toy.name; true>>> toy.name; "foo"

Page 10: JavaScript Properties

Enumerating properties

function Gadget(name, color) { this.name = name; this.color = color; this.someMethod = function(){return 1;}

}Gadget.prototype.price = 100;Gadget.prototype.rating = 3;

for (var prop in newtoy) { console.log(prop + ' = ' + newtoy[prop]);

}

name = webcam color = black someMethod = function () { return 1; } price = 100 rating = 3

Page 11: JavaScript Properties

Enumerating properties (2)

Notes: Not all properties show up in a for-in loop. For example, the

length (for arrays) and constructor properties will not show up. The properties that do show up are called enumerable. You can check with the propertyIsEnumerable() method

Prototypes that come through the prototype chain will also show up, provided they are enumerable You can check if a property is an own property using the

hasOwnProperty() method

propertyIsEnumerable() will return false for all of the prototype's properties, even those that are enumerable and will show up in the for-in loop

Page 12: JavaScript Properties

hasOwnProperty()

>>> newtoy.hasOwnProperty('name') true>>> newtoy.hasOwnProperty('price') False

for (var prop in newtoy) { if (newtoy.hasOwnProperty(prop)) {

console.log(prop + '=' + newtoy[prop]); }

}

The result:

name=webcam color=black someMethod=function () { return 1; }

Page 13: JavaScript Properties

propertyIsEnumerable()

>>> newtoy.propertyIsEnumerable('name') true

Most built-in properties and methods are not enumerable:>>> newtoy.propertyIsEnumerable('constructor') false

Any properties coming down the prototype chain are not enumerable:>>> newtoy.propertyIsEnumerable('price') false

However, that such properties are enumerable if you reach the objectcontained in the prototype and invoke its propertyIsEnumerable().>>> newtoy.constructor.prototype.propertyIsEnumerable('price') true

Page 14: JavaScript Properties

isPrototypeOf()

tells you whether that specific object is used as a prototype of another objectvar monkey = {

hair: true, feeds: 'bananas', breathes: 'air'

};

function Human(name) { this.name = name;

} Human.prototype = monkey;

>>> var george = new Human('George'); >>> monkey.isPrototypeOf(george) true

Page 15: JavaScript Properties

The secret __proto__ link

var developer = new Human();developer.feeds = 'pizza';developer.hacks = 'JavaScript';

>>> developer.constructor = 'junk' "junk"

It seems like the prototype is now all messed up:>>> typeof developer.constructor.prototype "undefined"

...but it isn't, because the developer still breathes "air":>>> developer.breathes ”air”

Page 16: JavaScript Properties

The secret __proto__ link (2)

The secret link to the prototype still exists The secret link is exposed in Firefox as the __proto__

property

>>> developer.__proto__ Object feeds=bananas breathes=air

You can use this secret property for learning purposes but it's not a good idea to use it in your real scripts, because it does not exist in Internet Explorer, so your scripts won't be portable __proto__ is a property of the instances prototype is a property of the constructor functions

Page 17: JavaScript Properties

Augmenting built-in objects

The built-in objects such as the constructor functions Array, String, and even Object, and Function can be augmented through their prototypes

which means that you can, for example, add new methods to the Array prototype and in this way make them available to all arrays

Page 18: JavaScript Properties

Augmenting built-in objects (2)

Array.prototype.inArray = function(needle) { for (var i = 0, len = this.length; i < len; i++) {

if (this[i] === needle) { return true;

} } return false;

}

>>> var a = ['red', 'green', 'blue'];>>> a.inArray('red'); True

String.prototype.reverse = function() { return Array.prototype.reverse.apply(this.split('')).join('');

}

>>> "Stoyan".reverse(); "nayotS"

Page 19: JavaScript Properties

Augmenting built-in objects (3)

If you decide to augment the prototype of built-in objects with a new property, do check for existence of the new property first.

if (!String.prototype.reverse) {

String.prototype.reverse = function() {

return Array.prototype.reverse.apply(this.split('')).join('');

}

}

Page 20: JavaScript Properties

Notes

two interesting behaviors to consider when dealing with prototypes:

The prototype chain is live with the exception of when you completely replace the prototype object

prototype.constructor is not reliable

Page 21: JavaScript Properties

>>> function Dog(){this.tail = true;}>>> var benji = new Dog();>>> var rusty = new Dog();

>>> Dog.prototype.say = function(){return 'Woof!';}>>> benji.say(); "Woof!“

>>> Dog.prototype = {paws: 4, hair: true};>>> typeof benji.paws "undefined">>> benji.say() "Woof!"

Page 22: JavaScript Properties

>>> var lucy = new Dog();>>> lucy.say() TypeError: lucy.say is not a function>>> lucy.paws 4

The secret __proto__ link points to the new prototype object

The following would have fixed all of the unexpected behavior described above:>>> Dog.prototype = {paws: 4, hair: true};>>> Dog.prototype.constructor = Dog;

When you overwrite the prototype, it is a good idea to reset the constructor property