Why does google main page use (0, obj.func)(args) syntax? - javascript

Sometimes I stared at js provided with google.com main page and found that they tended to use (0, obj.func)(args) syntax. Here are excerpts from the script:
var _ = _ || {};
(function (_) {
var window = this;
try {
_.mb = function (a) {
return (0, window.decodeURIComponent)(a.replace(/\+/g, " "))
};
_.zg = function (a, b) {
for (var c = a.length ? a.split("&") : [], d = 0; d < c.length; d++) {
var e = c[d];
if ((0, _.Ag)(e) == b) return (c = /=(.*)$/.exec(e)) ? (0, _.mb)(c[1]) : null
}
return null
};
_.Ag = function (a) {
return (a = /^(.+?)(?:=|$)/.exec(a)) ? (0, _.mb)(a[1]) : null
};
var Cg = function (a, b) {
var c = a.indexOf("?");
return 0 > c ? null : (0, _.zg)(a.substring(c + 1), b)
};
// Note var Cg called with no 0
var oca = function (a) {
this.A = Cg(a, "mods");
this.B = Cg(a, "ver")
};
} catch (e) {}
})(_);
Why prepending 0?

This makes an indirect call.
This ensures the context, in the called function, is the global one. This might be useful in an internal scope.
Example :
var a = {
b: function(){
console.log(this);
},
c1: function(){
this.b();
},
c2: function(){
(0, this.b)();
},
c3: function(){
(this.b)();
}
}
a.c1(); // logs a
a.c2(); // logs window
a.c3(); // logs a

Related

Javascript: empty constructor name for instances of "object properties"

I want to namespace my code, so I did this:
let Namespace = {};
Namespace.Func = function (a, b) {
this.a = a;
this.b = b;
};
Namespace.Func.prototype.getSum = function () {
return this.a + this.b;
};
Then, I created an instance of Namespace.Func:
let f = new Namespace.Func(1, 2);
Now , I would expect all these lines to be true:
console.log(f.getSum() === 3);
console.log(typeof f === 'object');
console.log(f instanceof Object);
console.log(f instanceof Namespace.Func);
console.log(f.constructor === Namespace.Func);
console.log(f.constructor.name === "Namespace.Func");
But the last one is false, because f.constructor.name is "".
Why is that? Can it be fixed?
Here you have the code snippet:
let Namespace = {};
Namespace.Func = function (a, b) {
this.a = a;
this.b = b;
};
Namespace.Func.prototype.getSum = function () {
return this.a + this.b;
};
let f = new Namespace.Func(1, 2);
console.log("f.getSum() === 3", f.getSum() === 3);
console.log("typeof f === 'object'", typeof f === 'object');
console.log("f instanceof Object", f instanceof Object);
console.log("f instanceof Namespace.Func", f instanceof Namespace.Func);
console.log("f.constructor === Namespace.Func", f.constructor === Namespace.Func);
console.log("f.constructor.name === 'Namespace.Func'", f.constructor.name === 'Namespace.Func');
console.log('---');
console.log("f.constructor.name", f.constructor.name);
console.log("f.constructor.name === ''", f.constructor.name === '');
Specify function name for your constructor like below:
Namespace.Func = function TheNameOfConstructor (a, b) {
this.a = a;
this.b = b;
};
The assert will pass after that like this:
console.log(f.constructor.name === "TheNameOfConstructor");

Reseting a counter of a protected/nested variable in JavaScript

My intention is to create a safe counter and reset it by calling a function. I tried this code:
function ZeroCounter () { var c = 0 ; return function() { return ++c } };
const Counter = ZeroCounter();
But didn't work as I expected. ZeroCounter doens't reset var C. I noticed that function() return creates a new object.
var m = ZeroCounter(); var n = ZeroCounter();
m === n //return false
I tried a new code for ZeroCounter.
function ZeroCounter () { var c = 0 ; ret = function() { return ++c }; return ret };
In fact, no reasons for new results. So, What can I do to reach my intention: create a resetable nested variable? Or is it not possible in this way?
Basically, you're re-creating c each time you execute ZeroCounter. To get around that, move c outside of ZeroCounter.
var c = 0;
function ZeroCounter() {
return ++c;
}
var m = ZeroCounter();
var n = ZeroCounter();
console.log(m);
console.log(n);
If you want to contain c within ZeroCounter but still want the effect, use an Immediately Invoked Function Expression or IIFE
var ZeroCounter = (function () {
var c = 0;
return function () {
return ++c;
};
}());
var m = ZeroCounter();
var n = ZeroCounter();
console.log(m);
console.log(n);
You could use the parameter of the function and reset to a wanted value.
function counter() {
var c = 0;
return function(v) {
if (v !== undefined) c = v;
return ++c
};
}
const counterA = counter();
console.log(counterA());
console.log(counterA());
console.log(counterA());
console.log(counterA(0));
console.log(counterA());
console.log(counterA());

Get return value of first function invocation match without invoking it twice

