JS中with的通用替代方法(非正则替换)

关键词:JSwith替代方法

大家好,我是入错行的bug猫。(http://blog.csdn.net/qq_41399429,谢绝转载)



with是个好东西,但是大家都在说 不推荐使用,甚至在严格模式下直接报错!
 岂可修呀!     (σ;Д)σ死刑!


那么,大家在写JS代码时,有时候不可避免需要使用到with,使用with能极大减少代码。
例如:angular在控制层中变量都绑定到$scope对象上,但是在视图里面可以直接使用变量名,而省略了$scope


举个栗子


var obj = {
    "math":78,
    "Chinese":99,
    "English":87
}

with(obj){

	//mark1
	
    console.log( (math + Chinese + English) / 3 );		//计算并打印平均分,如果没有 with,取变量就会变为 obj.math、obj.Chinese、obj.English
	
	//mark2
	
}




注意 !(敲黑板),要开始变形了!


去掉with

mark1 的地方,假设添加var math = obj.math; var Chinese = obj.Chinese; var English = obj.English;,把对象属性转化成变量;

那么后续代码也能正常执行;
但是后续代码中,如果给变量math Chinese English重新赋值了,而并没有给obj赋值!!!!!!(所以说JS传参是引用传递还是值传递呢?)

因此,在 mark2 的地方,需要再添加obj.math = math; obj.Chinese = Chinese; obj.English = English;,变量赋值给对象属性;


再考虑到在 mark1 处申明了很多变量,为了避免与后续作用域中变量冲突,应该将 mark1 mark2 使用代码块包裹起来;



/**
 * param [object] 等价于with对象,不能为undefined
 * global [object] 函数块中this对象,默认是param
 * func [function | string] 等价于with代码块
 */
function catwith ( param, global, func ){

    if( !param ) return;
    if( typeof(global) == "function" ){
         func = global;
         global = param;
    }
    
    //动态生成 变量声明代码。  _$_$_bugcat_with 是param的形参名,为了避免命名冲突,故意写得很奇葩,越奇葩越好,冲突的概率越小
    var head = "\"use strict\";", foot = ";";
    for(var key in param){
        head = head + "var " + key + " = _$_$_bugcat_with[\"" + key + "\"];";
        foot = foot + "_$_$_bugcat_with[\"" + key + "\"] = " + key + ";"
    }

    head = head + "var $$set = function(key, value){_$_$_bugcat_with[key]=value;};"; //添加内置方法 $$set,在函数块中给param赋值
    head = head + "try { ";
    foot = "} finally {" + foot + "}";

    var funStr = "";
    if( typeof(func) === "string" ){

        //如果是字符串,直接使用
        funStr = func;

    } else {

        //将with代码块转换成字符串,只保留代码块,去掉多余的字符"function(){}"
        funStr = func.toString();
        var start = funStr.indexOf("{") + 1, last = funStr.lastIndexOf("}");
        funStr = funStr.substring(start, last);
        
    }

    //在代码块的前后追加代码声明(mark1),和变量赋值(mark2),生成新的函数。函数的this指向param!!
    var nf = new Function("_$_$_bugcat_with", head + funStr + foot).bind(global);
    
    //执行代码块并且返回结果
    return nf(param);
    
}




喜闻乐见的呆毛

var obj = {
    "math":78,
    "Chinese":99,
    "English":87
}
catwith (obj, function(){
    console.log( (math + Chinese + English) / 3 );
    console.log(this); //打印this,如果是catwith (obj, window function(){..}),那么this即为window
    math = 90;
    this.name = "bugcat";   //添加属性
    $$set("clazz", "csdn"); //添加属性
    id = "1";   // 注意!!! id 不存在于obj,被泄露到全局的window了!!!
});
say(obj);


结果

88
{math: 78, Chinese: 99, English: 87}
{math: 90, Chinese: 99, English: 87, name: "bugcat", clazz: "csdn"}





~   the end    ~
抵制垃圾信息转载,减少检索时间成本





  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值