[20141129]编写高质量JS代码的68个有效方法(四)
Tips:
执行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对象的。
Tips:
直接调用eval,那么编译器无法优化JS代码。 如何间接调用eval?
(0,eval)(code)
Tips:
在全局对象上直接定义的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);
Tips:
需求:将数组元素全部转换为大写
//常规做法 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);
注意:需要注意高阶函数使用时的返回值,有些是更改原始对象,有些是返回新对象
Tips:
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);