Skip to content

Instantly share code, notes, and snippets.

@zhiyelee
Last active December 19, 2015 12:19
Show Gist options
  • Save zhiyelee/5954445 to your computer and use it in GitHub Desktop.
Save zhiyelee/5954445 to your computer and use it in GitHub Desktop.
node js demo
node_modules

Arguments Object

When control enters an execution context for function code, an arguments object is created and initialised as follows:

  • The value of the internal [[Prototype]] property of the arguments object is the original Object prototype object, the one that is the initial value of Object.prototype (see 15.2.3.1).
  • A property is created with name callee and property attributes { DontEnum }. The initial value of this property is the Function object being executed. This allows anonymous functions to be recursive.
  • A property is created with name length and property attributes { DontEnum }. The initial value of this property is the number of actual parameter values supplied by the caller.
  • For each non-negative integer, arg, less than the value of the length property, a property is created with name ToString(arg) and property attributes { DontEnum }. The initial value of this property is the value of the corresponding actual parameter supplied by the caller. The first actual parameter value corresponds to arg = 0, the second to arg = 1, and so on. In the case when arg is less than the number of formal parameters for the Function object, this property shares its value with the corresponding property of the activation object. This means that changing this property changes the corresponding property of the activation object and vice versa.

Reference

/**
`bind` function,return a wrapped function with specified context
**/
var bind = function (context, fn) {
var args = arguments.length > 2 ? Array.prototype.slice.call(arguments, 2) : [];
return function() {
fn.apply(context || fn, args.concat(Array.prototype.slice.call(arguments)));
};
};
var obj = {
title: 'object title'
};
var fooFn = function (title) {
console.log(this.title + ' and ' + title);
console.log(arguments);
};
// WARN: name is funtion`s nature property,anonymous function's property can not be add by like `fooFn.name`
// The WARN has no business of the topic here,just because I used took the name propety instead of title for demo, then I encountered the WARN
fooFn.title = 'foo function title';
var bindedFooFn = bind(obj, fooFn, 'append title');
bindedFooFn('arguments title');
bindedFooFn = bind('', fooFn, 'append title');
bindedFooFn('arguments title');
// Below is YUI`s bind
/**
* Returns a function that will execute the supplied function in the
* supplied object's context, optionally adding any additional
* supplied parameters to the beginning of the arguments collection the
* supplied to the function.
*
* @method bind
* @param {Function|String} f the function to bind, or a function name
* to execute on the context object.
* @param {object} c the execution context.
* @param {any} args* 0..n arguments to include before the arguments the
* function is executed with.
* @return {function} the wrapped function.
*/
//Y.bind = function(f, c) {
// var xargs = arguments.length > 2 ?
// Y.Array(arguments, 2, true) : null;
// return function() {
// var fn = L.isString(f) ? c[f] : f,
// args = (xargs) ?
// xargs.concat(Y.Array(arguments, 0, true)) : arguments;
// return fn.apply(c || fn, args);
// };
//};
// 命令管理器
var cmdManager = {
hash: {},
/**
* 注册cmd
* @param name {String} 子命令名
* @param description {Object}
* cmdArg {String} 命令参数示例
* cmdDes {String} 命令描述
* @param fn {Function} 命令对应的函数
**/
register: function(name, description, fn) {
var item = {};
item['des'] = description;
item['fn'] = fn;
this.hash[name] = item;
},
// 检查命令是否存在
isCMDExist: function(name) {
return !!this.hash[name];
},
// get Usage info
getUsage: function(name) {
var res = '',
cmdDemo = '',
cmdArg,
_this = this,
hash = _this.hash,
des;
res = 'Usage:\n';
if (_this.hash[name]) {
res += _this._getCmdUsage(name);
} else {
Object.keys(hash).forEach(function (name) {
res += _this._getCmdUsage(name, hash[name]['des']);
});
}
return res;
},
_getCmdUsage: function(name, des) {
var res = '';
cmdArg = des['cmdArg'] ? ' "' + des['cmdArg'] + '"' : '';
cmdDemo = des['appName'] + ' ' + name + cmdArg;
res += ' ' + cmdDemo + ':\t' + des['cmdDes'] + '\n';
return res;
},
// run sub cmd
run: function(name) {
var fn = this.hash[name]['fn'];
if (fn) {
fn.apply(this, Array.prototype.slice.call(arguments, 1));
}
}
};
module.exports = cmdManager;
// uasage Demo
// rm below comment to run
//cmdManager.register('page', { appName: 'mtblog', cmdArg: 'page title', cmdDes: 'create new page with title `page_title`' } , function () {
// console.log('fn new page');
//});
//
//console.log(cmdManager.getUsage());
/**
* currying javascript
* @source http://bjouhier.wordpress.com/2011/04/04/currying-the-callback-or-the-essence-of-futures/
**/
function future(fn, args, i) {
var cb,
err,
result,
done;
// 未指定回调函数时默认执行的回调函数
// 此处回调函数设定的功能是记录
// done 回调是否已执行
// err 执行currying函数返回的err(nodejs的结构)
// result 执行currying函数返回的result(nodejs的结构)
cb = function(e, r) { done = true; err = e; result = r; }
args = Array.prototype.slice.call(args);
// 指定回调函数的位置
args[i] = function(e, r) { cb(e, r); };
// 执行要currying的function
fn.apply(this, args);
return function(_) {
if (done) {
_(err, result);
} else {
cb = _;
}
}
}
// demo
var fs = require('fs');
var sleep = function(s) {
var e = new Date().getTime() + (s * 1000);
while (new Date().getTime() <= e) {
;
}
}
function readFile(path, encoding, cb) {
if (!cb) return future(readFile, arguments, 2);
// readFile's body
fs.readFile(path, encoding, cb);
}
var tt = readFile('./eval.js', 'utf8');
sleep(2);
tt(function(err, data) {
if (err) {
console.log(err);
} else {
console.log(data.split('\n').length);
}
});
/**
eval will excute that code in the scope within
which `eval()` is called
**/
var a = 1;
(function () {
eval('var a = 3;');
console.log(a);
})();
console.log(a);
/**
fool js to treat an object as array
*/
var obj;
obj = {
length: 0,
add: function (name) {
Array.prototype.push.call(this, name);
}
};
obj.add('first');
obj.add('second');
console.log(obj[0]); // first
console.log(obj[1]); // second
console.log(obj.length); // 2
console.log(obj);
{
"name": "jsdemo",
"version": "0.0.1",
"description": "my jsdemo repo",
"main": "bind.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "[email protected]:5954445.git"
},
"keywords": [
"ecma",
"javascript"
],
"author": "zhiyelee",
"license": "BSD",
"gitHead": "ff4d7afdb1a993dc45eed2b3e9ee1ab59c798d22",
"dependencies": {
"grunt-contrib-jshint": "*",
"grunt-contrib-watch": "*"
},
"bugs": {
"url": "https://gist.github.com/5954445"
}
}
// this value in function code
/* jshint undef: false, unused: false */
a = 'global a';
var b = 'global b';
c = 'global c';
function outer() {
var a = 'outer a';
var b = 'outer b';
this.c = 'outer c';
console.log('outer: this.a', this.a);
console.log('outer: this.b', this.b);
console.log('outer: this === global', this === global);
console.log('outer: this.c', this.c);
function inner() {
var a = 'inner a';
console.log('inner: this.a', this.a);
console.log('inner: this.b', this.b);
console.log('inner: this === global', this === global);
console.log('inner: this.c', this.c);
}
inner();
}
outer();
console.log('=========== obj.outer =======');
var obj = {};
obj.outer = outer;
obj.outer();
/**
conclusion:
* `this` is determined when the control enter the exec context
* in gloabl context: `var a = '10'` is not equal to `a = '10'`
*/
/** oop::augment demo **/
var YUI = require('yui').YUI;
// get the raw version js, not min version
YUI.GlobalConfig = { filter: 'RAW' };
YUI().use('oop', function(Y) {
var a = {};
var _supplier_ = function () {
this.type = '_supplier_ type';
};
_supplier_.prototype = {
name: '_supplier_',
get: function () {
return this.name;
},
set: function () {
return this.type = '_supplier_ set mothod';
},
getType: function () {
return '_supplier_ getType';
}
};
var Fa = function () {
this.type = '_Fa type';
this.getType = function () {
return this.type;
};
};
Y.augment(a, _supplier_);
Y.log(a, 'a');
Y.log(a.hasOwnProperty('get'), "a.hasOwnProperty('get')");
Y.augment(Fa, _supplier_);
Y.log(Fa.prototype.get, "Fa.prototype.get");
var faInstance = new Fa();
Y.log(faInstance, 'faInstance');
// has no `get` property,which is on the __proto__
Y.log(faInstance.hasOwnProperty('get'), "faInstance.hasOwnProperty('get')");
console.log(faInstance.get());
Y.log(faInstance, 'faInstance');
// after called `get`, has `get` property
Y.log(faInstance.hasOwnProperty('get'), "faInstance.hasOwnProperty('get')");
//Y.log(faInstance.__proto__);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment