侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

JavaScript学习笔记(1)

2024-05-09 星期四 / 0 评论 / 0 点赞 / 80 阅读 / 6238 字

参考自汤姆大叔“深入学习JavaScript系列”。http://www.cnblogs.com/TomXu/archive/2011/12/28/2286877.html 1、全局变量 全局变量

参考自汤姆大叔“深入学习JavaScript系列”。http://www.cnblogs.com/TomXu/archive/2011/12/28/2286877.html

1、全局变量

  • 全局变量就是在任何函数外面声明的或是未声明直接简单引用的。
  • 不声明的任何变量都会成为一个全局对象属性。
function sum(x,y){    result = x + y;    return result;}

此段代码中result为全局变量。要让全局变量少的法则是始终使用var声明变量。

隐式全局变量和明确定义的全局变量差异(通过delete操作符让变量未定义):

  • 通过var创建的全局变量(任何函数之外的程序中创建)是不能被删除的。
  • 无var创建的隐式全局变量(无视是否在函数中创建)是能被删除的。(在技术上,隐式全局变量并不是真正的全局变量,它们是全局对象的属性,属性是可以通过delete操作符删除的,而变量不能。
var global_var = 1;global_novar = 2;(function(){  global_fromfunc = 3;}());delete global_var;       //truedelete global_novar;     //falsedelete global_fromfunc;  //falseconsole.log(typeof global_var);       //numberconsole.log(typeof global_novar);     //undefinedconsole.log(typeof global_fromfunc);  //undefined

2、使用单var形式(使用一个var语句声明多个变量,并以逗号分隔)

  • 提供了一个单一的地方去寻找功能所需要的所有局部变量;
  • 防止变量在定义之前使用的逻辑错误;
  • 帮助记住声明的全局变量;
  • 少代码

3、for循环

// 次佳循环for(var i = 0;i < myarray.length; i++){   //代码块}

不足: 每次循环的时候数组的长度都要去获取,尤其当myarray不是数组,而是Dom操作 HTMLCollection对象的时候。

//缓存数组或集合的长度是较好的形式for(var i = 0,max = myarray.length; i < max; i++){    //代码块}

在上面的循环中,只检索了一次长度值。

4、for-in循环:用在非数组对象的遍历上,使用for-in进行循环也被称为“枚举”。

hasOwnProperty():当遍历对象属性的时候可以过滤掉从原型链上下来的属性。

var man = {  hands: 2,  legs: 2,  heads: 1};if(typeof Object.prototype.clone === 'undefined'){  Object.prototype.clone = function(){};}//for-in循环,hasOwnProperty()过滤原型属性for (var i in man){  if(man.hasOwnProperty(i)){   //过滤clone()方法    console.log(i, ':', man[i]);  }}//不过滤for (var i in man){  console.log(i, ':', man[i]);}//使用hasOwnProperty()取消Object.prototype上的方法for (var i in man){  if(Object.prototype.hasOwnProperty.call(man, i)){    console.log(i, ':', man[i]);  }}//局部变量“缓存”var i, hasOwn = Object.prototype.hasOwnProperty;for(i in man){  if(hasOwn.call(man, i)){    console.log(i, ':', man[i]);  }}

5、避免隐式类型转换

JavaScript的变量在比较的时候会隐式类型转换。这就是为什么一些诸如:false == 0 或 “” == 0 返回的结果是true。为避免引起混乱的隐含类型转换,在你比较值和表达式类型的时候始终使用===和!==操作符。

var zero = 0;if (zero === false) {   // 不执行,因为zero为0, 而不是false}// 反面示例if (zero == false) {   // 执行了...}

6、避免eval()

使用eval()也带来了安全隐患,因为被执行的代码(例如从网络来)可能已被篡改。这是个很常见的反面教材,当处理Ajax请求得到的JSON 相应的时候。

// 反面示例var property = "name";alert(eval("obj." + property));// 更好的var property = "name";alert(obj[property]);

同样重要的是要记住,给setInterval(), setTimeout()和Function()构造函数传递字符串,大部分情况下,与使用eval()是类似的,因此要避免。

// 反面示例setTimeout("myFunc()", 1000);setTimeout("myFunc(1, 2, 3)", 1000);// 更好的setTimeout(myFunc, 1000);setTimeout(function () {   myFunc(1, 2, 3);}, 1000);

使用新的Function()构造就类似于eval(),应小心接近。这可能是一个强大的构造,但往往被误用。如果你绝对必须使用eval(),你 可以考虑使用new Function()代替。有一个小的潜在好处,因为在新Function()中作代码评估是在局部函数作用域中运行,所以代码中任何被评估的通过var 定义的变量都不会自动变成全局变量。另一种方法来阻止自动全局变量是封装eval()调用到一个即时函数中。

console.log(typeof un);    // "undefined"console.log(typeof deux); // "undefined"console.log(typeof trois); // "undefined"var jsstring = "var un = 1; console.log(un);";eval(jsstring); // logs "1"jsstring = "var deux = 2; console.log(deux);";new Function(jsstring)(); // logs "2"jsstring = "var trois = 3; console.log(trois);";(function () {   eval(jsstring);}()); // logs "3"console.log(typeof un); // numberconsole.log(typeof deux); // "undefined"console.log(typeof trois); // "undefined"

eval()和Function构造不同的是eval()可以干扰作用域链,而Function()更安分守己些。不管你在哪里执行 Function(),它只看到全局作用域。所以其能很好的避免本地变量污染。在下面这个例子中,eval()可以访问和修改它外部作用域中的变量,这是 Function做不来的(注意到使用Function和new Function是相同的)。

(function () {   var local = 1;   eval("local = 3; console.log(local)"); // logs "3"   console.log(local); // logs "3"}());(function () {   var local = 1;   Function("console.log(typeof local);")(); // logs undefined}());

 

广告 广告

评论区