<JavaScript语言精粹>-读书笔记(一)

  1. 用object.hasOwnProperty(variable)来确定这个属性名是否为该对象成员,还是来自于原型链。

    for(my in obj){
        if(obj.hasOwnProperty(my)){
        ...
       }
    }

    思考:--用来遍历判断是否有该属性成员,当为一个string var="abcdef"一样的一个字符串时,通过JS代码判断其中是否含有我们需要的某一个字符,比如a,如果有就将其remove

  2. 一个属性存取表达式用于指定一个对象或数组的属性或元素。
  3. 对象字面量:一个对象字面量就是包围在一堆花括号中的0或多个“名/值”对。

    var empty_st={};
    var st={
       "f":"hello",
       "l":"word"
    }
    //进行调用
    st["f"]   //"hello"
    //当然也可嵌套
    var flagt={
      airline:"Oceanic",
      number:11,
      departue:{
      time:"2015",
      city:"Shanghai"
      }
    };

    JavaScript可以随意的定义全局变量来容纳你的需要的资源,但是这样会削弱程序的灵活性,尽量避免使用,还是尽可能使用上面的那种嵌套形式,这样flagt就变成了一个容器,还且容易看出层次结构.

  4. 每个函数在创建的时候会附加两个隐藏属性:函数的上下文和实现函数行为的代码。每个函数对象在创建的时候也会随机配 有一个prototype属性,他的值是一个拥有constructor属性且值即为该函数的对象。
  5. 函数对象通过函数字面量来创建

    //创建一个名为add的变量,并用来把两个数字相加的函数赋值给它
    var add=function(a,b){
      return a+b;
    }

    该函数是个匿名函数。

  6. 函数的调用模式有四种:方法调用模式,函数调用模式,构造器调用模式,apply调用模式。除了声明的时候定义的形参,每个函数还接受两个附加的参数:this和arguments。
  7. 闭包:

    a:要理解闭包,首先必须理解Javascript特殊的变量作用域。

    变量的作用域无非就是两种:全局变量和局部变量。

    Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

    var n=999;
      function f1(){
        alert(n);
      }
      f1(); // 999
    //另一方面,在函数外部自然无法读取函数内的局部变量。
      function f1(){
        var n=999;
      }
      alert(n); // error
    /*这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!*/
      function f1(){
        n=999;
      }
      f1();
      alert(n); // 999

    b:如何从外部读取局部变量

    出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。

    那就是在函数的内部,再定义一个函数。

    function f1(){
        n=999;
        function f2(){
          alert(n); // 999
        }
      }

    在上面的代码中,函数f2就被包括在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行,f2内部的局部变量,对f1 就是不可见的。这就是Javascript语言特有的“链式作用域”结构(chain scope),

    子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

    既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!

    function f1(){
        n=999;
        function f2(){
          alert(n);
        }
        return f2;
      }
      var result=f1();
      result(); // 999

    闭包有什么用?1:取函数内部的变量   2:让这些变量的值始终保持在内存中

    function f1(){
        var n=999;
        nAdd=function(){n+=1}
        function f2(){
          alert(n);
        }
        return f2;
      }
      var result=f1();
      result(); // 999
      nAdd();
      result(); // 1000

    在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。

    为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

    这段代码中另一个值得注意的地方,就是“nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此 nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个

    匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。

   既然是这么好的东西,那在使用过程中有没有需要注意的地方呢?很明显有!

      注意:

    1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

    2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便

改变父函数内部变量的值。

时间: 2024-08-08 08:11:20

<JavaScript语言精粹>-读书笔记(一)的相关文章

高性能javascript读书笔记(三.DOM 编程1)

第三章DOM Script DOM编程 读书笔记 访问和修改DOM元素 浏览器通常要求DOM实现和JavaScript保持相互独立. <!-- 例如IE中,被称为JScript的JavaScript实现位于库文件jscript.dll中,而DOM实现位于另一个库mshtml.dll(内 部代号Trident).这种分离技术允许其他技术和语言,如VBScript,受益于Trident所提供的DOM功能和渲染功能.Safari使用Webkit的WebCore处理DOM和渲染,具有一个分离的JavaS

数据访问---高性能JavaScript读书笔记(2)

