How to initial a object properties by functions?

C

Cylix

The following example are going to create an object to store the client
Information,
I would like to new the object to init all the properties by function:
setProperty()
Can I set the value to the object without using the global variable ?

Thank you.

///---------------The object -------------------------------
function clientENV {
var detect = navigator.userAgent.toLowerCase();
this.os;
this.browser;
this.version;

setProperty();
}

///-------------Function------------------------------------
var theString, place, OS, browser, version;
function setProperty() {
if (checkIt('msie')) browser = "Internet Explorer"
else if (checkIt('Firefox')) browser = "Safari"
else if (checkIt('safari')) browser = "Safari"
else if (checkIt('omniweb')) browser = "OmniWeb"
else if (checkIt('opera')) browser = "Opera"
else if (checkIt('webtv')) browser = "WebTV";
else if (checkIt('icab')) browser = "iCab"
else if (checkIt('konqueror')) {
browser = "Konqueror";
OS = "Linux";
} else if (!checkIt('compatible')) {
browser = "Netscape Navigator"
version = detect.charAt(8);
}
else browser = "An unknown browser";

if (!version) version = detect.charAt(place + thestring.length);

if (!OS) {
if (checkIt('linux')) OS = "Linux";
else if (checkIt('x11')) OS = "Unix";
else if (checkIt('mac')) OS = "Mac"
else if (checkIt('win')) OS = "Windows"
else OS = "an unknown operating system";
}
}

function checkIt(string) {
place = detect.indexOf(string) + 1;
thestring = string;
return place;
}
 
R

Richard Cornford

Cylix said:
The following example are going to create an object to
store the client Information, I would like to new the
object to init all the properties by function: setProperty()
Can I set the value to the object without using the
global variable ?

Thank you.

///---------------The object -----------------------
function clientENV {
^^
There should be an arguments list in this (potentially empty) if this is
intended to be a function declaration.
var detect = navigator.userAgent.toLowerCase();

Your - detect - variable appears to be local but you are using it as if
it was global (referencing it in other functions). Passing values
between functions via global variables is a very bad design pattern. You
should pass such values as arguments to the functions or properties of
objects for which those functions are methods.
this.os;
this.browser;
this.version;

setProperty();
}

If you mean that you want this - setProperty - function to act upon an
object created using - new clientENV() - then you make - setProperty -
into a method of the resulting object, probably by assigning it to the
prototype of - clientENV -:-

clientENV.prototype.setProperty = function(){
if(something){
this.propertyName = 'x';
}
// etc.
};

- and call it in the constructor as:-

