//Almost always RUNTIME
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@interface MyTest {}
class Sample{
@MyTest
public static void m1(){}
}
public class MyAnnotation{
public static void main(String[] args){
Class testClass = Sample.class;
//Get all methods including private, protected
//as opposed to testClass.getMethods() only returning public methods
for (Method m : testClass.getDeclaredMethods()){
if (m.isAnnotationPresent(MyTest.class)){
try{
m.invoke(null); //Call static method
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
Thursday, 24 November 2016
Effective Java Item 35. Write own annotation and reflection
Javascript: check undefined/null
If you are sure the variable has been declared (i.e var a;), simply use
If a can be undeclared, then use
if (a != null){ ... }
if (typeof a != 'undefined' && a != null){ ... }
Javascript: softbind
Excerpted from You Don't Know JS: this & Object Prototypes
I couldn't fully understand the code below.
Here is the output.
The outer this refers to the foo function while the inner this refers to the window (global) variable. It's worth noting that by the time foo.softBind(obj) completes execution, the bound() function hasn't been invoked. It's only invoked when the line fooOBJ('A2') is executed.
I couldn't fully understand the code below.
if (!Function.prototype.softBind) { Function.prototype.softBind = function(obj) { var fn = this, curried = [].slice.call( arguments, 1 ), bound = function bound() { return fn.apply( (!this || (typeof window !== "undefined" && this === window) || (typeof global !== "undefined" && this === global) ) ? obj : this, curried.concat.apply( curried, arguments ) ); }; bound.prototype = Object.create( fn.prototype ); return bound; }; } function foo() { console.log("name: " + this.name); } var obj = { name: "obj" }, obj2 = { name: "obj2" }, obj3 = { name: "obj3" }; var fooOBJ = foo.softBind( obj ); fooOBJ(); // name: obj obj2.foo = foo.softBind(obj); obj2.foo(); // name: obj2 <---- look!!! fooOBJ.call( obj3 ); // name: obj3 <---- look! setTimeout( obj2.foo, 10 ); // name: obj <---- falls back to soft-binding
- What does [].slice.call(...) do?
- Are the two 'this' referring to the same thing?
- What does bound.prototype = Object.create(fn.prototype) do?
if (!Function.prototype.softBind) { Function.prototype.softBind = function(obj) { var fn = this; console.log("Outer this = "+ fn); var curried = [].slice.call( arguments, 1 ); console.log("Outer curry = "+curried); var bound = function bound() { console.log("Inner this = " + this); console.log("Inner curry = "+curried.concat.apply( curried, arguments )); return fn.apply( (!this || (typeof window !== "undefined" && this === window) || (typeof global !== "undefined" && this === global) ) ? obj : this, curried.concat.apply( curried, arguments ) ); }; bound.prototype = Object.create( fn.prototype ); console.log("return bound"); return bound; }; } function foo(a1, a2) { console.log(a1 + ' ' +a2 + " name: " + this.name); } var obj = { name: "obj" }, obj2 = { name: "obj2" }, obj3 = { name: "obj3" }; var fooOBJ = foo.softBind( obj, 'A1'); fooOBJ('A2'); // name: obj //obj2.foo = foo.softBind(obj, 'A1'); //obj2.foo('A2'); // name: obj2 <---- look!!! //fooOBJ.call( obj3 ); // name: obj3 <---- look!
Outer this = function foo(a1, a2) { console.log(a1 + ' ' +a2 + " name: " + this.name); } Outer curry = A return bound Inner this = [object Object] Inner curry = A,A2 A A2 name: obj2
[].slice.call(arguments, 1)is semantically equal to
arguments.slice(1)except the latter is syntactically incorrect because the variable arguments is not a real array. It's an 'array-like' object.
The outer this refers to the foo function while the inner this refers to the window (global) variable. It's worth noting that by the time foo.softBind(obj) completes execution, the bound() function hasn't been invoked. It's only invoked when the line fooOBJ('A2') is executed.
bound.prototype = Object.create( fn.prototype );copies all the properties of foo to bound, essentially ensuring that after softbind the function foo doesn't lose any properties.
Wednesday, 23 November 2016
Javascript: dabble in 'new'
The code snippet below demonstates the difference between invoking a function with and without new.
Why bar2 is undefined? Because there is no return statement in foo(). What if there is?
Why bar2.a = 2 while bar2 itself is the Window object? Because this refers to the Window object and this.a essentially creates an 'a' variable in global scope (Window object).
Now what if returning something other than this?
Oh, it turns out that having a 'new' precede a function ignores the return statement all together. Although the author of stresses that 'new' in Javascript has nothing to do with the constructor concept in class-oriented languages, I, with a Java background, am still inclined to interpret it as:
function foo(a) { this.a = a; } var bar = new foo( 2 ); var bar2 = foo( 2 ); console.log( bar); // foo {a: 2} console.log( bar.a); // 2 console.log( bar2); // undefined console.log( bar2.a); // TypeError
function foo(a) { this.a = a; return this; } var bar = new foo( 2 ); var bar2 = foo( 2 ); console.log( bar); // foo {a: 2} console.log( bar.a); // 2 console.log( bar2); // Window {top: Window, location: Location, document: document, window: Window, external: Object…} console.log( bar2.a); // 2
function foo(a) { this.a = a; return 3; } var bar = new foo( 2 ); var bar2 = foo( 2 ); console.log( bar); // foo {a: 2} console.log( bar.a); // 2 console.log( bar2); // 3 console.log( bar2.a); // undefined
class foo{ var a; public foo(a){ this.a = a; } } var bar = new foo(2);
Tuesday, 22 November 2016
Javascript: 'this' and call
In this post, my assertion that
impl.apply(impl, deps) = impl.apply(null, deps);
just shows how naive I was due to the lack of understanding of 'this' mechanism.
From You Don't Know JS: this & Object Prototypes
The first parameter foo essentially makes 'this' point to the foo object.
Now replace the line with
It prints out '0' because this refers to window object now.
I am tempted to boldly make this assertion that the following two pairs of method invocation can always be used interchangeably.
Let's see when I can be proved wrong.
impl.apply(impl, deps) = impl.apply(null, deps);
just shows how naive I was due to the lack of understanding of 'this' mechanism.
From You Don't Know JS: this & Object Prototypes
function foo(num) { console.log( "foo: " + num ); // keep track of how many times `foo` is called // Note: `this` IS actually `foo` now, based on // how `foo` is called (see below) this.count++; } foo.count = 0; var i; for (i=0; i<10; i++) { if (i > 5) { // using `call(..)`, we ensure the `this` // points at the function object (`foo`) itself foo.call( foo, i ); } } // foo: 6 // foo: 7 // foo: 8 // foo: 9 // how many times was `foo` called? console.log( foo.count ); // 4
Now replace the line with
foo.call( null, i );
It prints out '0' because this refers to window object now.
I am tempted to boldly make this assertion that the following two pairs of method invocation can always be used interchangeably.
foo.call( foo, i ) = foo.bind(foo)(i) foo.call( null, i) = foo(i)
Let's see when I can be proved wrong.
Javascript: dabble in 'this'
It is probably going to take me a while to fully grasp the 'this' concept in Javascript. Today I just dabble in the topic and present my shallow understandings.
It still comes from You Dont Know Js Scope and Closure, Appendix C: Lexical this.
It looks like when invoked from setTimeout(), this refers to the window object. Then the author introduced various solutions, including self, bind(), and a new feature of ES6: arrow function. These are all cool stuff. But how to address the original problem -- that is, to get setTimeout() function to print 'awesome' as well?
The simplest solution is replace this with obj
Then I attempt to use bind().
Hey it works. I wouldn't have come up with this solution if I hadn't read the previous chapters of 'You Dont Know Js'. So once again, kudos to the author.
It still comes from You Dont Know Js Scope and Closure, Appendix C: Lexical this.
var obj = { id: "awesome", cool: function coolFn() { console.log( this.id ); } }; var id = "not awesome"; obj.cool(); // awesome setTimeout( obj.cool, 100 ); // not awesome
It looks like when invoked from setTimeout(), this refers to the window object. Then the author introduced various solutions, including self, bind(), and a new feature of ES6: arrow function. These are all cool stuff. But how to address the original problem -- that is, to get setTimeout() function to print 'awesome' as well?
The simplest solution is replace this with obj
console.log( obj.id );
Then I attempt to use bind().
cool2: function coolFn2() { console.log( this.id ); }.bind(obj)It doesn't work because obj cannot be referenced within itself, well, unless it is referenced within a function. Therefore the 2nd attempt.
cool3: function coolFn3() { (function(){ console.log(this.id); }.bind(obj))(); }
Javascript: apply
In You Dont Know JS Chapter 5: Scope Closure, there is following code snippet to illustrate the power of module pattern.
What does this line do?
It is another way of invoking a function, sort of like Java reflection. And we get to pass an array variable in the second argument to replace a list of parameters. What is the first argument for?
According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
fun.apply(thisArg, [argsArray]) = thisArg.fun(arg1, arg2....)
In this case, I also don't understand why the first parameter is 'impl'. But I have proved it can be replaced with 'null'.
The next question is why the function needs to be called in such a unconventional way. Could it be called normally?
If we put
bar.hello() executes OK, but foo.awsome() throws TypeError: bar.hello is not a function.
Then try
It does work. But obviously it's not a universal solution. Hence the use of apply().
var MyModules = (function Manager() { var modules = {}; function define(name, deps, impl) { for (var i=0; i<deps.length; i++) { deps[i] = modules[deps[i]]; } modules[name] = impl.apply(impl, deps); console.log("module "+modules[name]); } function get(name) { return modules[name]; } return { define: define, get: get }; })(); MyModules.define( "bar", [], function(){ function hello(who) { return "Let me introduce: " + who; } return { hello: hello }; } ); MyModules.define( "foo", ["bar"], function(bar){ var hungry = "hippo"; function awesome() { console.log( bar.hello( hungry ).toUpperCase() ); } return { awesome: awesome }; } ); var bar = MyModules.get( "bar" ); var foo = MyModules.get( "foo" ); console.log(bar.hello( "hippo" )); // Let me introduce: hippo foo.awesome(); // LET ME INTRODUCE: HIPPO
What does this line do?
modules[name] = impl.apply(impl, deps);
It is another way of invoking a function, sort of like Java reflection. And we get to pass an array variable in the second argument to replace a list of parameters. What is the first argument for?
According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
fun.apply(thisArg, [argsArray])
Parameters
thisArg- The value of
thisprovided for the call tofun. Note thatthismay not be the actual value seen by the method: if the method is a function in non-strict mode code,nullandundefinedwill be replaced with the global object, and primitive values will be boxed.
fun.apply(thisArg, [argsArray]) = thisArg.fun(arg1, arg2....)
In this case, I also don't understand why the first parameter is 'impl'. But I have proved it can be replaced with 'null'.
The next question is why the function needs to be called in such a unconventional way. Could it be called normally?
If we put
modules[name] = impl(deps);
bar.hello() executes OK, but foo.awsome() throws TypeError: bar.hello is not a function.
Then try
modules[name] = impl(deps[0]);
It does work. But obviously it's not a universal solution. Hence the use of apply().
Subscribe to:
Posts (Atom)