教你写出高质量的JavaScript代码

全局变量问题

(1)全局变量的问题,在你的JavaScript应用程序和web页面上的所有代码都共享了这些全局变量。他们在同一个全局的命名空间,所以当程序在不同的位置定义相同的名字时,会导致命名冲突。

mygobal = "hi";
console.log(mygobal);  // hi
console.log(window.mygobal);//  hi
console.log(window["mygobal"]);// hi
console.log(this.mygobal);//  hi

例如:第三方的JavaScript库;广告放的脚本代码,不同类型的小组件,标记和按钮

如果在第三方脚本中定义了一个全局变量 result,你也在自己的函数中定义了一个全局变量 result,结果导致后面的变量覆盖了签名的,第三方脚本就会失效。

(2)下面的操作会不自觉的创建出全局变量,隐式全局对象属性

示例一:代码中result没有声明,是可以照样运行的,这样做的后果会导致多一个全局命名空间(不建议)

function add(a,b) {
			result = a + b;
			return result;
		}

示例二:代码中的a是本地变量,但是b确是全局变量,原因在于从右到左的赋值, 首先 b=0, 这个情况下b是未声明的,这个表达式的返回值是0,然后这个0就分配给了通过var定义的这个局部变量a,相当于这样的代码 var a = (b = 0);

function add(a,b) {
            var a = b = 0;
        }

var全局变量 和隐式创建的全局变量的不同,第二种可以通过delete操作符进行删除,第一种不可以。

var g_var = 1;
        g_noval = 2;  // 不建议
        (function () {
            g_fromfunc = 3;    //不建议
        }());
        
        delete g_val;
        delete g_novar;
        delete g_fromfunc;
        
        typeof g_var;   // "number"
        typeof g_novar; // "undefined"
        typeof g_fromfunc;  // "undefined"

访问全局变量

在浏览器中的全局对象可以通过window属性在代码的任何位置访问,如果做了声明一个局部变量window,这样会有影响访问真正的window,你可以在任何层级的函数作用域做下面操作:

var global = (function () {
            return this;
        }());

预解析

myname = "global";
function func() {
    alert(myname);
    var myname = "local";
    alert(myname);
}
func();

输出:undefined   local

如何避免在不需要的情况下创建全局属性,在函数顶部使用单var形式

数组最好使用for循环,对象使用for-in循环

for循环

for (var i = 0; i < myarray.length; i++) {
    // do something
}
for (var i = 0, max = myarray.length; i < max; i++) {
    // do something
}
function looper() {
    var i = 0, max, myarray = [];  // 单var的形式
    for (i = 0, max = myarray.length; i < max; i ++) {
        // do something
    }
}
// 改进版本
var i, myarray = [];
for (i = myarray.length; i-- ;) {
    // do something
}
var myarray = [], i = myarray.length;
while(i--){
    // do something
}

for-in循环

有个非常重要的属性 hasOwnProperty()方法, 当遍历对象属性的时候可以过滤掉从原型链上下来的属性。

var man = {
    hands: 2,
    legs: 2,
    heads: 1
};
if (typeof Object.prototype.clone === "undefined") {
    Object.prototype.clone = function () {};
}
//在man定义完之后,在原型链上增加了一个叫做clone的方法,这意味着所有对象都可以访问clone方法,需要通过hasOwnProperty()方法过滤原型属性
for (var i in man) {
    if (man.hasOwnProperty(i)) { // 过滤
        console.log(i, ":",man[i])
        
    }
}
for (var i in man) {
    if (Object.prototype.hasOwnProperty.call(man,i)) { // 过滤
        console.log(i, ":", man[i]);
    }
}

避免隐式类型转化

例如:false == 0 或者 "" == 0 返回的结果都是true

var zero = 0
if (zero === false) {
    // 不执行
    console.log(1);
}
if (zero == false) {
    // 执行
    console.log(2)
}

避免eval()

不要在代码中使用eval(),因为它是魔鬼。这个方法可以接受任意字符串,并当作JavaScript代码来处理。

var property = "name";
alert(eval("obj." + "property"));  // 不好的
alert(obj[property])
setTimeOut("myFunc()",1000); // 不好的
setTimeOut(function () {    // 好的
    myFunc();
}, 1000);
console.log(typeof un); // "undefined"
console.log(typeof deux); // "undefined"
console.log(typeof trois); // "undefined"

var jsstring = "var un = 1;console.log(deux);";
eval(jsstring);  // logs "1"

jsstring = "var deux = 2;console.log(trois);";
new Function(jsstring)();  // logs "2"

jsstring = "var trois = 3;console.log(trois);";
(function () {
    eval(jsstring);
}());  // logs "3"

console.log(typeof un); // number
console.log(typeof deux);   // "undefined"
console.log(typeof trois);  // "undefined"

使用eval()可以访问和修改它外部作用域中的变量,而function不会。

(function () {
    var local = 1;
    eval("local = 3; console.log(local)");  // 3
    console.log(local);     // 3
}());
(function () {
    var local = 1;
    Function("console.log(typeof local);")()  // undefined
})()
注释,命名规范,空格,花括号,缩进,编码规范等等







猜你喜欢

转载自blog.csdn.net/qiutiange1205/article/details/79578484
今日推荐