I have a function defined on the window object somewhat like this
window["functionName"] = function(){
// code here
};
Now whenever I need that function I just call
window["functionName"]();
This works well in all browsers except IE8. IE8 throws an error
SCRIPT438: Object doesn't support property or method 'functionName'
I googled for explainations but didnt find any.
EDIT: After a long time debugging I got the cause of the error
Actually the above function definition was inside another function.
function otherFunction(){
window["functionName"] = function(){
// code here
};
// code here
}
When I moved it outside it looked to work fine.
window["functionName"] = function(){
// code here
};
function otherFunction(){
// code here
}
But I still cannot understand why this weird behaviour?
Related
I'm creating an extension in chrome for the first time (I'm not a web, or javascript developer). I'm adding onto a codebase that is in an older version of javascript that I've never used (Once I'm at a computer with that codebase, I'll tag which version it is, but I can't remember).
I have a class called DownloadManager, and inside of it I am calling chrome.downloads.onChanged, and within it, I call another function inside of the class, but it can't recognize the class (I think that's the issue).
// Class named DownloadManager
function DownloadManager(someData) {
this._myData = someData;
// function that does a thing, and tests run successfully
this.doAThing = function(someData) {
// Code in here that we assume works, and there's no issues.
}
if(chrome.downloads) {
chrome.downloads.onChanged.addListener(function(delta) {
// Error here
this.doAThing(delta.data);
}
}
}
The error I'm getting is on the this.doAThing(this._myData); line. The error is Error in event handler for downloads.onChanged: TypeError: Cannot read property 'doAThing' of null at <URL>.
I'm assuming it's a scoping issue, and this. doesn't mean anything there, and it can't access doAThing there. I'm certain that the argument taken in is of the same type as the function declared above.
I'll add more data when I'm back in that environment.
Inside your event handler for chrome.downloads.onChanged the this keyword now has a different context than this inside the DownloadManager. It might make sense that since you defined the event handler within the downloadManager that you could share the variable, but that just happens to be a coincidence of "where the code was defined vs where the code is invoked from".
You could probably get away with assigning this to a variable in the main scope:
function DownloadManager(someData) {
this.doAThing = function(someData) {
// Code in here that we assume works, and there's no issues.
}
window.myScope = this;
if(chrome.downloads) {
chrome.downloads.onChanged.addListener(function(delta) {
// Error here
window.myScope.doAThing(delta.data);
}
}
}
I have controller in which i have such broadcast:
$scope.seachColumn= function () {
$scope.$broadcast('seachColumn', true);
}
Other controller which listens for the broadcast:
$scope.$on('seachColumn', function (event) {
//console.log($scope);
console.log('vuala');
});
I comment line console.log($scope), then using Chrome explorer I create beakpoint on line console.log('vuala'). When Chrome stops on this line and in the console I try to execute command console.log($scope) i am getting an error:
Uncaught ReferenceError: $scope is not defined
But if I uncomment line console.log($scope), then this line prints $scope without error.
Why this is happening?
Just out of curiosity (may not be a solution but might be interesting), what happens if you bind that function (that contains the log call) to the scope that contains $scope?
$scope.$on('seachColumn', function (event) {
//console.log($scope);
console.log('vuala');
}.bind ( this )); // or whatever context makes sense.
Naively, the undefined either means $scope doesn't exist yet (which seems unlikely since the other function that calls the function-as-argument succeeds), or the function exists in another context and the log call can't see it (since it is in that function-as-argument).
I have a class that is structured something like this
function myClass () {
this.varA = 0;
}
myClass.prototype.consts = {
someConst : 1,
anotherConst : 1000,
}
myClass.prototype.startIt = function () {
window.setTimeout(this.brokenFunc.bind(this), this.consts.anotherConst);
}
myClass.prototype.brokenFunc = function () {
this.varA += this.consts.someConst;
window.setTimeout(this.brokenFunc.bind(this), this.consts.anotherConst);
}
// Example call
var myObj = new myClass();
myObj.startIt();
This works fine on most Android devices -- but a user running Android 2.3 has now informed me that it doesn't work and I could reproduce the error in an emulator. First, it says TypeError: Result of expression 'this.brokenFunc.bind' [undefined] is not a function for this line (within startIt):
window.setTimeout(this.brokenFunc.bind(this), this.consts.anotherConst);
Fair enough, I thought, and did the old var _this = this trick to get around the bind call. But now it says TypeError: Result of expression 'this.consts' [undefined] is not an object in this line
this.varA += this.consts.someConst;
And I'm a little lost. How can this piece of code not work? Especially since it works in most Android versions.
By default, setTimeout invokes functions with this of the global object (i.e., window, in the browser). (Side note: in strict mode, it's undefined instead.) Thus, when you don't use bind, the this brokenFunc is now window instead of the object that registered the timeout.
In order to preserve the this from startIt, you'll need to wrap your call in an anonymous function:
myClass.prototype.startIt = function () {
var that = this;
window.setTimeout(function() {
// call brokenFunc with the outer this
that.brokenFunc();
}, this.consts.anotherConst);
}
Your first error happened because the Android 2.3 browser doesn't support the EMCAScript 5 bind function. Your second error appeared because this.consts is really window.consts, which doesn't exist. Just wrap the call in an anonymous function that has that in its scope, and call the function from that.
I wrote a self invoking function in both firefox and chrome it it wouldn't invoke.
I wrote something to the effect of
(function () { alert("THE"); })();
do self invoking functions not work in current browsers?
I did include all essential tags and all other code works on the page
"Self-invoking functions" are not really a part of javascript, it's just a term that people are calling a specific pattern of code (like AJAX, etc.); these patterns should work anywhere that javascript works.
What you're calling a "self-invoking function" is just creating an anonymous function and immediately calling it (as opposed to say storing it in a var, as an object value, as a function param, etc.).
That is, the following are basically the same:
var f = function(){...}; f()
and
( function(){...} )()
So because your 'self-invoking function' is a basic part of javascript, there is no possible way it's not working unless the insides aren't working or your environment is messed up. You could copy-paste your code onto a new blank page, and it would work fine. Something else must be going wrong:
Check your errors in your dev console. Specifically, check to make sure you don't have a syntax error or that there isn't some weird thing going on with the webpage you're testing it on (e.g. if you somehow redefine alert...).
I had this issue with a self invoking function which produced this error...
Uncaught TypeError: object is not a function
The problem was caused by not having a semi colon ending the line before the opening bracket
That function works. Javascript supports functional programming, so for a browser not to run that code, even for a very old browser that would be absurd. Are you sure that statement is being reached? Try debugging javascript that occurs before that statement.
<script type="text/javascript">
(function() {
alert('Hello World!');
})();
</script>
Works in every browser I have installed on this machine.
This function definitely works. I would check your browser's console for any js errors in your page. Perhaps you could try to put a simple console.log function at the beginning of your script to see if any JavaScript is being called in the first place.
This self invoking function with return value will work in all current browsers(Safari, Chrome and Firefox) without issue. This function executes immediately, automatically and anonymously.
<script type="text/javascript">
alert((function(){
return("Hello World");
})());
</script>
I had a similar problem. I'm mentioning it below.
I couldn't run this self-invoking function on any browser
(function myfunc() {
var x = 34;
console.log(x);
})();
but whenever I added window.onload like below, it worked fine:
window.onload = (function myfunc() {
var x = 34;
console.log(x);
})();
I am new to Google Closure library, and I am trying to simulate something similar to that of Jquery's $.ajax function. Here is what I tried and what I got in response.
The trigger is from Chrome Extensions Right click
chrome.contextMenus.create({"title": "sample_closure", "onclick": samp.myProject.fun1,"contexts":['selection']});
This triggers the fun1 function which is defined as below:
samp.myProject.fun1 = function(info,tab) {
var string_url = info.selectionText;
//String_url works fine and passed to the function below.
samp.myProject.getAjaxData(string_url);
}
The getAjaxData function is as below.
goog.require("goog.net.XhrIo");
samp.myProject.getAjaxData = function(url) {
goog.net.XhrIo.send(url, function(event) {
alert(event.target.getResponseText());
});
}
But I get this error when I call the getAjaxData function.
Error in event handler for 'contextMenus': TypeError: Cannot read property 'XhrIo' of undefined
Can anyone tell me where I am going wrong.. I checked the Argument type that need to be passed for xhrio.send function and it has string type.
Solved this issue.. The path to base.js is causing this problem.
Not deleting this question because some of you may face the same issue and leaving for them. So, Check your path to base.js of closure-library for solving this issue