How Can I Fix the Object.defineProperty Error in the PhoneGap Developer App JavaScript

As a developer working with hybrid mobile apps, I recently ran into a frustrating issue while testing my project on a Windows Phone using the PhoneGap Developer App. I was excited to see my app come to life, but instead of my UI, I was greeted with a JavaScript error that said:

Object doesn't support property or method "defineProperty"

At first, I was confused because the same code worked flawlessly when I opened the HTML page in the Windows Phone browser. So I decided to dig into it and in this post, I’ll walk you through the error, explain why it happens, and share the fix that worked for me, along with some practice code you can play with.

The Code That Caused the Error

Here’s the snippet that triggered the issue:

Object.defineProperty(Detail, "name", {
get: function () { return this._name; },
set: function (value) { this._name = value; },
enumerable: true,
configurable: true
});

This code uses Object.defineProperty to create a getter/setter for the name property on a JavaScript object. It’s perfectly valid in modern browsers and in fact, when I tested it directly in the Windows Phone 8.1 browser, it worked fine.

But when I launched the app using the PhoneGap Developer App, the exact same code threw that dreaded error.

What’s Going On

The Real Problem

The issue lies in the JavaScript engine used by the PhoneGap Developer App on Windows Phone. While the built-in browser on Windows Phone supports ECMAScript 5 features like Object.defineProperty, the WebView engine embedded in the PhoneGap Developer App does not or at least, it doesn’t support them fully, especially for plain JavaScript objects.

So although Object.defineProperty might work on DOM elements (like document.body), it fails on regular objects (like my Detail object) when run inside the PhoneGap Developer App.

Fix That Worked for Me

To solve the issue, I had two choices: either avoid using Object.defineProperty altogether or implement a fallback method.

Avoid Object.defineProperty

I replaced the property definition with direct assignment and added simple functions to handle setting and getting values.

Detail = {
_name: "Default Name",
setName: function (value) {
this._name = value;
},
getName: function () {
return this._name;
}
};

Detail.setName("Zoya");
console.log(Detail.getName()); // Output: Zoya

This approach gave me complete compatibility and worked smoothly across all devices, including Windows Phone.

Polyfill for Older Engine

I also tried using a polyfill for environments that don’t support Object.defineProperty. But be warned: this doesn’t provide full support especially not in legacy WebViews.

(typeof Object.defineProperty !== 'function') {
Object.defineProperty = function(obj, prop, descriptor) {
if (descriptor.get) {
obj["get" + prop] = descriptor.get;
}
if (descriptor.set) {
obj["set" + prop] = descriptor.set;
}
return obj;
};
}

This acts as a kind of fallback and helps avoid runtime crashes, but it’s not a perfect solution.

Safe Property Handle

To reinforce what I learned, I created a practice-friendly version of the code using direct methods. It’s simpler, readable, and works everywhere:

Detail = {
_name: "Initial Name",
setName: function(name) {
this._name = name;
},
getName: function() {
return this._name;
},
print: function() {
console.log("Name is: " + this.getName());
}
};

// Practice usage
Detail.print(); // Output: Name is: Initial Name
Detail.setName("Zoya");
Detail.print(); // Output: Name is: Zoya

This pattern not only avoids compatibility issues, but it also makes your code more readable and easier to debug.

Ditch the Developer App for Real Build

If you’re using Windows Phone, I recommend building your project using the PhoneGap CLI instead of testing through the Developer App. Just run:

cordova build windows

This will generate a real Windows app package that runs with the full system browser engine instead of the outdated WebView used by the Developer App.

Final Thought

Dealing with legacy JavaScript engines can be frustrating especially when your code works in one browser but crashes in another. This Object.defineProperty issue is a perfect example of why understanding your runtime environment is just as important as writing clean code.

By falling back to simpler approaches and avoiding newer syntax where it’s unsupported, I was able to get my app working again even on older phones. I hope this helped you if you’re facing the same problem.

Feel free to modify the sample project above and explore how JavaScript objects behave across environments. And remember: compatibility first, cleverness second.

Related blog posts