Javascipt 学习笔记

再认识:Classes, Constructors, and Prototypes

一. Constructor

  eg: var array = new Array(10);

    var today = new Date();

    function Rectangle(w, h){

      this.width = w;

      this.height = h;

    }

    var rect = new Rectangle(6,8);

  上面的三个例子是创建JS对象的方法, new 操作符后面必须跟一个 “函数”。 其真正的方式是,new 会创建一个新对象,

  这个对象没有任何的属性,然后触发new后面的”函数“,把刚刚建的新的空对象作为 “this”属性传入函数中。这个用来和

  new一起创建对象的方法,成为Constructor, 它的作用是,初始化新建的对象。

  注:设置对象的属性用this.attr 来进行设置,如果不用this.attr = attrs 这种形式, 而采用 var attr = attrs, 那么你就

    定义了js中所谓的“private”变量,这些变量无法从外边访问。

二. prototype 和 Inheritance

  如果要计算一Rectangle的面积,怎么做?

  eg. 1. function computeAreaOfRectangle(r) { return r.width * r.height}

    2. {// 很二逼, 最好把area直接写在Rectangle的定义里

      var r = new Rectangle(2, 3);

      r.area = function(){return this.width * this.height}

      var a = r.area()

      }

    3. Rectangle.prototype.area = function(){ return this.width * this.height}

  每个Javascript对象,都有一个内部引用指向另外一个对象(prototype object),对象的prototype的所有属性,都

  是这个对象的属性,也就是说,JavaScript 对象从它的prototype中继承(inherit)属性.

  注:new 操作符新建了一个 新的、空的对象,然后set这个空对象的prototype. 这个对象的prototype就是这个对象

    构造函数的prototype属性的值.  所有的Function都有prototype属性,这个属性的创建和初始化在这个Function

    定义的时候完成,它的初始值是一个只有一个属性的对象。这个唯一的属性是constructor,指向这个Constructor

三、Reading and Writing Inherited Properties

  属性继承发生在Read Property的时候,但写的时候不会继承。写的时候直接写到对应的对象中。

四、Function

  Function的定义有Statement, Literal 两种,statement在Nested Functions中有top level限制,后者是expression。

  JS的函数,最迷惑人的莫过于其Scope and Closures. JS的Function, 作用域是词法作用域而不是动态作用域。即

  Function在它被定义的Scope里运行, 而不是在他被执行时所在的Scope里. Function在被定义的时候,当前的scope chain

  就被保存而且成为这个Function的一部分. 值得一提的是, 虽然Scope Chain在函数定义的时候就固定了, 但是scope chain

  的properties是可变的。下面分点儿介绍:

  1.Function Arguments

    Js functions中可以引用任何数目的arguments, 而不受定义的限制。

    case1: 如果调用时的参数少于定义的参数, 那么缺失的参数为 undefined

    case2: 函数体内, 标识符arguments指向Arguments Object. Argument Object是个Array-like Object, 这种实现

        也允许arguments的获取可以通过数组下标获得, 而且Argument Object还定义了callee 属性,指向正在执行

        的的函数,通常在匿名函数递归调用自己时使用

  2. apply 和 call 方法

    ECMAScript定义了apply() 和 call()方法, 可通过这两个方法调用function,而function却像一个object的method一样。

    举例, 函数f, 对象o 调用方式如下:

      f.call(o, 1, 2)

    这跟下面的几行code相似:

      o.m = f;

      o.m(1, 2);

      delete o.m;

    apply和call的区别在arguments, call的参数是一个一个的, apply的参数是个数组:  f.apply(o, [1,2])

    执行时,第一个参数o就是function body的this。如果这个参数是null或者undefined, 那么global就是this

  3. Call Object

    JS解释器触发function时, 它首先会设置scope为function定义时的scope chain, 然后在scope chain首部中添加一个

    new object 即 call object, 这个 call object有个初始属性arguments指向function的Arguments object. function

    中用var声明的变量也都在call object里. 咱们在函数中用到的arguments就是这个call object中的属性, 但 this 不是!

    当function退出的时候, call object 就会被从scope chain里移除。

    注:scope chain可以理解为由call object组成的链或者数组,最外层为global object。

  4. Function() 构造方法

    JS中,一般通过function来定义一个函数, 但函数也可以通过Function() contructor定义, 这种定义不太好用,所以很少用!

    var f = new Function("x", "y", "return x*y");   基本等同于  function f(x, y){ return x*y}

    Function()接受任意数目的string arguments,最后一个参数是函数体。这个方式比较奇葩的:

    1. Function()使JavaScript code在执行时动态的创建和编译

    2. Fucntion()解析function body, 每次调用都会生成一个新的function object. 如果调用发生在一个loop里或者频繁

      调用的function里, 每次调用时的创建和编译导致低效, 每次调用产生不同的object导致不适用于递归调用!

    3. Fuction()构造函数不遵循lexical scoping. body中引用的变量如果前面的arguments中没有,那么function直接被

     编译成top-level function

 

posted @ 2013-11-25 23:30  jameswhf  阅读(155)  评论(0编辑  收藏  举报