I have an array of function references.
I need to find the return value of the first function invocation that satisfies my match condition.
How can I avoid calling the matched function twice?
var f = function(x) { if (x === 10) return "ten"; }
var g = function(y) { if (y === 20) return "twenty"; }
var result = [f, g].find(m => m(10))
if (result) return result(10)
// this returns "ten"
Still not sure I fully understand you question. It seems to me that you want to iterate through an array of functions and return the result if the function called with the condition is truthy.
let fncaller = (fns, condition) => {
var result
for (var fn of fns) {
result = fn(condition)
if (result) { return result }
}
}
Can you use global variables?
var f = function(x) {
return x % 2 == 0
}
var g = function(y) {
return x % 2 == 1
}
var result = [f, g].find(function(m) {
window.blah = m(10);
return window.blah;
})
console.log(window.blah);
Or #DaveNewton's method. Not sure which is faster:
var f = function(x) {
if (x === 10) return "ten";
}
var g = function(y) {
if (y === 20) return "twenty";
}
var funcs = [f, g];
function checkIt(value) {
for (var i = 0, numFuncs = funcs.length; i < numFuncs; ++i) {
var v = funcs[i](value);
if (v) return v;
}
}
console.log(checkIt(20));
You could store in a variable as you go. It's better than using a global.
var f = function(x) { if (x === 10) return "ten"; };
var g = function(y) { if (y === 20) return "twenty"; };
function findValue(funcs, val) {
var result;
funcs.find(m => result = m(val));
return result;
}
console.log(findValue([f, g], 10));

Javascript module pattern introduced in TGP deentityify method - why is this pattern necessary?

Crockford introduces a pattern in the deentityify method to create a module. He claims:
The module pattern takes advantage of function scope and close to create relationships that are binding and private. In this example, only the deentityify method has access to the entity data structure.
Distilling to remove his custom functions, I think the code boils down to...
String.prototype.deentityify = function() {
var entity = {
quot: '"',
lt: '<',
gt: '>'
};
return function() {
return this.replace(/&([^&;]+);/g, function(a, b) {
var r = entity[b];
return typeof r === 'string' ? r : a;
}); //close function(a,b)
}; //close the returned function
} /* close top level */ (); /* but evaluate it so deentitify becomes the returned fcn(!)
Problem is I don't see why this additional layer of indirection is necessary. Is this code not equivalent?
String.prototype.deentityify = function() {
var entity = {
quot: '"',
lt: '<',
gt: '>'
};
// return function() {
return this.replace(/&([^&;]+);/g, function(a, b) {
var r = entity[b];
return typeof r === 'string' ? r : a;
}); //close function(a,b)
// }; //close the returned function
} /* close top level, don't evaluate
The basic reason for this pattern is to avoid re-evaluating entity on every call. Replace entity with something that is expensive to construct and doesn't change from call to call:
String.prototype.deentityify = function() {
// expensiveFunctionCall is called *once* - when the function is defined.
var entity = expensiveFunctionCall();
return function() {
return this.replace(/&([^&;]+);/g, function(a, b) {
var r = entity[b];
return typeof r === 'string' ? r : a;
}); //close function(a,b)
}; //close the returned function
}();
vs
String.prototype.deentityify = function() {
// expensiveFunctionCall is called
// *every time* "anyString".deentityify() is called.
var entity = expensiveFunctionCall();
return this.replace(/&([^&;]+);/g, function(a, b) {
var r = entity[b];
return typeof r === 'string' ? r : a;
}); //close function(a,b)
};

Create an object based on 2 others [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How can I merge properties of two JavaScript objects dynamically?
I have two objects a and b defined like this:
a = {
a: 1,
af: function() { console.log(this.a) },
};
b = {
b: 2,
bf: function() { console.log(this.b) },
};
What I want now is to create another object which will get the properties of a and b, like this:
c = {
a: 1,
af: function() { console.log(this.a) },
b: 2,
bf: function() { console.log(this.b) },
}
Note that a and b need to stay the same.
Any idea of how to do this ?
You could do a for in loop for both a and b, and copy all hasOwn properties to a new object.
var c = {};
for (var p in a)
if(a.hasOwnProperty(p))
c[p] = a[p];
for (var p in b)
if(b.hasOwnProperty(p))
c[p] = b[p];
DEMO
Or, if you happen to be using jQuery, you could do:
var c = $.extend({}, a, b);
var desc = Object.getOwnPropertyDescriptor,
props = Object.getOwnPropertyNames,
define = Object.defineProperty;
function extend( target ) {
return {
with: function( source ) {
props( source ).forEach(function( key ) {
define( target, key, desc( source, key ) );
});
}
};
}
So now we can go like
var c = Object.create( null );
extend( c ).with( a );
extend( c ).with( b );
Disclaimer: the provided codes assume we are in a ES5 or ES5 shimed environment !
var i, c={};
for (i in a) { if (a.hasOwnProperty(i)) { c[i] = a[i]; } }
for (i in b) { if (b.hasOwnProperty(i)) { c[i] = b[i]; } }
You can abstract this functionality into your own "extend" function similar to the one provided by jQuery:
function extend() {
var i, j, x, o=(arguments[0] || {});
for (i=1; i<arguments.length; i++) {
x = arguments[i];
for (j in x) { if (x.hasOwnProperty(j)) { o[j] = x[j]; } }
}
return o;
}
var c = extend({}, a, b);

Categories

Resources