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