this.setProperty();
///-------------Function-----------------------------
var theString, place, OS, browser, version;
function setProperty() {
if (checkIt('msie')) browser = "Internet Explorer"
else if (checkIt('Firefox')) browser = "Safari"
else if (checkIt('safari')) browser = "Safari"
else if (checkIt('omniweb')) browser = "OmniWeb"
else if (checkIt('opera')) browser = "Opera"
else if (checkIt('webtv')) browser = "WebTV";
else if (checkIt('icab')) browser = "iCab"
else if (checkIt('konqueror')) {
browser = "Konqueror";
OS = "Linux";
} else if (!checkIt('compatible')) {
browser = "Netscape Navigator"
version = detect.charAt(8);
}
<snip>

This is browser detection. Browser detection is an utterly futile
activity that has been abandoned in favour of better alternatives (at
least by everyone who knows what they are doing). If you are only just
starting to learn browser scripting (which is the obvious conclusion
from what you have posted here) then you should not even attempt to go
in the browser detection direction as eventually you will have to
re-trace your steps and learn proper feature detection (and everything
you write in the meanwhile will be very poor at best).

<URL: http://jibbering.com/faq/faq_notes/not_browser_detect.html >

Richard.
 
R

RobG

Cylix said:
The following example are going to create an object to store the client
Information,
I would like to new the object to init all the properties by function:
setProperty()
Can I set the value to the object without using the global variable ?

Richard's response is pretty good, I prepared this before seeing his so
I'll post it anyway.

Without commenting on the actual example, what you are trying to do is
fairly common: you want a small object that also has methods to set its
own values, but you don't want all the methods replicated inside each
and every instance of the object. That's what JavaScript's prototype
inheritance is good at.

Have the constructor set the values, add the methods to the
constructor's prototype. As a cut-down version of your script:

// By convention, constructors start with a capital letter
function ClientENV()
{
// Set some default property values - not really necessary
// But keeps things tidy
this.os = 'default';
this.browser = 'default';
this.platform = 'default';

// Call setProperties, pass reference to the
// object being constructed
this.setProperties(this);
}

// Add the setProperties function as a method of the
// constructor's prototype so it's only one object, not
// a new instance for every object created
ClientENV.prototype.setProperties = function(obj)
{
obj.os = 'blah OS';
obj.browser = 'blah Browser';
}

var thisENV = new ClientENV();


alert(thisENV.os + '\n' + thisENV.browser
+ '\n' + thisENV.platform);


Of course, using the above is moot since you are likely to only create
one 'thisENV' object anyway, so you might be better to use:

var thisENV = getENVProperties();

Where getENVProperties() returns an object with appropriate
properties/values:

function getENVProperties ()
{
var tempObj = {};
tempObj.os = 'blah OS';
tempObj.browser = 'blah Browser';
return tempObj;
}

I think that's simpler and the outcome is pretty much identical.

[...]
 
C

Cylix

Richard said:
<snip>

This is browser detection. Browser detection is an utterly futile
activity that has been abandoned in favour of better alternatives (at
least by everyone who knows what they are doing). If you are only just
starting to learn browser scripting (which is the obvious conclusion
from what you have posted here) then you should not even attempt to go
in the browser detection direction as eventually you will have to
re-trace your steps and learn proper feature detection (and everything
you write in the meanwhile will be very poor at best).

I heard a lot of time about these thing, but sometimes ...
I really need to detect the client environment,
for example, I am going to use AJAX, but some of older browser does not
support that,
I need to mention the reason to the client and show the client a more
static page.
How can I present it better?

Thank you.
 
R

RobG

RobG wrote:
[...]
// By convention, constructors start with a capital letter
function ClientENV()
{
// Set some default property values - not really necessary
// But keeps things tidy
this.os = 'default';
this.browser = 'default';
this.platform = 'default';

// Call setProperties, pass reference to the
// object being constructed
this.setProperties(this);

Hey, musta been asleep ... don't need to pass this:

this.setProperties();
}

ClientENV.prototype.setProperties = function(obj)
{
obj.os = 'blah OS';
obj.browser = 'blah Browser';
}

And setProperties is:

ClientENV.prototype.setProperties = function()
{
this.os = 'blah OS';
this.browser = 'blah Browser';
}
 
L

Lasse Reichstein Nielsen

Cylix said:
I really need to detect the client environment,
for example, I am going to use AJAX, but some of older browser does not
support that,
I need to mention the reason to the client and show the client a more
static page.

The test for the existence of an XMLHttpRequest object through the
known methods of acquireing one: global XMLHttpRequest constructor
or IE's ActiveX-controls.
There are known ways of checking this:
How can I present it better?

Make the page default to the static behavior if Javascript is disabled
or if there is no XMLHttpRequest object. Then change behavior if it
is possible.

/L
 
R

Richard Cornford

I heard a lot of time about these thing, but sometimes ...
I really need to detect the client environment,

In the event that you find a situation where you really need to detect
the browser being used you will have a problem as no mechanism is known
that can reliable do that, and examining the contents of the -
navigator.userAgent - string is easily the least discriminating strategy
available.
for example, I am going to use AJAX, but some of older
browser does not support that,

Some absolute brand new browsers will not support it either, but the
tests you are performing have little practical relationship with a
browsers ability (or even potential ability) to do AJAX. Logically, in
order to determine a browser's ability to do AJAX from browse detection
it would first be necessary to know which versions of which browsers
provide an XML HTTP request facility. Do you know, for example, which
minor version of IceBrowser introduced support for XML HTTP requests?

Knowing which versions of which browsers support XML HTTP requests it
becomes necessary to discriminate those browsers from the ones that do
not. While the code you are proposing using will not even discriminate
between IE and Opera (if Opera is using one of its variable User Agent
strings). How are you planning on identifying IceBrowser, let alone
discriminate between its versions sufficiently to identify its support
for AJAX?

However, on a browser as common as IE 6 the ability to employ XML HTTP
requests is guaranteed by the type or version of the browsers. The XML
HTTP request object is an ActiveX component outside of the browser so it
may be removed from the system independently from the browser. In
addition, even if the ActiveX object is installed on the system IE's
security settings are allowed to veto the availability of various
categories of ActiveX controls. And finally Internet security programs
may effectively block the use of ActiveX objects as a security measure.
I need to mention the reason to the client and show the
client a more static page.
How can I present it better?

The most reliable method of determining that you have an ability to
employ an XML HTTP request object is to attempt to instantiate one. If
you cannot do that then you may as well fall back to your alternative.
Though in reality any application of AJAX will depend on the browser
providing facilities well beyond the simple XML HTTP request object, so
they should also be feature detected as well.

Richard.
 
C

Cylix

Thanks Rob and Richard.

I think I abuse to use the term AJAX,
Actually, I just doing the thing like AJAX but not using XML http
request.

My case is that, I need to using javascript to generate the whole
table,
you may think that it is a grid.

I have already test the js and get the interface in
PC {IE6, Firefox1.5}, Mac {Safari1.3.1, IE5.2}

As my boss using Mac IE5.2, I have to ensure it works on Mac IE5.2.
However, I find that one of important page cannot show on Mac IE5.2
properly,
the reason seems a bug of Mac IE5.2.

The bug is that when I using js(using createElement of
insertRow+insertCell),
If the innerHTML(or createElement('img') and then append on it)
contains <img> or any other HTML tag(I have tried IMG and SPAN only),
there is a great space around 300px on the cell, It doesn't matter that
I have other CSS to control the width.

One more problem that is Mac IE tabledata(td) seems doesn't have
colSpan property...
 
C

Cylix

RobG said:
And setProperties is:

ClientENV.prototype.setProperties = function()
{
this.os = 'blah OS';
this.browser = 'blah Browser';
}

What is the differnece if I set the setProperties like this:
function clientENV {
....
....
this.setProperties=setP
}

function setP {
....
....
}

Actually, I will create this object when the pages onLoad,
I just need the property variable but no need the function
setProperties on the object,
Does there a way that when I "new clientENV", the properties is set
already and the clientENV only contain the proper value?

Thanks.
 
R

RobG

Cylix said:
What is the differnece if I set the setProperties like this:
function clientENV {
...
...
this.setProperties=setP
}

function setP {
...
...
}

Actually, I will create this object when the pages onLoad,
I just need the property variable but no need the function
setProperties on the object,
Does there a way that when I "new clientENV", the properties is set
already and the clientENV only contain the proper value?

The only decision you have to make is whether to add the setP function
to the global (window) object or the ClientENV constructor's prototype.

Either way, the end result is the same - you have a setP object and an
ENV object with its properties set.

If you have a large and complex application, and setP only relates to
the ENV object, then making it a property of the constructor makes sense
from a house keeping (i.e. architectural) viewpoint. But if you have a
simple application - just a page with a few functions - then that seems
unnecessary. I wouldn't even have a constructor, I'd just do:

var ENV = setENVprops();

function setENVprops(){
var tObj = {};
// set tObj properties
return tObj;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top