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

十度 javaScript 2016年01月06日 收藏

[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);