对于任何一种编程语言来说,数据存储的位置关系到访问速度! 在JavaScript中的直接量包括字符串string.数字number.布尔值boolean.对象object.数组array.函数function.正则表达式regular expression.空值null.未定义数组undefined.而数组项则需要通过数组的数字索引来访问,对象通过字符串进行索引来访问其成员(这里顺便提一句因为数组项是通过数字进行索引.对象成员是通过字符串进行索引,所以这也就是为什么访问对象成员比访问数组项更慢的

加载和运行---高性能JavaScript读书笔记(1)

众所周知大多数浏览器是使用单进程处理UI更新和JavaScript运行等多个任务的,而同一时间只能有一个任务被执行,如此说来,JavaScript运行了多长时间就意味着用户得等待浏览器响应需要花多久时间. 从认知上来说,解析器解析一个界面的时候都是从上至下依次解析的,这就是说界面上出现多少个<script>标签(不管是内联还是外部文件),页面下载和解析必须停止等待脚本下载完成并运行完成(注意这里包括运行),这个过程当中,页面解析和用户交互是被完全阻塞的. Javascript第一条定律:将脚本

DOM访问---高性能JavaScript读书笔记(3)

在JavaScript高级程序设计第一章当中就把JavaScript分成三大部分 所以事实上DOM和BOM是两在独立的部分,它们之间的通信是通过相互之间的功能接口来实现的,这样说来两个独立的部分以功能接口必定会带来性能损耗.这也就是为什么大家一致都说尽量少去访问和修改DOM元素(注意我这里说的是访问和修改,为什么包括访问,请继续往下看  哈哈). 下面用一张图来说明它们各自的作用. 1.在修改DOM元素的时候,我们应该尽量使用innerHTML而不是CreateElement再AppendChi

高性能javascript读书笔记(三.DOM 编程2)

重绘和重排版 浏览器下载完所有的HTML标记,Javascript,CSS,图片之后,它解析文件并创建两个内部数据结构 DOM树 表示页面结构渲染树 表示DOM节点如何显示 渲染树中为每个需要显示的DOM树木=节点存放至少一个节点(隐藏DOM元素在选桉树中没有对应节点)渲染树上的节点称为"框"或者"盒",符合CSS模型的定义,将页面元素看作一个具有填充,边距,边框和位置的盒.一 旦DOM树和渲染树构造完毕,浏览器就可以显示(绘制)页面上的元素了. 当DOM改变影响到

Javascript读书笔记:函数定义和函数调用

定义函数 使用function关键字来定义函数,分为两种形式: 声明式函数定义: function add(m,n) { alert(m+n); } 这种方式等同于构造一个Function类的实例的方式: var add = new Function("m", "n", "alert(m+n);"); Function类构造方法的最后一个参数为函数体:"alert(m+n);",前面的都是函数的形参,参数必须是字符串形式的:&

Javascript读书笔记:字符串常用方法

concat() 连接多个字符串,返回合并后的字符串. 1 var s1="a"; 2 var s2="b"; 3 var s3="c"; 4 5 console.log(s1.concat(s2,s3));//abc 数组中的concat():将参数添加为数组的元素,返回新的数组. 1 var arr = [1, 2, 3]; 2 console.log(arr.concat(4, 5));//[1,2,3,4,5] indexOf() 查找子

高性能javascript学习笔记系列(1) -js的加载和执行

这篇笔记的内容主要涉及js的脚本位置,如何加载js脚本和脚本文件执行的问题,按照自己的理解结合高性能JavaScript整理出来的 javascript是解释性代码,解释性代码需要经历转化成计算机指令的过程,这个过程就会带来一定的性能损耗,所以在js中做性能的优化是必须的 javascript的阻塞特性:浏览器在执行js代码的时候,不能做其他的任何事情,因为浏览器使用单一的进程来处理用户界面的刷新和javascript的脚本执行,也就是说什么时候执行js脚本影响着用户对页面的使用体验(之所以js

高性能javascript学习笔记系列(6) -ajax

参考 高性能javascript javascript高级程序设计 ajax基础  ajax技术的核心是XMLHttpRequest对象(XHR),通过XHR我们就可以实现无需刷新页面就能从服务器端读取数据 var xhr = new XMLHttpRequest(); //只支持IE7以及更高的版本 xhr.onreadystatechange = function() { if(xhr.readyState == 4) { if( (xhr.status >= 200 && xh

高性能javascript学习笔记系列(5) -快速响应的用户界面

参考高性能javascript 理解浏览器UI线程  用于执行javascript和更新用户界面的进程通常被称为浏览器UI线程  UI线程的工作机制可以理解为一个简单的队列系统,队列中的任务按顺序执行 <button onclick="handleClick()">click</button> <script type="text/javascript"> function handleClick() { var div = do