JavaScript学习笔记
笔记来源于JavaScript红宝书第二版和第四版的内容,将学习JS的心得、笔记记录于此。
第5章 引用类型
5.5 Function类型
5.5.4函数内部属性
- 在函数内部,有两个特殊的对象,arguments和this,arguments是一个类数组对象,包含着传入函数中的所以参数,主要用途是保存函数参数。arguments对象中有一个callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。
例如经典的阶乘函数:
function factorial(num){
if(num <= 1){
return 1;
}
else{
return num * arguments.callee(num-1);
}
}
- 函数内部的另一个特殊对象是this,this引用的是函数据以执行操作的对象——或者也可以说,this是函数在执行时所处的作用域(当在网页的全局作用域中调用函数时,this对象引用的就是window)。
请看以下例子:
window.color = "red";
var o = {color:"blue"};
function sayColor(){
alert(this.color);
}
sayColor(); //"red"
o.sayColor = sayColor;
o.sayColor(); //"blue"
注意!函数的名字仅仅是一个包含指针的变量而已。因此,即使是在不同的环境中执行,全局的sayColor()函数与o.sayColor()指向的仍然是同一个函数。
- 每个函数都包含两个非继承而来的方法:apply()和call()。apply()和call()作用相同,区别是接收参数的方式不同,其中第一个参数相同,意指在运行函数的作用域,而第二个在apply()中是参数数组,可以是Array实例,也可以是arguments对象;在call()中传递给函数的参数必须是逐个列举出来的。
- 这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值,能够扩充函数赖以运行的作用域。
下面来看一个例子:
window.color = "red";
var o = {color:"bule"};
function sayColor(){
alert(this.color);
}
sayColor(); //red
sayColor.call(this); //red
sayColor.call(window); //red
sayColor.call(o); //blue
使用call()和apply()来扩充作用域的最大好处,就是对象不需要与方法有任何耦合关系。
5.7内置对象
5.7.2Math对象
1. 舍入方法
-
将小数值舍入为整数的几个方法:Math.ceil()、Math.floor()、Math.round()
Math.ceil()执行向上舍入,即它总是将数值向上舍入为最接近的整数。 Math.floor()执行向下舍入,即它总是将数值向下舍入为最接近的整数。 Math.round()标准舍入,即它总是将数值四舍五入为最接近的整数。
下面是使用这些方法的示例:
alert(Math.ceil(25.9)); //26
alert(Math.ceil(25.5)); //26
alert(Math.ceil(25.1)); //26
alert(Math.round(25.9)); //26
alert(Math.round(25.5)); //26
alert(Math.round(25.1)); //25
alert(Math.floor(25.9)); //25
alert(Math.floor(25.5)); //25
alert(Math.floor(25.1)); //25
2.random()方法
Math.random()方法返回介于0到1之间的一个随机数,不包括0和1。
套用下面的公式,Math.random()从某个整数范围内随机选择一个值。
值 = Math.floor(Math.random() * 可能值得总数 + 第一个可能的值)
第6章 面向对象的程序设计
6.1.2 构造函数模式
1.将构造函数当作函数
- 构造函数和其他函数的唯一区别,就在于调用它们的方式不同。
- 任何函数,只要通过new操作符来调用,那它就可以作为构造函数;而任何函数,如果不通过new操作符来调用,那它跟普通函数是一样的。
6.1.3 原型模式
- 我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所以实例共享的属性和方法。如果按照字面意思来理解,prototype就是通过调用构造函数而创建的那个对象的原型对象。使用原型的好处是可以让所有对象实例共享它所包含的属性和方法。不必在构造函数中定义对象信息,而是可以将这些信息直接添加到原型对象中。
如下面例子所示:
function Person(){
}
Person.prototype.name = "Nicholas";
Person.prototype.age = "29";
Person.prototype.job = "Doctor";
Person.prototype.sayName = function(){
alert(this.name);
};
var person1 = new Person();
person1.sayName(); //Nicholas
var person1 = new Person();
person1.sayName(); //Nicholas
alert(person1.sayName == person2.sayName); //true
在此,将sayName()方法和所有属性直接添加到了Person和prototype属性中,构造函数变成了空函数。即使如此,也仍然可以调用构造函数来创建一个新对象,而且新对象中还会具有相同的属性和方法。但与构造函数不同的是,新对象的属性和方法是和所有实例共享的。
1.理解原型
- 无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性。在默认情况下,所有prototype属性都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数。
- 当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型属性,这个内部属性的名字是__proto__。需要注意的是,这个连接存在于实例与构造函数的原型属性之间,而不是存在于实例与构造函数之间。