昨天百度新闻的同事让我帮忙排查一下线上问题,最终问题定位到这样一段代码:
if (window.varname === undefined) {
...
}
左侧是Chrome,右侧是Firefox
所以不要写这样的代码
if (window.xxxxxx === undefined) {...}
要写成
if (typeof window.xxxxx === "undefined" ) {....}
昨天百度新闻的同事让我帮忙排查一下线上问题,最终问题定位到这样一段代码:
if (window.varname === undefined) {
...
}
左侧是Chrome,右侧是Firefox
所以不要写这样的代码
if (window.xxxxxx === undefined) {...}
要写成
if (typeof window.xxxxx === "undefined" ) {....}
http://nodejs.org/ 上已经有多个版本的node.js for windows 的单个可执行文件.体积都很大.
有个问题至今未解决就是还没有好的npm for windows.
在npm for windows出来之前我们可以用下面的方法解决:
思路类似rubygems
按下面目录结构组织node.exe.
将bin目录加到%path%中
将各种module放到node_modules目录下,如果没有描述文件package.json,还需要手工建立
这样就可以直接在node中require(module_name)了
一般从github上下载下来的zip直接解压到node_modules下,把目录名改为模块名就ok了
更新 21:50 2011-11-14
npm已经可以顺利在windows安装了.参见官方文档
/***********************************************/ /** Embedder's Guide */ /** http://code.google.com/apis/v8/embed.html **/ /***********************************************/ /** * Constant **/ v8::True(); v8::False(); v8::Null(); v8::Undefined(); /** * Some classes **/ v8::Boolean v8::Array v8::Arguments v8::Date v8::Function v8::Int32 v8::Integer v8::Number v8::Object v8::Regexp v8::Primitive v8::Script v8::String v8::Uint32 v8::TryCatch v8::V8 /** * Function signature **/ static v8::Handle<v8::Value> FUNCTION(const v8::Arguments& args); /** * Set simple property **/ process->Set(String::NewSymbol("platform"), String::New(PLATFORM)); /** * Return object **/ Handle<Object> NewObj(int x) { HandleScope handle_scope; Handle<Object> obj = Object::New(); obj->Set(String::NewSymbol("name"), Integer::New(x)); return handle_scope.Close(obj);} /** * Return array **/ Handle<Array> NewPointArray(int x, int y, int z) { // We will be creating temporary handles so we use a handle scope. HandleScope handle_scope; // Create a new empty array. Handle<Array> array = Array::New(3); //if can not determine the length of the array just left first parameter empty Handle<Array> array = Array::New(); // Return an empty result if there was an error creating the array. if (array.IsEmpty()) return Handle<Array>(); // Fill out the values array->Set(0, Integer::New(x)); array->Set(1, Integer::New(y)); array->Set(2, Integer::New(z)); // Return the value through Close. return array; //ERROR // The Close method copies the value of its argument into the enclosing scope // return handle_scope.Close(array); } /** * Accessor * accessor callbacks are invoked when a specific object property is accessed by a script **/ Handle<ObjectTemplate> global_templ = ObjectTemplate::New(); global_templ->SetAccessor(String::New("x"), XGetter, XSetter); global_templ->SetAccessor(String::New("y"), YGetter, YSetter); Handle<Value> XGetter(Local<String> property, const AccessorInfo& info) { return Integer::New(x); } void XSetter(Local<String> property, Local<Value> value, const AccessorInfo& info) { x = value->Int32Value(); } /** * Interceptor * interceptor callbacks are invoked when any object property is accessed by a script * named property interceptors - called when accessing properties with string names. * ndexed property interceptors - called when accessing indexed properties. **/ Local<ObjectTemplate> envTemplate = ObjectTemplate::New(); envTemplate->SetNamedPropertyHandler(EnvGetter, EnvSetter, EnvQuery, EnvDeleter, EnvEnumerator, Undefined()); Local<Object> env = envTemplate->NewInstance();process->Set(String::NewSymbol("env"), env); //Getter static Handle<Value> EnvGetter(Local<String> property, const AccessorInfo& info) { String::Utf8Value key(property); const char* val = getenv(*key); if (val) { HandleScope scope; return scope.Close(String::New(val)); } return Undefined(); } //Setter static Handle<Value> EnvSetter(Local<String> property, Local<Value> value, const AccessorInfo& info) { String::Utf8Value key(property); String::Utf8Value val(value); #ifdef __POSIX__ setenv(*key, *val, 1); #else __WIN32__ NO_IMPL_MSG(setenv) return value; } //Query static Handle<Integer> EnvQuery(Local<String> property, const AccessorInfo& info) { String::Utf8Value key(property); if (getenv(*key)) { HandleScope scope; return scope.Close(Integer::New(None)); } return Handle<Integer>(); } //Deleter static Handle<Boolean> EnvDeleter(Local<String> property, const AccessorInfo& info) { String::Utf8Value key(property); if (getenv(*key)) { #ifdef __POSIX__ unsetenv(*key); #else NO_IMPL_MSG(unsetenv) #endif return True(); } return False(); } //Enumerator static Handle<Array> EnvEnumerator(const AccessorInfo& info) { HandleScope scope; int size = 0; while (environ[size]) size++; Local<Array> env = Array::New(size); for (int i = 0; i < size; ++i) { const char* var = environ[i]; const char* s = strchr(var, '='); const int length = s ? s - var : strlen(var); env->Set(i, String::New(var, length)); } return scope.Close(env); } /** * Create function object and set it's properties **/ /** * Exception **/ TryCatch trycatch; Handle v = script->Run(); if (v.IsEmpty()) { Handle<value> exception = trycatch.Exception(); String::AsciiValue exception_str(exception); printf("Exception: %s\n", *exception_str); // ... } if (args.Length() < 3 || !args[0]->IsString() || !args[1]->IsInt32() || !args[2]->IsInt32()) { return ThrowException( Exception::TypeError(String::New("Bad argument"))); } /** * prototype **/ Handle<FunctionTemplate> biketemplate = FunctionTemplate::New(); biketemplate.PrototypeTemplate().Set( String::New("wheels"), FunctionTemplate::New(MyWheelsMethodCallback)) /** * Inheritance **/ void Inherit(Handle<FunctionTemplate> parent);biketmplate.Inherit(transportTemplate); /** * Parameter conversion **/ //int64 int n = args[0]->IntegerValue(); return scope.Close(Number::New(n)); //int32 int n = args[0]->Int32Value(); //double double d = args[0]->NumberValue(); //uint32 unsigned int ui = args[0]->Uint32Value(); //const char* v8::String:Utf8Value str(args[0]); const char* cstr = *str ? *str : NULL;
天在join(“”)一个Array的时候遇到一个问题:
当Array中还有Array的时候,嵌套的Array仍然会用逗号连接,而不是指定的空字符。比如
[1,[2,3],4].join("")
的结果是12,34
这不是我想要的。我希望得到1234
首先想到的解决办法就是递归遍历数组,如果元素是数组则对其调用join(“”)。
然后转念一想,递归调用的过程就是Array.prototype.join
本身啊。我只需改写Array.prototype.toString
就OK了
这是第一个版本:其问题是,如果忘记调用restore或连续调用两次Bakup就完蛋了。
var Bakup = (function(G) { var old = null; return function(who, name, to) { old = who.prototype[name]; who.prototype[name] = to; arguments.callee.restore = function() { who.prototype[name] = old; }; }; })(); var tag = ["<", "a ", ["href", "=\"", "http://localhost", "\""], ">"]; Bakup(Array, "toString", function() { return this.join(""); }); print(tag); Bakup.restore(); print(tag); Bakup(Array, "toString", function() { return this.join("-"); }); print(tag); Bakup.restore(); print(tag);
这是第二个版本:
function Bakup(who, name, to, callback) { var old = who.prototype[name]; who.prototype[name] = to; callback(); who.prototype[name] = old } var tag = ["<", "a ", ["href", "=\"", "http://localhost", "\""], ">"]; Bakup(Array, "toString", function() { return this.join(""); }, function() { print(tag); }); print(tag); Bakup(Array, "toString", function() { return this.join("-"); }, function() { print(tag); }); print(tag);
你知道typeof /a/
返回什么么?
Continue reading “JavaScript中RegExp对象的类型”
获取ActionScript 类信息的另类方法:
前一阵写了个提取 ActionScript 类中符号信息的脚本。算是可用。
用于混淆效果还行。
今天突然想到,在ActionScript中可以用
public function describeType(value:*):XML
flash.util.describeType(KlassName)
获得类的详细信息:
(对于类的每个方法)名称、参数的数量、返回类型和参数类型
这样,就可以写一个类,将其他类的信息都打印出来。
但是,ActionScript工程中无法操作本地文件,只能trace到调试窗口。
以前有篇文章是写给Delphi程序增加对Pax JavaScript的支持
今天研究了一下给Java程序增加对 Ruby 的支持
目前可以通过 Apache的 BSF(Bean Script Framework)
和Sun的 Java Scripting(javax.script)
Continue reading “Java程序中引入JRuby”
初学php是在大三。在看了STL,Ruby,JavaScript之后,再看php和当初完全是两种感觉了。
Array, Hash是动态语言中核心的数据结构。一旦你用过他们,你就会试图在此后接触的语言中寻找他们的身影或替代品。
以前写过一篇关于成员指针的博文,其中提到了MFC是如何使用成员指针的…
Continue reading “C++成员指针”
曾有人问了我个问题:如果在构造函数中抛出异常会怎么样?
现在可以回答了。
构造函数中抛出异常的主要问题是:当有多个资源分配时,如果出现异常,如何释放已经成功分配的资源。
下面是TCPL中推荐的一种方法:基本思想是将资源封装在对象中,然后将该对象以成员变量的形式聚合入你的类中。这个封装类在其析构函数中释放资源。这样,当你的类的构造函数中出现异常后,编译器会调用封装类的对象的析构函数,释放资源。