以下代码要用到之前博客中的代码,在执行时请将其中的代码引入,否则报错。
console.log('*************调用(方法调用模式、函数调用模式、构造子调用模式和Apply调用模式)');
console.log('第一种模式:方法调用模式');
//当一个函数被保存为对象的一个属性时,我们称它为一个方法,
//如果调用表达式包含一个提取属性的动作(即包含一个 . 点表达式或[subscript]下标表达式),
//那么它就是被当做一个方法来调用 。当一个方法被调用时,this被绑定到该对象。
myObject = {
value : 0,
increment : function(inc){
this.value += typeof inc === 'number' ? inc : 1;
}
};
myObject.increment();
console.log(myObject.value);
myObject.increment(5);
console.log(myObject.value);
console.log('第二种模式:函数调用模式');
//当一个函数并非一个对象的属性时,那么它就是被当做一个函数来调用。
//在内部函数被调用的时,this应该仍然绑定到外部函数的this变量。
//解决办法是在外部函数定义一个变量并给它赋值为this,那么内部函数就可以通过那个变量访问到this。
//按照约定,把那个变量命名为that。
myObject.double = function(){
var that = this; //解决方案
var helper = function(){
console.log("为赋值给that变量前:",this);
console.log("为赋值给that变量后:",that);
};
helper(); //以函数的形式调用 helper
};
// 以方法的形式调用
myObject.double();
console.log('第三种模式:构造器调用模式');
var Quo = function(string){
console.log(this);
this.status = string;
};
Quo.prototype.get_status = function(){
return this.status;
};
//在使用new时,this绑定具体实例
var myQuo = new Quo('confused');
console.log(myQuo.get_status());
//不使用new时,this绑定window
var myQuo2 = Quo('con');
console.log(myQuo2 && myQuo2.status);
console.log(window.status);
console.log('第四种模式:Apply调用模式');
var statuObject = {
status : 'A-OK'
};
console.log(Quo.prototype.get_status.apply(statuObject));
console.log('*************异常');
var add = function(a,b){
if(typeof a !== 'number' || typeof b !== 'number'){
throw{
name : 'typeError',
message : 'add need number'
};
}
return a+b;
};
(function(){
try{
console.log(add('d',2));
}catch(e){
document.write(e.name);
console.log(e.name+':'+e.message);
}
})();
console.log('*************扩充类型的功能');
Function.prototype.method = function(name,func){
//基本类型的原型是公用结构,所以在类库混用时务必小心。在确定没有该方法时才添加它。
if(!this.prototype[name]){
this.prototype[name] = func;
}
return this;
};
Number.method('integer',function(){
return Math[this < 0 ? 'ceil' : 'floor'](this);
});
console.log((-10/3).integer());
//通过method方法构造string转换成int函数
String.method('toInteger',function(){
var newStr = '';
var str = this || '';
for(var i=0;i<str.length;i++){
if(str.charCodeAt(i) < 58){
newStr += str.charAt(i);
}
}
return parseInt(newStr) || '';
});
console.log('2222dd33'.toInteger());
console.log("*************闭包(看页面的渐变效果)");
var fade = function(node){
var level = 1;
var step = function(){
var hex = level.toString(16);
node.style.background = '#' + hex + hex + hex + hex + hex + hex;
if(level < 15){
level++;
setTimeout(step,40);
}else{
// console.log("结束");
}
};
setTimeout(step,40);
};
fade(document.body);
// 构造一个函数,用错误的方式给一个数组中的节点设置时间处理程序。
//当点击一个节点时,按照预期,应该弹出一个对话框显示节点的序号,
//但它总是会显示节点的数目。
/*
var add_the_handlers = function(nodes){
var i;
for(i = 0;i<nodes.length;i++){
nodes[i].onclick = function(e){
alert(i);
};
}
};
*/
//改良后的例子
var add_the_handlers = function(nodes){
var i;
var helper = function(i){
return function(e){
alert(i);
};
};
for(i = 0;i<nodes.length;i++){
nodes[i].onclick = helper(i);
}
};
//(这个我也不是太清楚是怎么回事,有懂的大牛们希望指点)
console.log("*************模块");
//模块模式的一般形式是:一个定义了私有变量和函数的函数;
//利用闭包创建可以访问的私有变量和函数的特权函数;
//最后返回这个特权函,或者把它们保存到一个可以访问的地方。
String.method('deentityify',function(){
var entity = {
quot : '"',
lt : '<',
gt : '>'
};
return function(){
return this.replace(/&([^&]+);/g,function(a,b,c){
//a 表示/&([^&;]+);/g匹配的结果,b表示([^&;]+)匹配的结果,c表示的字符串
console.log(a,b,c);
var r = entity[b];
return typeof r === 'string' ? r : a;
});
};
}());
console.log('<">'.deentityify());
var serial_maker = function(){
var prefix = '';
var seq = 0;
return {
set_prefix : function(p){
prefix = String(p);
},
set_seq : function(s){
seq = s || seq;
},
getsym : function(){
var result = prefix +seq;
seq ++;
return result;
}
};
};
var seqer = serial_maker();
seqer.set_prefix('T');
seqer.set_seq(1024);
console.log(seqer.getsym());
seqer.set_prefix('D');
seqer.set_seq();
console.log(seqer.getsym());
//seqer.getsym = function(){
// return prefix;
//};
//console.log(seqer.getsym()); //Uncaught ReferenceError: prefix is not defined
console.log("*************级联");
//在没有返回值的方法中加入返回this,就可以启动级联。在级联中,我们可以在单独一条语句中一次调用一个对象的很多方法。
var user_maker = function(){
var user = {
name : "truth",
sex : "male",
age : 24
};
return {
set_name : function(n){
user.name = n;
return this;
},
set_sex : function(s){
user.sex = s;
return this;
},
set_age : function(a){
user.age = a;
return this;
},
add_user_info : function(key,value){
user[key] = value || '';
return this;
},
get :function(){
return user;
}
};
};
var u = user_maker();
console.log(u.set_name('lee').add_user_info('weight','130kg').get());
console.log("*************记忆");
//函数可以将先前操作的寄过记录在某个对象里,从而避免无谓的重复运算。这种优化被称为记忆。
//下面的例子就是将算好的值存储在memo数组里减少不必要的重复计算,进而优化。
//斐波那契数列算法
var memoizer = function(memo,formula){
var recur = function(n){
var result = memo[n];
if(typeof result !== 'number'){
result = formula(recur,n);
memo[n] = result;
}else{
console.log(memo[n]);
}
return result;
};
return recur;
};
var fibonacci = memoizer([0,1],function(recur,n){
return recur(n-1)+recur(n-2);
});
console.log(fibonacci(10));