Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

strange problem with external script

0 views
Skip to first unread message

luismgz

unread,
Sep 3, 2010, 9:28:40 AM9/3/10
to
Sorry if I'm doing something stupid, but I just can't understand what
I'm doing wrong...
I wrote a function in an external script, which is included in my page
with this tag "<script src="pythonic.js></script>".
The function extends String. prototype as follows:


String.prototype.title = function(){
var s = [];
var ss = this.split(' ');
for(i in ss) s.push(ss[i].slice(0,1).toUpperCase() +
ss[i].slice(1).toLowerCase());
return s.join(' ');
}

(This function capitalises all the first letters of each word in a
string).
The problem is that when used from an external script, it doesn't work
(there are other functions in the same script that work fine).
But if I copy and paste it into the page, it works.

Why?

SteveYoungGoogle

unread,
Sep 3, 2010, 9:43:16 AM9/3/10
to
On Sep 3, 3:28 pm, luismgz <luis...@gmail.com> wrote:
> Sorry if I'm doing something stupid, but I just can't understand what
> I'm doing wrong...
> I wrote a function in an external script, which is included in my page
> with this tag "<script src="pythonic.js></script>".

You should include type:

<script src="src="pythonic.js" type="text/javascript"></script>

Regards, Steve.

Asen Bozhilov

unread,
Sep 3, 2010, 9:45:33 AM9/3/10
to
luismgz wrote:

> The function extends String. prototype as follows:
>
> String.prototype.title = function(){
>         var s = [];
>         var ss = this.split(' ');
>         for(i in ss) s.push(ss[i].slice(0,1).toUpperCase() +
> ss[i].slice(1).toLowerCase());
>         return s.join(' ');
>
> }

The expression statement should end with semicolon. From posted code
and described behaviour I am suspecting the follow part of your code
does not allow automatic semicolon insertion by interpreter. For
example:

var func = function (){
//...
}

(function () {
}())

That code will call both functions. If you put semicolon after `func'
assignment. Will be called only the anonymous function. Please show
the rest of your code.


Asen Bozhilov

unread,
Sep 3, 2010, 9:48:44 AM9/3/10
to
Asen Bozhilov wrote:

> That code will call both functions. If you put semicolon after `func'
> assignment. Will be called only the anonymous function. Please show
> the rest of your code.

And put explicitly a semicolon where is needed. You should use IDE
which is closer to ECMAScript nature.

luismgz

unread,
Sep 3, 2010, 9:55:55 AM9/3/10
to

I simply test it as follows:

document.write( "this is my sample text string".title() );

Again, if I define this function in the same document, it works. But
using it from "pythonic.js" it doesn't work.

One hint:
If I delete all the other functions in "pythonic.js", it works.
I guess there's some kind of conflict, but I don't know. I tried
deleting one function at a time so I can identify the conflicting
code, but I couldn't find the problem.

This is the full code in "pythonic.js":

String.prototype.title = function(){
var s = [];
var ss = this.split(' ');

for(var i in ss) s.push(ss[i][0].toUpperCase() +


ss[i].slice(1).toLowerCase());
return s.join(' ');
}

function range() {
if (range.arguments.length > 1){
var begin = arguments[0];
var end = arguments[1];
}
else{
var begin = 0;
var end = arguments[0];
}
var x = [];
for(var i = begin; i < end; i++) x.push(i);
return x;
}

function show(o){
if(typeof(o)=='object') {
var s = [];
for(i in o){
if(typeof(o[i]) != 'function')
s.push(i + ' : "' + o[i] +'", ');
}
s = s.join('').slice(0, -2);
document.writeln('[' + s + ']');
}
else
document.writeln(o);
}

Array.prototype.comp = function(compstring){
var args = compstring.split(' ');
switch(args.length){
case 1:
var func = new Function('i', 'return ' + args[0]);
break;
case 2:
var func = new Function(args[1], 'return ' + args[0]);
break;
case 3:
var func = new Function(args[1], 'if (' + args[2] + '){ return ' +
args[0] + '}');
break;
case 4:
var func = new Function(args[1], 'return ' + args[2] + '?' +
args[0] + ':' + args[3]);
break;
}
var res = this.filter(func).map(func);
return res;
}

Array.prototype.sum = function(){
for(var i=0,sum=0;i<this.length;sum+=this[i++]);
return sum;
}

Array.prototype.max = function(){
return Math.max.apply({},this)
}

Array.prototype.min = function(){
return Math.min.apply({},this)
}

Asen Bozhilov

unread,
Sep 3, 2010, 10:09:43 AM9/3/10
to
luismgz wrote:

> String.prototype.title = function(){
>         var s = [];
>         var ss = this.split(' ');
>         for(var i in ss)

Your pollutions of `Array.prototype' are visible here. Why don't you
use regular `for' loop instead?

> s.push(ss[i][0].toUpperCase() +

^^^
Non standard character access. Better use standard approach as
`charAt(index)'
> ss[i].slice(1).toLowerCase());

The whole `title' can be rewritten as:

str.toLowerCase().replace(/ [A-Z]/ig, function (str) {
return str.toUpperCase();
});

Asen Bozhilov

unread,
Sep 3, 2010, 10:16:31 AM9/3/10
to
Asen Bozhilov wrote:

> str.toLowerCase().replace(/ [A-Z]/ig, function (str) {
>     return str.toUpperCase();
>
> });

The first letter must be in uppercase too.

str.toLowerCase().replace(/ [a-z]|^[a-z]/g, function (str) {
return str.toUpperCase();
})

luismgz

unread,
Sep 3, 2010, 10:18:20 AM9/3/10
to

Yes, I see.
Actually, I had also written with "slice(0,1.)" instead of
"[0]" ( which looks more pythonic by the way ).
But this is not the problem, because either way the problem persists.

I figured out that mixing functions that extend string.prototype and
array.prototype in the same script is creating some conflict.
I don't know why.

I just tried deleting all the functions that extend Array (the last
four in "pythonic.js") and now it works.
Do you know why?

luismgz

unread,
Sep 3, 2010, 10:19:59 AM9/3/10
to


What do you mean by "pollutions of Array.prototype" ?

Asen Bozhilov

unread,
Sep 3, 2010, 10:38:23 AM9/3/10
to
luismgz wrote:

> What do you mean by "pollutions of Array.prototype" ?

If you have got enough time, read the archive of the newsgroup. This
topic has been discussed many times. `for-in' loop enumerates the
properties which haven't internal {DontEnum} attribute including
properties in the prototype chain of passed object. ECMAScript 3 does
not provide way for control on internal attributes.
This is the problem with `for-in' and augmentations of built-in
prototypes. The other problem is third party collisions. For example
if I have augmented `Array.prototype' with `comp' and after that
include your "pythonic.js" my program will not work in expected way.
If you still want to use your `title' approach, use regular `for`
loop, for example:

for(var i = 0, len = ss.length; i < len; i++) {
//...
}

And don't forget to declare your variables, this is not a Python ;)
Probably because you are programmer on Python try to use `for-in' loop
over array?


luismgz

unread,
Sep 3, 2010, 10:43:47 AM9/3/10
to

YES!
Just before reading your reply I replaced the for loop as you
suggested and it works.
This is exactly the problem.

And you are right, I'm coming from python and I'm writing small
functions to mimic some features I miss from this language.
However, it is very important to make the mental switch required to
understand a new language.
I just cannot pretend to write python in javascript...

You kind help is very much appreciated.
Thank you very much Asen!

luismgz

unread,
Sep 3, 2010, 12:05:26 PM9/3/10
to
On Sep 3, 11:38 am, Asen Bozhilov <asen.bozhi...@gmail.com> wrote:
> And don't forget to declare your variables, this is not a Python ;)
> Probably because you are programmer on Python try to use `for-in' loop
> over array?

One last question:
Where exactly have I missed declaring a variable?
You mean in the for-loops?
I have checked my code and I don't see any obvious place where I
should have declared a variable.

My python habits may be causing me trouble. Please let me know if I
made mistakes here.
Thanks!

Asen Bozhilov

unread,
Sep 3, 2010, 2:54:02 PM9/3/10
to
luismgz wrote:

> One last question:
> Where exactly have I missed declaring a variable?
> You mean in the for-loops?
> I have checked my code and I don't see any obvious place where I
> should have declared a variable.

In the first message you have skipped declaration of `i' in `for-in`
loop. In Javascript if you skip declaration of variable and directly
assign value, that variable become the global variable. You can use
JSLint to handle usual mistakes:

<URL: http://jslint.com />

If you use Firefox, you can set `javascript.options.strict;true` in
your configuration, and you will get warnings in this case.

> My python habits may be causing me trouble. Please let me know if I
> made mistakes here.

I am learning Python at the moment and language has interesting syntax
and nature closer to ECMAScript.

> Thanks!

You are welcome.

luismgz

unread,
Sep 3, 2010, 7:12:29 PM9/3/10
to
On Sep 3, 3:54 pm, Asen Bozhilov <asen.bozhi...@gmail.com> wrote:

> In the first message you have skipped declaration of `i' in `for-in`
> loop. In Javascript if you skip declaration of variable and directly
> assign value, that variable become the global variable. You can use
> JSLint to handle usual mistakes:
>
> <URL:http://jslint.com/>
>
> If you use Firefox, you can set `javascript.options.strict;true` in
> your configuration, and you will get warnings in this case.

Excellent advices. Thanks again!

0 new messages