JavaScript之作用域和引用类型

学习js高级程序设计第四、五章

  4.1基本类型和引用类型的值:基本类型值指的是简单的数据段,引用类型值指可能由多个值构成的对象。

    引用类型的值是保存在内存中的对象,不能直接访问,而是按引用访问(类似指针?)

    复制变量值:基本类型值会在复制的变量对象上创建一个新值,两个变量的任何操作互不影响。而引用类型实际是复制引用,指向同一个对象,所以一个个边,另一个也随之变化。

    传递参数:所有参数均按值传递,传递基本类型值,值被复制给一个局部变量(命名参数,arguments对象中的一个元素),传递引用类型的值时,会把这个值在内存中的地址复制给局部变量,因此这个局部变量的变化会反映在函数的外部,而不是传递了引用。  

  function setName(obj){
  obj.name='kaka';
  obj=new Object();
  obj.name='dodo';
  }
  var person=new Object();
  setName(person);
  alert(person.name); //'kaka'

上面的例子中对象person的地址传递给setName,执行obj.name='kaka'会添加到person中,而obj=new Object()这行代码重新添加(指向)了一个新对象地址,和person无关,所以之后改变name属性person。name任然是kaka,假设是按引用传递的,那么就会使person指向新的对象name属性随之改变。

  检测类型:typeof var a='aa';console.log(typeof(a)) //String

       instanceof  console.log(person instanceof Object)判断是否是某种类型的对象

本章重点:执行环境及作用域

    对于局部变量和全局变量在其他语言中我有点了解,但是牵扯到作用域链,执行环境,甚至闭包函数等问题,还是得重点关注下作用域链的问题

    这个最好环视画一画图比较好理解,纯文字看起来有点费劲,作用域链这部分在第七章闭包中讲的很详细,第七章的学习中进一步巩固。摘抄一下原文,写的很精辟。

执行环境(execution context)定义了变量或函数有权访问其他数据,每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中。某个执行汗巾中的所有代码执行完毕后,该环境被销毁,保存在其中的变量和函数定义也随之销毁(全局执行环境知道应用陈谷退出--例如关闭网页或浏览器时才被销毁)。

  当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的前端,始终都是当前执行的代码虽在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。作用域链中的下一个变量对象来自包含(外部)环境,再下一个变量对象则来自下一个包含环境。全局执行环境的变量对象是中毒是作用域链中的最后一个对象。

  标识符解析(搜索变量的说法跟贴近些?)是沿作用域链一级一级的搜索标识符的过程。始终从作用域链的前端开始,然后逐级的回溯,知道找到为止。

  建议先看闭包,再回过头来看这一章节,就很清晰了,我之前扫到这的时候是晕的,看完闭包那一章节之后再看这段就很简单了,例子跳过。。。

  延长作用域链:1try-catch语句的catch块

         2with语句

  垃圾收集

    1:标记清除。常用方法。垃圾收集器 给所有内存中的变量添加标记-->去掉环境中的变量以及被环境中变量引用的变量的标记-->然后那些有标记的变量就可以销毁了。

    2引用计数。

第五章 引用类型

相当于Java中的类,描述的是一类对象所具有的属性和方法。

原生引用类型,便于开发应用:Object,Array,Date,RegEXP,Function类型

Object类型

    创建方法 1:varperson=new Object(); person.name='aa';..

        2:使用对象字面量表示法:var person={name:'aa',...}

可以使用方括号访问对象属性,优点:可以通过变量来访问属性 e:var propertyName=’blabla’;alert(person[propertyName])

  Arrayl类型

     检测方法 Array.isArray(var ..)

length属性不是只读的,可以通过设置这个属性,改变数组。

常用的数组方法:

join()方法,只接受一个参数(用作分隔符的字符串),返回包含所有数组项的字符串e:var colors=[‘red’,’green’,’blue’] alert(colors.join(‘||’);=>返回字符串‘red||green||blue’

栈方法:push() pop()

push方法接收任意数量的参数,把他们逐个添加到数组末尾,并返回数组长度(返回值为数组长度),

pop方法从数组末尾移除最后一项,然后返回移除的项

队列方法shift()移除数组中第一个项,并返回该项

      Unshifth()在数组前端添加任意个项,并返回新数组的长度

重排序方法:reverse() 反转数组项的顺序,sort()

concat()基于当前数组所有项创建一个新数组,将参数添加到新数组末尾,返回新数组。

slice(i,j)返回第i项到第j项(不包括j项,不改变原数组)

splice()

                  splice(i,j)删除数组中的i到j项,返回删除项

                  solice(i,j,k,l...) i起始位置,j要删除的项数,k插入项。返回被删除的项

indexOf(i) 正序查找数组中元素i所在的角标

lastIndexOF(i) 倒序查找数组中元素i所在角标

迭代方法:arr.map(func(item,index,array){})                    

map():返回一个新的Array,每个元素为调用func的结果--->新数组,数组每一项为函数运行结果

filter():返回一个符合func条件的元素数组会返回true的项组成的数组。--->数组,满足条件的arr元素组成的数组,对数组中的每一项运行给定函数,返回该函数

some():返回一个boolean,判断是否有元素是否符合func条件--->true/false逻辑或

every():返回一个boolean,判断每个元素是否符合func条件--->true/false逻辑与

forEach():没有返回值,只是针对每个元素调用func--->

缩小:reduce()/reduceRight()

RegExp: 正则表达式 var a=new RegExp("");a.test(bla) true/false

var expression=/parttern/flags

flags: g-->全局模式

i-->忽略大小写

m-->多行模式

    Math对象

Math.random()返回介于0和1之间一个随机数,不包括0和1

Math.floor(Math.random()*52+1) 返回一个1到52的随机整数

         Date对象

1 var date=new Date()

2 var date=new Date(Date.parse(‘2016-11-10’))

3 var date=new Date(Date.UTC(2016,0,…)) 1月份->0

  Function类型(对象)

  函数实际上是对象,函数名是指向函数对象的指针。解析器先读取函数声明,使其在执行任何代码之前可用,所以代码中先调用后写函数是可以的。

  重点:函数作为值的调用

    function callSomeFunction(someFunction,someArgument){

      return someFunction(someArgument);
    }

  函数内部属性

  arguments对象,callee属性:指针,指向拥有这儿arguments对象的函数

    function factorial(num){
      if(num<=1){
      return num*arguments.callee(num-1)
      }
      }
      arguments.callee=factorial  解耦

  this对象:

    this引用的是函数执行环境的对象

  caller保存着调用当前函数的的函数引用 arguments。callee.caller

函数的属性和方法:

  

每个函数都包含两个属性:length和prototype

Length表示函数希望收的到参数的个数

  prototype保存引用类型所有实例方法的真正所在。主要用于创建自定义引用类型和实现继承(第六章讲述)。

  每个函数都包含两个非继承而来的方法 :apply() call()  用途:在特定的作用与众调用函数,等于设置函数体内this对象的值。区别:fun.apply(this,arguments)/fun.apply(this,[arg1,arg2])/fun.call(this,arg1,arg2).

单体内置对象:1URI编码

      encodeURI()和encodeURIComponent() 分别编空格(%20) 非数字字母

      2 eval()方法,接收参数为要执行的js字符串,在字符串转json格式时候很有用  eval("("+data+")")

上一篇:Node.js之路【第三篇】NodeJS异步实现


下一篇:解决excel日期变成数字的问题