Category Archives: Uncategorized

JavaScript Prototypes for the Object Oriented Developer

I interview plenty of Web Developers who list JavaScript (not just JQuery) as a technical skill.  But when I ask them what a prototype is in JavaScript they give me blank stares.  This would be like a candidate coming in for an Object Oriented interview (C++ / Java / C#) and not knowing what inheritance is.

So in the interest of getting future job candidates prepared for one of my interview questions before coming through my door, I will demonstrate JavaScript prototypes with an example:

function parent() {};

var child1 = new parent();

// this line will throw an exception as there is no function called namemyparent()
child1.namemyparent();

// now lets create the function on the parent
function adam() { return "Adam"; }
parent.prototype.namemyparent = adam;

// lets try this again -- now returns "Adam" -- the child dynamically inherited a new method from the parent
child1.namemyparent();

// unlike object oriented languages (such as C#) we can change the parent anytime
function ilene() {return "Ilene"};
parent.prototype.namemyparent = ilene;

// check this out -- child now returns "Ilene"
child1.namemyparent();

In other words, a prototype allows you to extend a JavaScript object with methods or properties.  They are kind of like a dynamic language version of C# extension methods.  (Of course prototypes came long before C# extension methods.  Prototypes where added to JavaScript in 1996.  The first version of C# came in 2002 and the first version with extension methods came in 2007.  Also prototypes support properties, not just methods.)

I like to think of prototypes more like object oriented inheritance.  But there is at least one major exception.  Once a parent class is defined in an object oriented language it cannot be changed.  This restriction is likely what caused Microsoft to have to introduce extension methods to support new concepts like LINQ.  As I demonstrated, the ‘parent’ may change at any time in JavaScript.

Of course prototypes allow me to do all the fun things I can do with inheritance in object oriented languages, including replicating the concept of polymorphism. There is even a JavaScript operator to verify whether a child belongs to a parent: instanceof.

AWS Gotcha: IAmazonS3.CopyObject() Method On S3 Objects Changes ACLs

There are many gotchas with Amazon’s AWS (I suppose that is true with all technologies).  Here is one that plagued me just the other day:

I had a bunch of publicly readable files in an S3 bucket.  I needed to update some headers for all items in the bucket, so I wrote a PowerShell script that calls the AWS .Net SDK CopyObject() method on an instance of the Amazon.S3.AmazonS3Client class. (Of course, I could have just done this in C# but PowerShell seemed easier for my purposes.)

Advanced aside: CopyObject() actually comes from the IAmazonS3 interface, which is implenented in AmazonS3Client. An AmazonS3Client object is returned from the Amazon.AWSClientFactory.CreateAmazonS3Client() factory method as show below.

This is an excerpt from my script, the variables should be self explanatory if you are familiar with AWS:

$s3Config = New-Object Amazon.S3.AmazonS3Config
$s3Config.RegionEndpoint = [Amazon.RegionEndpoint]::USEast1
$s3client = [Amazon.AWSClientFactory]::CreateAmazonS3Client($AccessKey, $SecretKey, $s3Config)

$s3Request = New-Object Amazon.S3.Model.CopyObjectRequest 
$s3Request.MetadataDirective = "REPLACE"
$s3Request.SourceBucket = $s3Bucket
$s3Request.SourceKey = $s3object.Key;
$s3Request.DestinationBucket = $s3Bucket
$s3Request.DestinationKey = $s3object.Key;
$s3Request.Headers.Item('Content-Disposition') =  <new-content-disposition>
$s3Request.Headers.Item('Content-Type') = <new content type>
$s3client.CopyObject($s3Request)

What I learned too late was that CopyObject() removes the public read ACL from my $s3Object.  I ended up needing to clean up my S3 objects to re-enable public read, using another PowerShell script similar to the following:

$s3Config = New-Object Amazon.S3.AmazonS3Config
$s3Config.RegionEndpoint = [Amazon.RegionEndpoint]::USEast1
$s3client = [Amazon.AWSClientFactory]::CreateAmazonS3Client($AccessKey, $SecretKey, $s3Config)

$s3Request = New-Object Amazon.S3.Model.PutACLRequest
            
$s3Request.BucketName = $s3Bucket
$s3Request.Key = $s3object.Key
$s3Request.CannedACL = [Amazon.S3.S3CannedACL]::PublicRead
$s3client.PutACL($s3Request) > $null

I guess the moral of the story is 1) AWS is fraught with best practices that can only be learned by making mistakes, and 2) Test. Test. Test.