• 编写高质量JS代码的68个有效方法(四)


    [20141129]编写高质量JS代码的68个有效方法(四)

    No.16、避免使用eval创建局部变量

    Tips:

    1. 避免使用eval函数创建的变量污染调用者作用域。
    2. 如果eval函数代码可能创建全局变量,将此调用封装到嵌套的函数中已防止作用域污染。

    执行eval时,eval中的变量才会被加到作用域中(函数作用域)

    function fun1(){
        eval('var y = 1;');
        console.log('fun1->y:'+y); // 'fun->y:1'
    }
    fun1();
    console.log('global->y:'+y); //throw Error
    

    不要直接将不可控参数交给eval执行,可能会改变作用域对象。

    //Bad code
    var g = 'global';
    function fun2(code){
        eval(code);
    }
    fun2('var g="local"');
    console.log(g) //'local'
    
    //Right code
    var g = 'global';
    function fun2(code){
        (function(){
            eval(code);
        })();
    }
    fun2('var g="local"');
    console.log(g) //'global',嵌套作用域
    

    以上Right Code,如果执行不带var的变量申明,那么也是会影响全局的g对象的。

    No.17、间接调用eval函数优于直接调用

    Tips:

    1. 将eval函数同一个毫无意义的字面量包裹在序列表达式中以达到强制使用间接调用eval函数的目的
    2. 尽可能间接调用eval函数,而不要直接调用eval函数

    直接调用eval,那么编译器无法优化JS代码。 如何间接调用eval?

    (0,eval)(code) 
    

    No.18、理解函数的调用、方法调用及构造函数调用之间的不同

    Tips:

    1. 方法调用将被查找方法属性的对象作用调用接收者
    2. 函数调用将全局对象作为其接受者。一般很少使用该函数调用语法来调用方法
    3. 构造函数需要通过new运算符调用,并产生一个新的对象作为其接收者

    在全局对象上直接定义的function被称为函数,调用则是函数调用

    var fun1 = function(p){
        console.log(p);
    };
    
    function fun2(p){
        console.log(p);
    }
    //函数调用
    fun1('p1');
    fun2('p2');
    

    如果对象的属性是函数,那么称之为方法,使用模式则是方法调用

    var obj = {
        name: 'Hello ',
        fun1: function(name){
            console.log(this.name + name);
        }
    };
    //方法调用
    obj.fun1('Jay');
    

    注意:fun1中通过this来访问obj的name属性

    构造函数调用将一个全新的对象作为this变量的值

    fucntion User(name, age){
        this.Name = name;
        this.Age = age;
    }
    //此时,user是一个全新的对象
    var user = new User('Jay', 23);
    

    No.19、熟练掌握高阶函数

    Tips:

    1. 高阶函数是那些将函数作为参数或返回值的函数
    2. 熟练掌握现有库的高阶函数
    3. 学会发现可以被高阶函数所取代的常见编码模式

    需求:将数组元素全部转换为大写

    //常规做法
    var arr = ['abc', 'test', '123'];
    for(var i =0, len = arr.length; i < len; i++){
        arr[i] = arr[i].toUpperCase();
    }
    console.log(arr);
    
    //高阶函数
    var arr = ['abc', 'test', '123'];
    arr = arr.map(function(item){
        return item.toUpperCase();
    });
    console.log(arr);
    

    注意:需要注意高阶函数使用时的返回值,有些是更改原始对象,有些是返回新对象

    No.20、使用call方法自定义接收者来调用方法

    Tips:

    1. 使用call方法自定义接收者(个人理解为作用域)来调用函数
    2. 使用call方法可以调用在给定对象中不存在的方法
    3. 使用call方法定义高阶函数允许使用者给回调函数指定接收者

    function fun1(){
        this.name = 'Test';
    }
    var obj = {
        name: 'Jay'
    };
    console.log(obj.name);
    fun1.call(obj);
    console.log(obj.name);
    

    call函数的调用方式:

    f.call(obj, p1, p2, p3);
    
  • 相关阅读:
    [Android Samples视频系列之ApiDemos] AppActivityReceive Result
    【Android每日一讲】2012.11.19 我同意条款 CheckBox的isChecked属性
    Android中得到SharedPreference全面总结
    【Android每日一讲】2012.11.27 向左或向右 RadioGroup组与onCheckedChanged事件
    [Android Samples视频系列之ApiDemos] AppActivityReorder Activities
    Lc.exe已退出,代码为1
    反射和委托的两个例子
    数据库日志太大如何快速删除
    Spring.NET环境搭建之基础篇(收藏、学习)
    软件工程之编程规范
  • 原文地址:https://www.cnblogs.com/humin/p/4130960.html
Copyright © 2020-2023  润新知